Skip to content
Snippets Groups Projects
Commit 4e623a95 authored by inso's avatar inso
Browse files

Handle new endpoints

parent e5a26a53
Branches
Tags
No related merge requests found
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
# Caner Candan <caner@candan.fr>, http://caner.candan.fr # Caner Candan <caner@candan.fr>, http://caner.candan.fr
# #
MANAGED_API=["BASIC_MERKLED_API", "BMAS", "WS2P"]
__author__ = 'Caner Candan & inso & vit' __author__ = 'Caner Candan & inso & vit'
__version__ = '0.42.0' __version__ = '0.42.0'
......
...@@ -11,5 +11,7 @@ block_uid_regex = "{block_id_regex}-{block_hash_regex}".format(block_id_regex=bl ...@@ -11,5 +11,7 @@ block_uid_regex = "{block_id_regex}-{block_hash_regex}".format(block_id_regex=bl
conditions_regex = "(&&|\|\|| |[()]|(SIG\({pubkey_regex}\)|(XHX\({hash_regex}\))))*"\ conditions_regex = "(&&|\|\|| |[()]|(SIG\({pubkey_regex}\)|(XHX\({hash_regex}\))))*"\
.format(pubkey_regex=pubkey_regex, hash_regex=hash_regex) .format(pubkey_regex=pubkey_regex, hash_regex=hash_regex)
ipv4_regex = '(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])' ipv4_regex = '(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])'
ipv6_regex = '(?:(?:[0-9A-Fa-f]{1,4}:){6}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|::(?:[0-9A-Fa-f]{1,4}:){5}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,4}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(?:(?:[0-9A-Fa-f]{1,4}:){,6}[0-9A-Fa-f]{1,4})?::)' ipv6_regex = '(?:(?:[0-9A-Fa-f]{1,4}:){6}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|::(?:[0-9A-Fa-f]{1,4}:){5}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,4}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(?:(?:[0-9A-Fa-f]{1,4}:){,6}[0-9A-Fa-f]{1,4})?::)(?:%.+)?'
ws2pid_regex = "[0-9a-f]{8}" ws2pid_regex = "[0-9a-f]{8}"
host_regex = "[a-z0-9-_.]*(?:.[a-zA-Z])?"
path_regex = "[/\w \.-]*/?"
...@@ -3,8 +3,7 @@ import re ...@@ -3,8 +3,7 @@ import re
from ..api.bma import ConnectionHandler from ..api.bma import ConnectionHandler
from .document import Document, MalformedDocumentError from .document import Document, MalformedDocumentError
from . import BlockUID from . import BlockUID
from .. import MANAGED_API from .constants import block_hash_regex, pubkey_regex, ipv4_regex, ipv6_regex, ws2pid_regex, host_regex, path_regex
from .constants import block_hash_regex, pubkey_regex, ipv4_regex, ipv6_regex, ws2pid_regex
class Peer(Document): class Peer(Document):
...@@ -99,14 +98,9 @@ def endpoint(value): ...@@ -99,14 +98,9 @@ def endpoint(value):
elif isinstance(value, WS2PEndpoint): elif isinstance(value, WS2PEndpoint):
return value return value
elif isinstance(value, str): elif isinstance(value, str):
for api in MANAGED_API: for api, cls in MANAGED_API.items():
if value.startswith(api): if value.startswith(api + " "):
if api == "BASIC_MERKLED_API": return cls.from_inline(value)
return BMAEndpoint.from_inline(value)
if api == "BMAS":
return SecuredBMAEndpoint.from_inline(value)
if api == "WS2P":
return WS2PEndpoint.from_inline(value)
return UnknownEndpoint.from_inline(value) return UnknownEndpoint.from_inline(value)
else: else:
raise TypeError("Cannot convert {0} to endpoint".format(value)) raise TypeError("Cannot convert {0} to endpoint".format(value))
...@@ -141,7 +135,7 @@ class UnknownEndpoint(Endpoint): ...@@ -141,7 +135,7 @@ class UnknownEndpoint(Endpoint):
properties = inline.split()[1:] properties = inline.split()[1:]
return cls(api, properties) return cls(api, properties)
except IndexError: except IndexError:
return None raise MalformedDocumentError(inline)
def inline(self): def inline(self):
doc = self.api doc = self.api
...@@ -163,8 +157,9 @@ class UnknownEndpoint(Endpoint): ...@@ -163,8 +157,9 @@ class UnknownEndpoint(Endpoint):
class BMAEndpoint(Endpoint): class BMAEndpoint(Endpoint):
API = "BMA" API = "BASIC_MERKLED_API"
re_inline = re.compile('^BASIC_MERKLED_API(?: ([a-z0-9-_.]*(?:.[a-zA-Z])))?(?: ({ipv4_regex}))?(?: ({ipv6_regex}))?(?: ([0-9]+))$'.format(ipv4_regex=ipv4_regex, re_inline = re.compile('^BASIC_MERKLED_API(?: ({host_regex}))?(?: ({ipv4_regex}))?(?: ({ipv6_regex}))?(?: ([0-9]+))$'.format(host_regex=host_regex,
ipv4_regex=ipv4_regex,
ipv6_regex=ipv6_regex)) ipv6_regex=ipv6_regex))
def __init__(self, server, ipv4, ipv6, port): def __init__(self, server, ipv4, ipv6, port):
...@@ -178,7 +173,7 @@ class BMAEndpoint(Endpoint): ...@@ -178,7 +173,7 @@ class BMAEndpoint(Endpoint):
m = BMAEndpoint.re_inline.match(inline) m = BMAEndpoint.re_inline.match(inline)
str_re = BMAEndpoint.re_inline.pattern str_re = BMAEndpoint.re_inline.pattern
if m is None: if m is None:
raise MalformedDocumentError("BMAEndpoint") raise MalformedDocumentError(BMAEndpoint.API)
server = m.group(1) server = m.group(1)
ipv4 = m.group(2) ipv4 = m.group(2)
ipv6 = m.group(3) ipv6 = m.group(3)
...@@ -186,7 +181,7 @@ class BMAEndpoint(Endpoint): ...@@ -186,7 +181,7 @@ class BMAEndpoint(Endpoint):
return cls(server, ipv4, ipv6, port) return cls(server, ipv4, ipv6, port)
def inline(self): def inline(self):
return "BASIC_MERKLED_API{DNS}{IPv4}{IPv6}{PORT}" \ return BMAEndpoint.API + "{DNS}{IPv4}{IPv6}{PORT}" \
.format(DNS=(" {0}".format(self.server) if self.server else ""), .format(DNS=(" {0}".format(self.server) if self.server else ""),
IPv4=(" {0}".format(self.ipv4) if self.ipv4 else ""), IPv4=(" {0}".format(self.ipv4) if self.ipv4 else ""),
IPv6=(" {0}".format(self.ipv6) if self.ipv6 else ""), IPv6=(" {0}".format(self.ipv6) if self.ipv6 else ""),
...@@ -221,8 +216,10 @@ class BMAEndpoint(Endpoint): ...@@ -221,8 +216,10 @@ class BMAEndpoint(Endpoint):
class SecuredBMAEndpoint(BMAEndpoint): class SecuredBMAEndpoint(BMAEndpoint):
API = "BMAS" API = "BMAS"
re_inline = re.compile('^BMAS(?: ([a-z0-9-_.]*(?:.[a-zA-Z])))?(?: ({ipv4_regex}))?(?: ({ipv6_regex}))? ([0-9]+)(?: ([/\w \.-]*)/?)?$'.format(ipv4_regex=ipv4_regex, re_inline = re.compile('^BMAS(?: ({host_regex}))?(?: ({ipv4_regex}))?(?: ({ipv6_regex}))? ([0-9]+)(?: ({path_regex}))?$'.format(host_regex=host_regex,
ipv6_regex=ipv6_regex)) ipv4_regex=ipv4_regex,
ipv6_regex=ipv6_regex,
path_regex=path_regex))
def __init__(self, server, ipv4, ipv6, port, path): def __init__(self, server, ipv4, ipv6, port, path):
super().__init__(server, ipv4, ipv6, port) super().__init__(server, ipv4, ipv6, port)
...@@ -232,7 +229,7 @@ class SecuredBMAEndpoint(BMAEndpoint): ...@@ -232,7 +229,7 @@ class SecuredBMAEndpoint(BMAEndpoint):
def from_inline(cls, inline): def from_inline(cls, inline):
m = SecuredBMAEndpoint.re_inline.match(inline) m = SecuredBMAEndpoint.re_inline.match(inline)
if m is None: if m is None:
raise MalformedDocumentError("BMAS") raise MalformedDocumentError(SecuredBMAEndpoint.API)
server = m.group(1) server = m.group(1)
ipv4 = m.group(2) ipv4 = m.group(2)
ipv6 = m.group(3) ipv6 = m.group(3)
...@@ -244,7 +241,7 @@ class SecuredBMAEndpoint(BMAEndpoint): ...@@ -244,7 +241,7 @@ class SecuredBMAEndpoint(BMAEndpoint):
def inline(self): def inline(self):
inlined = [str(info) for info in (self.server, self.ipv4, self.ipv6, self.port, self.path) if info] inlined = [str(info) for info in (self.server, self.ipv4, self.ipv6, self.port, self.path) if info]
return "BMAS " + " ".join(inlined) return SecuredBMAEndpoint.API + " " + " ".join(inlined)
def conn_handler(self, session=None, proxy=None): def conn_handler(self, session=None, proxy=None):
""" """
...@@ -263,28 +260,34 @@ class SecuredBMAEndpoint(BMAEndpoint): ...@@ -263,28 +260,34 @@ class SecuredBMAEndpoint(BMAEndpoint):
class WS2PEndpoint(Endpoint): class WS2PEndpoint(Endpoint):
API = "WS2P" API = "WS2P"
re_inline = re.compile('^WS2P ({ws2pid_regex}) ((?:[a-z0-9-_.]*(?:.[a-zA-Z]))|(?:{ipv4_regex})) ([0-9]+)?$'.format(ws2pid_regex=ws2pid_regex, re_inline = re.compile('^WS2P ({ws2pid_regex}) ((?:{host_regex})|(?:{ipv4_regex})) ([0-9]+)?(?: ({path_regex}))?$'.format(ws2pid_regex=ws2pid_regex,
host_regex=host_regex,
ipv4_regex=ipv4_regex, ipv4_regex=ipv4_regex,
ipv6_regex=ipv6_regex)) ipv6_regex=ipv6_regex,
path_regex=path_regex))
def __init__(self, ws2pid, server, port): def __init__(self, ws2pid, server, port, path):
self.ws2pid = ws2pid self.ws2pid = ws2pid
self.server = server self.server = server
self.port = port self.port = port
self.path = path
@classmethod @classmethod
def from_inline(cls, inline): def from_inline(cls, inline):
m = WS2PEndpoint.re_inline.match(inline) m = WS2PEndpoint.re_inline.match(inline)
if m is None: if m is None:
raise MalformedDocumentError("WS2P") raise MalformedDocumentError(WS2PEndpoint.API)
ws2pid = m.group(1) ws2pid = m.group(1)
server = m.group(2) server = m.group(2)
port = int(m.group(3)) port = int(m.group(3))
return cls(ws2pid, server, port) path = m.group(4)
if not path:
path = ""
return cls(ws2pid, server, port, path)
def inline(self): def inline(self):
inlined = [str(info) for info in (self.ws2pid, self.server,self.port)] inlined = [str(info) for info in (self.ws2pid, self.server, self.port, self.path) if info]
return "WS2P " + " ".join(inlined) return WS2PEndpoint.API + " " + " ".join(inlined)
def conn_handler(self, session=None, proxy=None): def conn_handler(self, session=None, proxy=None):
""" """
...@@ -293,7 +296,7 @@ class WS2PEndpoint(Endpoint): ...@@ -293,7 +296,7 @@ class WS2PEndpoint(Endpoint):
:param aiohttp.ClientSession session: AIOHTTP client session instance :param aiohttp.ClientSession session: AIOHTTP client session instance
:rtype: ConnectionHandler :rtype: ConnectionHandler
""" """
yield ConnectionHandler("https", "wss", self.server, self.port, "", proxy, session) yield ConnectionHandler("https", "wss", self.server, self.port, self.path, proxy, session)
def __str__(self): def __str__(self):
return self.inline() return self.inline()
...@@ -301,9 +304,109 @@ class WS2PEndpoint(Endpoint): ...@@ -301,9 +304,109 @@ class WS2PEndpoint(Endpoint):
def __eq__(self, other): def __eq__(self, other):
if isinstance(other, WS2PEndpoint): if isinstance(other, WS2PEndpoint):
return self.server == other.server and self.ws2pid == other.ws2pid \ return self.server == other.server and self.ws2pid == other.ws2pid \
and self.port == other.port and self.port == other.port and self.path == other.path
else:
return False
def __hash__(self):
return hash((self.ws2pid, self.server, self.port, self.path))
class ESUserEndpoint(Endpoint):
API = "ES_USER_API"
re_inline = re.compile('^ES_USER_API ((?:{host_regex})|(?:{ipv4_regex})) ([0-9]+)$'.format(ws2pid_regex=ws2pid_regex,
host_regex=host_regex,
ipv4_regex=ipv4_regex))
def __init__(self, server, port):
self.server = server
self.port = port
@classmethod
def from_inline(cls, inline):
m = ESUserEndpoint.re_inline.match(inline)
if m is None:
raise MalformedDocumentError(ESUserEndpoint.API)
server = m.group(1)
port = int(m.group(2))
return cls(server, port)
def inline(self):
inlined = [str(info) for info in (self.server, self.port) if info]
return ESUserEndpoint.API + " " + " ".join(inlined)
def conn_handler(self, session=None, proxy=None):
"""
Return connection handler instance for the endpoint
:param aiohttp.ClientSession session: AIOHTTP client session instance
:rtype: ConnectionHandler
"""
yield ConnectionHandler("https", "wss", self.server, self.port, "", proxy, session)
def __str__(self):
return self.inline()
def __eq__(self, other):
if isinstance(other, ESUserEndpoint):
return self.server == other.server and self.port == other.port
else:
return False
def __hash__(self):
return hash((self.server, self.port))
class ESSubscribtionEndpoint(Endpoint):
API = "ES_SUBSCRIPTION_API"
re_inline = re.compile('^ES_SUBSCRIPTION_API ((?:{host_regex})|(?:{ipv4_regex})) ([0-9]+)$'.format(ws2pid_regex=ws2pid_regex,
host_regex=host_regex,
ipv4_regex=ipv4_regex))
def __init__(self, server, port):
self.server = server
self.port = port
@classmethod
def from_inline(cls, inline):
m = ESSubscribtionEndpoint.re_inline.match(inline)
if m is None:
raise MalformedDocumentError(ESSubscribtionEndpoint.API)
server = m.group(1)
port = int(m.group(2))
return cls(server, port)
def inline(self):
inlined = [str(info) for info in (self.server, self.port) if info]
return ESSubscribtionEndpoint.API + " " + " ".join(inlined)
def conn_handler(self, session=None, proxy=None):
"""
Return connection handler instance for the endpoint
:param aiohttp.ClientSession session: AIOHTTP client session instance
:rtype: ConnectionHandler
"""
yield ConnectionHandler("https", "wss", self.server, self.port, "", proxy, session)
def __str__(self):
return self.inline()
def __eq__(self, other):
if isinstance(other, ESSubscribtionEndpoint):
return self.server == other.server and self.port == other.port
else: else:
return False return False
def __hash__(self): def __hash__(self):
return hash((self.ws2pid, self.server, self.port)) return hash((ESSubscribtionEndpoint.API, self.server, self.port))
\ No newline at end of file
MANAGED_API={
BMAEndpoint.API: BMAEndpoint,
SecuredBMAEndpoint.API: SecuredBMAEndpoint,
WS2PEndpoint.API: WS2PEndpoint,
ESUserEndpoint.API: ESUserEndpoint,
ESSubscribtionEndpoint.API: ESSubscribtionEndpoint
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment