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

Handle new endpoints

parent e5a26a53
No related branches found
No related tags found
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