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 @@
# Caner Candan <caner@candan.fr>, http://caner.candan.fr
#
MANAGED_API=["BASIC_MERKLED_API", "BMAS", "WS2P"]
__author__ = 'Caner Candan & inso & vit'
__version__ = '0.42.0'
......
......@@ -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}\))))*"\
.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])'
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}"
host_regex = "[a-z0-9-_.]*(?:.[a-zA-Z])?"
path_regex = "[/\w \.-]*/?"
......@@ -3,8 +3,7 @@ import re
from ..api.bma import ConnectionHandler
from .document import Document, MalformedDocumentError
from . import BlockUID
from .. import MANAGED_API
from .constants import block_hash_regex, pubkey_regex, ipv4_regex, ipv6_regex, ws2pid_regex
from .constants import block_hash_regex, pubkey_regex, ipv4_regex, ipv6_regex, ws2pid_regex, host_regex, path_regex
class Peer(Document):
......@@ -99,14 +98,9 @@ def endpoint(value):
elif isinstance(value, WS2PEndpoint):
return value
elif isinstance(value, str):
for api in MANAGED_API:
if value.startswith(api):
if api == "BASIC_MERKLED_API":
return BMAEndpoint.from_inline(value)
if api == "BMAS":
return SecuredBMAEndpoint.from_inline(value)
if api == "WS2P":
return WS2PEndpoint.from_inline(value)
for api, cls in MANAGED_API.items():
if value.startswith(api + " "):
return cls.from_inline(value)
return UnknownEndpoint.from_inline(value)
else:
raise TypeError("Cannot convert {0} to endpoint".format(value))
......@@ -141,7 +135,7 @@ class UnknownEndpoint(Endpoint):
properties = inline.split()[1:]
return cls(api, properties)
except IndexError:
return None
raise MalformedDocumentError(inline)
def inline(self):
doc = self.api
......@@ -163,8 +157,9 @@ class UnknownEndpoint(Endpoint):
class BMAEndpoint(Endpoint):
API = "BMA"
re_inline = re.compile('^BASIC_MERKLED_API(?: ([a-z0-9-_.]*(?:.[a-zA-Z])))?(?: ({ipv4_regex}))?(?: ({ipv6_regex}))?(?: ([0-9]+))$'.format(ipv4_regex=ipv4_regex,
API = "BASIC_MERKLED_API"
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))
def __init__(self, server, ipv4, ipv6, port):
......@@ -178,7 +173,7 @@ class BMAEndpoint(Endpoint):
m = BMAEndpoint.re_inline.match(inline)
str_re = BMAEndpoint.re_inline.pattern
if m is None:
raise MalformedDocumentError("BMAEndpoint")
raise MalformedDocumentError(BMAEndpoint.API)
server = m.group(1)
ipv4 = m.group(2)
ipv6 = m.group(3)
......@@ -186,7 +181,7 @@ class BMAEndpoint(Endpoint):
return cls(server, ipv4, ipv6, port)
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 ""),
IPv4=(" {0}".format(self.ipv4) if self.ipv4 else ""),
IPv6=(" {0}".format(self.ipv6) if self.ipv6 else ""),
......@@ -221,8 +216,10 @@ class BMAEndpoint(Endpoint):
class SecuredBMAEndpoint(BMAEndpoint):
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,
ipv6_regex=ipv6_regex))
re_inline = re.compile('^BMAS(?: ({host_regex}))?(?: ({ipv4_regex}))?(?: ({ipv6_regex}))? ([0-9]+)(?: ({path_regex}))?$'.format(host_regex=host_regex,
ipv4_regex=ipv4_regex,
ipv6_regex=ipv6_regex,
path_regex=path_regex))
def __init__(self, server, ipv4, ipv6, port, path):
super().__init__(server, ipv4, ipv6, port)
......@@ -232,7 +229,7 @@ class SecuredBMAEndpoint(BMAEndpoint):
def from_inline(cls, inline):
m = SecuredBMAEndpoint.re_inline.match(inline)
if m is None:
raise MalformedDocumentError("BMAS")
raise MalformedDocumentError(SecuredBMAEndpoint.API)
server = m.group(1)
ipv4 = m.group(2)
ipv6 = m.group(3)
......@@ -244,7 +241,7 @@ class SecuredBMAEndpoint(BMAEndpoint):
def inline(self):
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):
"""
......@@ -263,28 +260,34 @@ class SecuredBMAEndpoint(BMAEndpoint):
class WS2PEndpoint(Endpoint):
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,
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.server = server
self.port = port
self.path = path
@classmethod
def from_inline(cls, inline):
m = WS2PEndpoint.re_inline.match(inline)
if m is None:
raise MalformedDocumentError("WS2P")
raise MalformedDocumentError(WS2PEndpoint.API)
ws2pid = m.group(1)
server = m.group(2)
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):
inlined = [str(info) for info in (self.ws2pid, self.server,self.port)]
return "WS2P " + " ".join(inlined)
inlined = [str(info) for info in (self.ws2pid, self.server, self.port, self.path) if info]
return WS2PEndpoint.API + " " + " ".join(inlined)
def conn_handler(self, session=None, proxy=None):
"""
......@@ -293,7 +296,7 @@ class WS2PEndpoint(Endpoint):
:param aiohttp.ClientSession session: AIOHTTP client session instance
: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):
return self.inline()
......@@ -301,9 +304,109 @@ class WS2PEndpoint(Endpoint):
def __eq__(self, other):
if isinstance(other, WS2PEndpoint):
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:
return False
def __hash__(self):
return hash((self.ws2pid, self.server, self.port))
\ No newline at end of file
return hash((ESSubscribtionEndpoint.API, self.server, self.port))
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