From 1a944735df76d07c40404d33637929ed69c9284c Mon Sep 17 00:00:00 2001 From: rllola Date: Sun, 14 Apr 2019 16:57:37 +0200 Subject: [PATCH 1/9] New ZeronameLocal plugin with connection to namecoin node --- plugins/ZeronameLocal/SiteManagerPlugin.py | 133 +++++++++++++++++++++ plugins/ZeronameLocal/UiRequestPlugin.py | 39 ++++++ plugins/ZeronameLocal/__init__.py | 2 + 3 files changed, 174 insertions(+) create mode 100644 plugins/ZeronameLocal/SiteManagerPlugin.py create mode 100644 plugins/ZeronameLocal/UiRequestPlugin.py create mode 100644 plugins/ZeronameLocal/__init__.py diff --git a/plugins/ZeronameLocal/SiteManagerPlugin.py b/plugins/ZeronameLocal/SiteManagerPlugin.py new file mode 100644 index 00000000..54c06eef --- /dev/null +++ b/plugins/ZeronameLocal/SiteManagerPlugin.py @@ -0,0 +1,133 @@ +import logging, json, os, re, sys, time, requests +import gevent +from Plugin import PluginManager +from Config import config +from Debug import Debug + +allow_reload = False # No reload supported + +log = logging.getLogger("ZeronameLocalPlugin") + + +@PluginManager.registerTo("SiteManager") +class SiteManagerPlugin(object): + + def load(self, *args, **kwargs): + super(SiteManagerPlugin, self).load(*args, **kwargs) + self.url = "http://%(host)s:%(port)s" % {"host": config.namecoin_host, "port": config.namecoin_rpcport} + self.cache = dict() + + # Checks if it's a valid address + def isAddress(self, address): + print("ISADDRESS") + return self.isBitDomain(address) or super(SiteManagerPlugin, self).isAddress(address) + + # Return: True if the address is domain + def isDomain(self, address): + print("ISDOMAIN : ", address) + return self.isBitDomain(address) or super(SiteManagerPlugin, self).isDomain(address) + + # Return: True if the address is .bit domain + def isBitDomain(self, address): + print("ISBITDOMAIN : ", address) + return re.match(r"(.*?)([A-Za-z0-9_-]+\.bit)$", address) + + # Return: Site object or None if not found + def get(self, address): + print("GET : ", address) + if self.isBitDomain(address): # Its looks like a domain + address_resolved = self.resolveDomain(address) + if address_resolved: # Domain found + site = self.sites.get(address_resolved) + if site: + site_domain = site.settings.get("domain") + if site_domain != address: + site.settings["domain"] = address + else: # Domain not found + site = self.sites.get(address) + + else: # Access by site address + site = super(SiteManagerPlugin, self).get(address) + return site + + # Return or create site and start download site files + # Return: Site or None if dns resolve failed + def need(self, address, *args, **kwargs): + print("NEED : ", address) + if self.isBitDomain(address): # Its looks like a domain + address_resolved = self.resolveDomain(address) + if address_resolved: + address = address_resolved + else: + return None + + return super(SiteManagerPlugin, self).need(address, *args, **kwargs) + + # Resolve domain + # Return: The address or None + def resolveDomain(self, domain): + print("RESOLVEDOMAIN : ", domain) + domain = domain.lower() + + #remove .bit on end + if domain[-4:] == ".bit": + domain = domain[0:-4] + + domain_array = domain.split(".") + + if len(domain_array) > 2: + raise Error("Too many subdomains! Can only handle one level (eg. staging.mixtape.bit)") + + subdomain = "" + if len(domain_array) == 1: + domain = domain_array[0] + else: + subdomain = domain_array[0] + domain = domain_array[1] + + print(domain) + + if domain in self.cache: + delta = time.time() - self.cache[domain]["time"] + if delta < 3600: + # Must have been less than 1hour + return self.cache[domain]["addresses_resolved"][subdomain] + + payload = json.dumps({ + "jsonrpc": "2.0", + "id": "zeronet", + "method": "name_show", + "params": ["d/"+domain] + }) + + try: + #domain_object = self.rpc.name_show("d/"+domain) + response = requests.post(self.url, auth=(config.namecoin_rpcuser, config.namecoin_rpcpassword), data=payload) + print(response) + domain_object = response.json()["result"] + except Exception as err: + #domain doesn't exist + print("FAILED TO RESOLVE NAME : ", err) + return None + + print(domain_object) + if "zeronet" in domain_object["value"]: + # Has a subdomain? + zeronet_domains = json.loads(domain_object["value"])["zeronet"] + + self.cache[domain] = {"addresses_resolved": zeronet_domains, "time": time.time()} + + print(self.cache[domain]) + + return self.cache[domain]["addresses_resolved"][subdomain] + +@PluginManager.registerTo("ConfigPlugin") +class ConfigPlugin(object): + def createArguments(self): + group = self.parser.add_argument_group("Zeroname Local plugin") + group.add_argument('--namecoin_host', help="Host to namecoin node (eg. 127.0.0.1)") + group.add_argument('--namecoin_rpcport', help="Port to connect (eg. 8336)") + group.add_argument('--namecoin_rpcuser', help="RPC user to connect to the namecoin node (eg. nofish)") + group.add_argument('--namecoin_rpcpassword', help="RPC password to connect to namecoin node") + + return super(ConfigPlugin, self).createArguments() diff --git a/plugins/ZeronameLocal/UiRequestPlugin.py b/plugins/ZeronameLocal/UiRequestPlugin.py new file mode 100644 index 00000000..0ccfb530 --- /dev/null +++ b/plugins/ZeronameLocal/UiRequestPlugin.py @@ -0,0 +1,39 @@ +import re +from Plugin import PluginManager + +@PluginManager.registerTo("UiRequest") +class UiRequestPlugin(object): + def __init__(self, *args, **kwargs): + from Site import SiteManager + self.site_manager = SiteManager.site_manager + super(UiRequestPlugin, self).__init__(*args, **kwargs) + + + # Media request + def actionSiteMedia(self, path): + match = re.match(r"/media/(?P
[A-Za-z0-9-]+\.[A-Za-z0-9\.-]+)(?P/.*|$)", path) + if match: # Its a valid domain, resolve first + domain = match.group("address") + address = self.site_manager.resolveDomain(domain) + if address: + path = "/media/"+address+match.group("inner_path") + return super(UiRequestPlugin, self).actionSiteMedia(path) # Get the wrapper frame output + + + # Is mediarequest allowed from that referer + def isMediaRequestAllowed(self, site_address, referer): + referer_path = re.sub("http[s]{0,1}://.*?/", "/", referer).replace("/media", "") # Remove site address + referer_path = re.sub(r"\?.*", "", referer_path) # Remove http params + + if self.isProxyRequest(): # Match to site domain + referer = re.sub("^http://zero[/]+", "http://", referer) # Allow /zero access + referer_site_address = re.match("http[s]{0,1}://(.*?)(/|$)", referer).group(1) + else: # Match to request path + referer_site_address = re.match(r"/(?P
[A-Za-z0-9\.-]+)(?P/.*|$)", referer_path).group("address") + + if referer_site_address == site_address: # Referer site address as simple address + return True + elif self.site_manager.resolveDomain(referer_site_address) == site_address: # Referer site address as dns + return True + else: # Invalid referer + return False diff --git a/plugins/ZeronameLocal/__init__.py b/plugins/ZeronameLocal/__init__.py new file mode 100644 index 00000000..cf724069 --- /dev/null +++ b/plugins/ZeronameLocal/__init__.py @@ -0,0 +1,2 @@ +from . import UiRequestPlugin +from . import SiteManagerPlugin \ No newline at end of file From af1fb7aaa6e3d4730e49e06d4ca8fea768ff9f38 Mon Sep 17 00:00:00 2001 From: rllola Date: Sun, 14 Apr 2019 22:41:26 +0200 Subject: [PATCH 2/9] Also recognise 'map' namecoin standard way of registering for domain --- plugins/ZeronameLocal/SiteManagerPlugin.py | 27 +++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/plugins/ZeronameLocal/SiteManagerPlugin.py b/plugins/ZeronameLocal/SiteManagerPlugin.py index 54c06eef..082cefcd 100644 --- a/plugins/ZeronameLocal/SiteManagerPlugin.py +++ b/plugins/ZeronameLocal/SiteManagerPlugin.py @@ -112,14 +112,35 @@ class SiteManagerPlugin(object): print(domain_object) if "zeronet" in domain_object["value"]: - # Has a subdomain? zeronet_domains = json.loads(domain_object["value"])["zeronet"] + if isinstance(zeronet_domains, str): + # { + # "zeronet":"19rXKeKptSdQ9qt7omwN82smehzTuuq6S9" + # } is valid + zeronet_domains = {"": zeronet_domains} + self.cache[domain] = {"addresses_resolved": zeronet_domains, "time": time.time()} - print(self.cache[domain]) + elif "map" in domain_object["value"]: + # Namecoin standard use {"map": { "blog": {"zeronet": "1D..."} }} + data_map = json.loads(domain_object["value"])["map"] - return self.cache[domain]["addresses_resolved"][subdomain] + zeronet_domains = dict() + for subdomain in data_map: + if "zeronet" in data_map[subdomain]: + zeronet_domains[subdomain] = data_map[subdomain]["zeronet"] + if "zeronet" in data_map and isinstance(data_map["zeronet"], str): + # {"map":{ + # "zeronet":"19rXKeKptSdQ9qt7omwN82smehzTuuq6S9", + # }} + zeronet_domains[""] = data_map["zeronet"] + + else: + # No Zeronet address registered + return None + + return self.cache[domain]["addresses_resolved"][subdomain] @PluginManager.registerTo("ConfigPlugin") class ConfigPlugin(object): From 36ff506dfecde833bd6973507bd9bdcc00411ce2 Mon Sep 17 00:00:00 2001 From: rllola Date: Sun, 14 Apr 2019 22:44:04 +0200 Subject: [PATCH 3/9] Added 'requests' dependency to requierements.txt --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 1173d695..7777e09b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,3 +12,4 @@ bencode.py coincurve python-bitcoinlib maxminddb +requests>=2.21.0 From c4d8466195fb0d0b5ee2b29f249fefa1f6f5b79c Mon Sep 17 00:00:00 2001 From: rllola Date: Sun, 14 Apr 2019 22:58:05 +0200 Subject: [PATCH 4/9] Delete old plugin --- .../SiteManagerPlugin.py | 68 ------- .../UiRequestPlugin.py | 40 ---- plugins/disabled-Zeroname-local/__init__.py | 2 - .../bitcoinrpc/__init__.py | 0 .../bitcoinrpc/authproxy.py | 190 ------------------ .../disabled-Zeroname-local/domainLookup.py | 78 ------- 6 files changed, 378 deletions(-) delete mode 100644 plugins/disabled-Zeroname-local/SiteManagerPlugin.py delete mode 100644 plugins/disabled-Zeroname-local/UiRequestPlugin.py delete mode 100644 plugins/disabled-Zeroname-local/__init__.py delete mode 100644 plugins/disabled-Zeroname-local/bitcoinrpc/__init__.py delete mode 100644 plugins/disabled-Zeroname-local/bitcoinrpc/authproxy.py delete mode 100644 plugins/disabled-Zeroname-local/domainLookup.py diff --git a/plugins/disabled-Zeroname-local/SiteManagerPlugin.py b/plugins/disabled-Zeroname-local/SiteManagerPlugin.py deleted file mode 100644 index c43e792a..00000000 --- a/plugins/disabled-Zeroname-local/SiteManagerPlugin.py +++ /dev/null @@ -1,68 +0,0 @@ -import logging, json, os, re, sys, time -import gevent -from Plugin import PluginManager -from Config import config -from Debug import Debug -from .domainLookup import lookupDomain - -allow_reload = False # No reload supported - -log = logging.getLogger("Zeroname-localPlugin") - - -@PluginManager.registerTo("SiteManager") -class SiteManagerPlugin(object): - def load(self): - super(SiteManagerPlugin, self).load() - - # Checks if its a valid address - def isAddress(self, address): - if self.isDomain(address): - return True - else: - return super(SiteManagerPlugin, self).isAddress(address) - - - # Return: True if the address is domain - def isDomain(self, address): - return re.match(r"(.*?)([A-Za-z0-9_-]+\.[A-Za-z0-9]+)$", address) - - - # Resolve domain - # Return: The address or None - def resolveDomain(self, domain): - return lookupDomain(domain) - - - # Return or create site and start download site files - # Return: Site or None if dns resolve failed - def need(self, address, all_file=True): - if self.isDomain(address): # Its looks like a domain - address_resolved = self.resolveDomain(address) - if address_resolved: - address = address_resolved - else: - return None - - return super(SiteManagerPlugin, self).need(address, all_file) - - - # Return: Site object or None if not found - def get(self, address): - if self.sites == None: # Not loaded yet - self.load() - if self.isDomain(address): # Its looks like a domain - address_resolved = self.resolveDomain(address) - if address_resolved: # Domain found - site = self.sites.get(address_resolved) - if site: - site_domain = site.settings.get("domain") - if site_domain != address: - site.settings["domain"] = address - else: # Domain not found - site = self.sites.get(address) - - else: # Access by site address - site = self.sites.get(address) - return site - diff --git a/plugins/disabled-Zeroname-local/UiRequestPlugin.py b/plugins/disabled-Zeroname-local/UiRequestPlugin.py deleted file mode 100644 index df37e066..00000000 --- a/plugins/disabled-Zeroname-local/UiRequestPlugin.py +++ /dev/null @@ -1,40 +0,0 @@ -import re -from Plugin import PluginManager - -@PluginManager.registerTo("UiRequest") -class UiRequestPlugin(object): - def __init__(self, *args, **kwargs): - from Site import SiteManager - self.site_manager = SiteManager.site_manager - super(UiRequestPlugin, self).__init__(*args, **kwargs) - - - # Media request - def actionSiteMedia(self, path): - match = re.match(r"/media/(?P
[A-Za-z0-9-]+\.[A-Za-z0-9\.-]+)(?P/.*|$)", path) - if match: # Its a valid domain, resolve first - domain = match.group("address") - address = self.site_manager.resolveDomain(domain) - if address: - path = "/media/"+address+match.group("inner_path") - return super(UiRequestPlugin, self).actionSiteMedia(path) # Get the wrapper frame output - - - # Is mediarequest allowed from that referer - def isMediaRequestAllowed(self, site_address, referer): - referer_path = re.sub("http[s]{0,1}://.*?/", "/", referer).replace("/media", "") # Remove site address - referer_path = re.sub(r"\?.*", "", referer_path) # Remove http params - - if self.isProxyRequest(): # Match to site domain - referer = re.sub("^http://zero[/]+", "http://", referer) # Allow /zero access - referer_site_address = re.match("http[s]{0,1}://(.*?)(/|$)", referer).group(1) - else: # Match to request path - referer_site_address = re.match(r"/(?P
[A-Za-z0-9\.-]+)(?P/.*|$)", referer_path).group("address") - - if referer_site_address == site_address: # Referer site address as simple address - return True - elif self.site_manager.resolveDomain(referer_site_address) == site_address: # Referer site address as dns - return True - else: # Invalid referer - return False - diff --git a/plugins/disabled-Zeroname-local/__init__.py b/plugins/disabled-Zeroname-local/__init__.py deleted file mode 100644 index cf724069..00000000 --- a/plugins/disabled-Zeroname-local/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from . import UiRequestPlugin -from . import SiteManagerPlugin \ No newline at end of file diff --git a/plugins/disabled-Zeroname-local/bitcoinrpc/__init__.py b/plugins/disabled-Zeroname-local/bitcoinrpc/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/plugins/disabled-Zeroname-local/bitcoinrpc/authproxy.py b/plugins/disabled-Zeroname-local/bitcoinrpc/authproxy.py deleted file mode 100644 index facf2c41..00000000 --- a/plugins/disabled-Zeroname-local/bitcoinrpc/authproxy.py +++ /dev/null @@ -1,190 +0,0 @@ - -""" - Copyright 2011 Jeff Garzik - - AuthServiceProxy has the following improvements over python-jsonrpc's - ServiceProxy class: - - - HTTP connections persist for the life of the AuthServiceProxy object - (if server supports HTTP/1.1) - - sends protocol 'version', per JSON-RPC 1.1 - - sends proper, incrementing 'id' - - sends Basic HTTP authentication headers - - parses all JSON numbers that look like floats as Decimal - - uses standard Python json lib - - Previous copyright, from python-jsonrpc/jsonrpc/proxy.py: - - Copyright (c) 2007 Jan-Klaas Kollhof - - This file is part of jsonrpc. - - jsonrpc is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - This software is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this software; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -""" - -try: - import http.client as httplib -except ImportError: - import http.client -import base64 -import decimal -import json -import logging -try: - import urllib.parse as urlparse -except ImportError: - import urllib.parse - -USER_AGENT = "AuthServiceProxy/0.1" - -HTTP_TIMEOUT = 30 - -log = logging.getLogger("BitcoinRPC") - -class JSONRPCException(Exception): - def __init__(self, rpc_error): - parent_args = [] - try: - parent_args.append(rpc_error['message']) - except: - pass - Exception.__init__(self, *parent_args) - self.error = rpc_error - self.code = rpc_error['code'] if 'code' in rpc_error else None - self.message = rpc_error['message'] if 'message' in rpc_error else None - - def __str__(self): - return '%d: %s' % (self.code, self.message) - - def __repr__(self): - return '<%s \'%s\'>' % (self.__class__.__name__, self) - - -def EncodeDecimal(o): - if isinstance(o, decimal.Decimal): - return float(round(o, 8)) - raise TypeError(repr(o) + " is not JSON serializable") - -class AuthServiceProxy(object): - __id_count = 0 - - def __init__(self, service_url, service_name=None, timeout=HTTP_TIMEOUT, connection=None): - self.__service_url = service_url - self.__service_name = service_name - self.__url = urllib.parse.urlparse(service_url) - if self.__url.port is None: - port = 80 - else: - port = self.__url.port - (user, passwd) = (self.__url.username, self.__url.password) - try: - user = user.encode('utf8') - except AttributeError: - pass - try: - passwd = passwd.encode('utf8') - except AttributeError: - pass - authpair = user + b':' + passwd - self.__auth_header = b'Basic ' + base64.b64encode(authpair) - - self.__timeout = timeout - - if connection: - # Callables re-use the connection of the original proxy - self.__conn = connection - elif self.__url.scheme == 'https': - self.__conn = http.client.HTTPSConnection(self.__url.hostname, port, - timeout=timeout) - else: - self.__conn = http.client.HTTPConnection(self.__url.hostname, port, - timeout=timeout) - - def __getattr__(self, name): - if name.startswith('__') and name.endswith('__'): - # Python internal stuff - raise AttributeError - if self.__service_name is not None: - name = "%s.%s" % (self.__service_name, name) - return AuthServiceProxy(self.__service_url, name, self.__timeout, self.__conn) - - def __call__(self, *args): - AuthServiceProxy.__id_count += 1 - - log.debug("-%s-> %s %s"%(AuthServiceProxy.__id_count, self.__service_name, - json.dumps(args, default=EncodeDecimal))) - postdata = json.dumps({'version': '1.1', - 'method': self.__service_name, - 'params': args, - 'id': AuthServiceProxy.__id_count}, default=EncodeDecimal) - self.__conn.request('POST', self.__url.path, postdata, - {'Host': self.__url.hostname, - 'User-Agent': USER_AGENT, - 'Authorization': self.__auth_header, - 'Content-type': 'application/json'}) - self.__conn.sock.settimeout(self.__timeout) - - response = self._get_response() - if response.get('error') is not None: - raise JSONRPCException(response['error']) - elif 'result' not in response: - raise JSONRPCException({ - 'code': -343, 'message': 'missing JSON-RPC result'}) - - return response['result'] - - def batch_(self, rpc_calls): - """Batch RPC call. - Pass array of arrays: [ [ "method", params... ], ... ] - Returns array of results. - """ - batch_data = [] - for rpc_call in rpc_calls: - AuthServiceProxy.__id_count += 1 - m = rpc_call.pop(0) - batch_data.append({"jsonrpc":"2.0", "method":m, "params":rpc_call, "id":AuthServiceProxy.__id_count}) - - postdata = json.dumps(batch_data, default=EncodeDecimal) - log.debug("--> "+postdata) - self.__conn.request('POST', self.__url.path, postdata, - {'Host': self.__url.hostname, - 'User-Agent': USER_AGENT, - 'Authorization': self.__auth_header, - 'Content-type': 'application/json'}) - results = [] - responses = self._get_response() - for response in responses: - if response['error'] is not None: - raise JSONRPCException(response['error']) - elif 'result' not in response: - raise JSONRPCException({ - 'code': -343, 'message': 'missing JSON-RPC result'}) - else: - results.append(response['result']) - return results - - def _get_response(self): - http_response = self.__conn.getresponse() - if http_response is None: - raise JSONRPCException({ - 'code': -342, 'message': 'missing HTTP response from server'}) - - responsedata = http_response.read().decode('utf8') - response = json.loads(responsedata, parse_float=decimal.Decimal) - if "error" in response and response["error"] is None: - log.debug("<-%s- %s"%(response["id"], json.dumps(response["result"], default=EncodeDecimal))) - else: - log.debug("<-- "+responsedata) - return response diff --git a/plugins/disabled-Zeroname-local/domainLookup.py b/plugins/disabled-Zeroname-local/domainLookup.py deleted file mode 100644 index 0521d233..00000000 --- a/plugins/disabled-Zeroname-local/domainLookup.py +++ /dev/null @@ -1,78 +0,0 @@ -from .bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException -import time, json, os, sys, re, socket - -# Connecting to RPC -def initRpc(config): - """Initialize Namecoin RPC""" - rpc_data = { - 'connect': '127.0.0.1', - 'port': '8336', - 'user': 'PLACEHOLDER', - 'password': 'PLACEHOLDER', - 'clienttimeout': '900' - } - try: - fptr = open(config, 'r') - lines = fptr.readlines() - fptr.close() - except: - return None # Or take some other appropriate action - - for line in lines: - if not line.startswith('rpc'): - continue - key_val = line.split(None, 1)[0] - (key, val) = key_val.split('=', 1) - if not key or not val: - continue - rpc_data[key[3:]] = val - - url = 'http://%(user)s:%(password)s@%(connect)s:%(port)s' % rpc_data - - return url, int(rpc_data['clienttimeout']) - -# Either returns domain's address or none if it doesn't exist -# Supports subdomains and .bit on the end -def lookupDomain(domain): - domain = domain.lower() - - #remove .bit on end - if domain[-4:] == ".bit": - domain = domain[0:-4] - - #check for subdomain - if domain.find(".") != -1: - subdomain = domain[0:domain.find(".")] - domain = domain[domain.find(".")+1:] - else: - subdomain = "" - - try: - domain_object = rpc.name_show("d/"+domain) - except: - #domain doesn't exist - return None - - domain_json = json.loads(domain_object["value"]) - - try: - domain_address = domain_json["zeronet"][subdomain] - except: - #domain exists but doesn't have any zeronet value - return None - - return domain_address - -# Loading config... - -# Check whether platform is on windows or linux -# On linux namecoin is installed under ~/.namecoin, while on on windows it is in %appdata%/Namecoin - -if sys.platform == "win32": - namecoin_location = os.getenv('APPDATA') + "/Namecoin/" -else: - namecoin_location = os.path.expanduser("~/.namecoin/") - -# Initialize rpc connection -rpc_auth, rpc_timeout = initRpc(namecoin_location + "namecoin.conf") -rpc = AuthServiceProxy(rpc_auth, timeout=rpc_timeout) From f195111354a8dde952034cb5161eae9d78b2047b Mon Sep 17 00:00:00 2001 From: rllola Date: Tue, 16 Apr 2019 16:23:09 +0200 Subject: [PATCH 5/9] Using http.client instead of requests module --- plugins/ZeronameLocal/SiteManagerPlugin.py | 29 ++++++++++------------ requirements.txt | 1 - 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/plugins/ZeronameLocal/SiteManagerPlugin.py b/plugins/ZeronameLocal/SiteManagerPlugin.py index 082cefcd..7e6e306b 100644 --- a/plugins/ZeronameLocal/SiteManagerPlugin.py +++ b/plugins/ZeronameLocal/SiteManagerPlugin.py @@ -1,8 +1,9 @@ -import logging, json, os, re, sys, time, requests -import gevent +import logging, json, os, re, sys, time from Plugin import PluginManager from Config import config from Debug import Debug +from http.client import HTTPSConnection, HTTPConnection +from base64 import b64encode allow_reload = False # No reload supported @@ -14,27 +15,27 @@ class SiteManagerPlugin(object): def load(self, *args, **kwargs): super(SiteManagerPlugin, self).load(*args, **kwargs) - self.url = "http://%(host)s:%(port)s" % {"host": config.namecoin_host, "port": config.namecoin_rpcport} + url = "%(host)s:%(port)s" % {"host": config.namecoin_host, "port": config.namecoin_rpcport} + self.c = HTTPConnection(url) + user_pass = "%(user)s:%(password)s" % {"user": config.namecoin_rpcuser, "password": config.namecoin_rpcpassword} + userAndPass = b64encode(bytes(user_pass, "utf-8")).decode("ascii") + self.headers = {"Authorization" : "Basic %s" % userAndPass, "Content-Type": " application/json " } self.cache = dict() # Checks if it's a valid address def isAddress(self, address): - print("ISADDRESS") return self.isBitDomain(address) or super(SiteManagerPlugin, self).isAddress(address) # Return: True if the address is domain def isDomain(self, address): - print("ISDOMAIN : ", address) return self.isBitDomain(address) or super(SiteManagerPlugin, self).isDomain(address) # Return: True if the address is .bit domain def isBitDomain(self, address): - print("ISBITDOMAIN : ", address) return re.match(r"(.*?)([A-Za-z0-9_-]+\.bit)$", address) # Return: Site object or None if not found def get(self, address): - print("GET : ", address) if self.isBitDomain(address): # Its looks like a domain address_resolved = self.resolveDomain(address) if address_resolved: # Domain found @@ -53,7 +54,6 @@ class SiteManagerPlugin(object): # Return or create site and start download site files # Return: Site or None if dns resolve failed def need(self, address, *args, **kwargs): - print("NEED : ", address) if self.isBitDomain(address): # Its looks like a domain address_resolved = self.resolveDomain(address) if address_resolved: @@ -66,7 +66,6 @@ class SiteManagerPlugin(object): # Resolve domain # Return: The address or None def resolveDomain(self, domain): - print("RESOLVEDOMAIN : ", domain) domain = domain.lower() #remove .bit on end @@ -85,8 +84,6 @@ class SiteManagerPlugin(object): subdomain = domain_array[0] domain = domain_array[1] - print(domain) - if domain in self.cache: delta = time.time() - self.cache[domain]["time"] if delta < 3600: @@ -102,15 +99,15 @@ class SiteManagerPlugin(object): try: #domain_object = self.rpc.name_show("d/"+domain) - response = requests.post(self.url, auth=(config.namecoin_rpcuser, config.namecoin_rpcpassword), data=payload) - print(response) - domain_object = response.json()["result"] + self.c.request("POST", "/", payload, headers=self.headers) + response = self.c.getresponse() + data = response.read() + self.c.close() + domain_object = json.loads(data.decode())["result"] except Exception as err: #domain doesn't exist - print("FAILED TO RESOLVE NAME : ", err) return None - print(domain_object) if "zeronet" in domain_object["value"]: zeronet_domains = json.loads(domain_object["value"])["zeronet"] diff --git a/requirements.txt b/requirements.txt index 7777e09b..1173d695 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,4 +12,3 @@ bencode.py coincurve python-bitcoinlib maxminddb -requests>=2.21.0 From 86d3d35619244d5057e3b42de0971680a6ccd0ec Mon Sep 17 00:00:00 2001 From: rllola Date: Tue, 16 Apr 2019 20:07:30 +0200 Subject: [PATCH 6/9] Disable Zeroname plugin --- .../SiteManagerPlugin.py | 0 .../{ZeronameLocal => disabled-ZeronameLocal}/UiRequestPlugin.py | 0 plugins/{ZeronameLocal => disabled-ZeronameLocal}/__init__.py | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename plugins/{ZeronameLocal => disabled-ZeronameLocal}/SiteManagerPlugin.py (100%) rename plugins/{ZeronameLocal => disabled-ZeronameLocal}/UiRequestPlugin.py (100%) rename plugins/{ZeronameLocal => disabled-ZeronameLocal}/__init__.py (100%) diff --git a/plugins/ZeronameLocal/SiteManagerPlugin.py b/plugins/disabled-ZeronameLocal/SiteManagerPlugin.py similarity index 100% rename from plugins/ZeronameLocal/SiteManagerPlugin.py rename to plugins/disabled-ZeronameLocal/SiteManagerPlugin.py diff --git a/plugins/ZeronameLocal/UiRequestPlugin.py b/plugins/disabled-ZeronameLocal/UiRequestPlugin.py similarity index 100% rename from plugins/ZeronameLocal/UiRequestPlugin.py rename to plugins/disabled-ZeronameLocal/UiRequestPlugin.py diff --git a/plugins/ZeronameLocal/__init__.py b/plugins/disabled-ZeronameLocal/__init__.py similarity index 100% rename from plugins/ZeronameLocal/__init__.py rename to plugins/disabled-ZeronameLocal/__init__.py From 4be0e1ee7f33d08900d76b8f37cc66219f5c3558 Mon Sep 17 00:00:00 2001 From: rllola Date: Wed, 17 Apr 2019 18:34:53 +0200 Subject: [PATCH 7/9] Forgot to cache in one 'if' --- plugins/disabled-ZeronameLocal/SiteManagerPlugin.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/disabled-ZeronameLocal/SiteManagerPlugin.py b/plugins/disabled-ZeronameLocal/SiteManagerPlugin.py index 7e6e306b..b0058bca 100644 --- a/plugins/disabled-ZeronameLocal/SiteManagerPlugin.py +++ b/plugins/disabled-ZeronameLocal/SiteManagerPlugin.py @@ -133,6 +133,8 @@ class SiteManagerPlugin(object): # }} zeronet_domains[""] = data_map["zeronet"] + self.cache[domain] = {"addresses_resolved": zeronet_domains, "time": time.time()} + else: # No Zeronet address registered return None From ef6ccb330b03704cda0fd2bd903137904cb404b3 Mon Sep 17 00:00:00 2001 From: rllola Date: Thu, 18 Apr 2019 15:27:49 +0200 Subject: [PATCH 8/9] Dont raise an error if domain has more than one subdomain and just return None --- plugins/disabled-ZeronameLocal/SiteManagerPlugin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/disabled-ZeronameLocal/SiteManagerPlugin.py b/plugins/disabled-ZeronameLocal/SiteManagerPlugin.py index b0058bca..872b797f 100644 --- a/plugins/disabled-ZeronameLocal/SiteManagerPlugin.py +++ b/plugins/disabled-ZeronameLocal/SiteManagerPlugin.py @@ -75,7 +75,8 @@ class SiteManagerPlugin(object): domain_array = domain.split(".") if len(domain_array) > 2: - raise Error("Too many subdomains! Can only handle one level (eg. staging.mixtape.bit)") + log("Too many subdomains! Can only handle one level (eg. staging.mixtape.bit)") + return None subdomain = "" if len(domain_array) == 1: From 907a26a8b956db904d092eb72d17536ff3a169f4 Mon Sep 17 00:00:00 2001 From: rllola Date: Sat, 20 Apr 2019 20:23:59 +0200 Subject: [PATCH 9/9] Take care of the exceptions so it wont crash zeronet if someting goes wrong. --- .../SiteManagerPlugin.py | 44 +++++++++++++++---- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/plugins/disabled-ZeronameLocal/SiteManagerPlugin.py b/plugins/disabled-ZeronameLocal/SiteManagerPlugin.py index 872b797f..579e31c1 100644 --- a/plugins/disabled-ZeronameLocal/SiteManagerPlugin.py +++ b/plugins/disabled-ZeronameLocal/SiteManagerPlugin.py @@ -1,25 +1,48 @@ -import logging, json, os, re, sys, time +import logging, json, os, re, sys, time, socket from Plugin import PluginManager from Config import config from Debug import Debug -from http.client import HTTPSConnection, HTTPConnection +from http.client import HTTPSConnection, HTTPConnection, HTTPException from base64 import b64encode allow_reload = False # No reload supported -log = logging.getLogger("ZeronameLocalPlugin") - - @PluginManager.registerTo("SiteManager") class SiteManagerPlugin(object): - def load(self, *args, **kwargs): super(SiteManagerPlugin, self).load(*args, **kwargs) + self.log = logging.getLogger("ZeronetLocal Plugin") + self.error_message = None + if not config.namecoin_host or not config.namecoin_rpcport or not config.namecoin_rpcuser or not config.namecoin_rpcpassword: + self.error_message = "Missing parameters" + self.log.error("Missing parameters to connect to namecoin node. Please check all the arguments needed with '--help'. Zeronet will continue working without it.") + return + url = "%(host)s:%(port)s" % {"host": config.namecoin_host, "port": config.namecoin_rpcport} - self.c = HTTPConnection(url) + self.c = HTTPConnection(url, timeout=3) user_pass = "%(user)s:%(password)s" % {"user": config.namecoin_rpcuser, "password": config.namecoin_rpcpassword} userAndPass = b64encode(bytes(user_pass, "utf-8")).decode("ascii") self.headers = {"Authorization" : "Basic %s" % userAndPass, "Content-Type": " application/json " } + + payload = json.dumps({ + "jsonrpc": "2.0", + "id": "zeronet", + "method": "ping", + "params": [] + }) + + try: + self.c.request("POST", "/", payload, headers=self.headers) + response = self.c.getresponse() + data = response.read() + self.c.close() + if response.status == 200: + result = json.loads(data.decode())["result"] + else: + raise Exception(response.reason) + except Exception as err: + self.log.error("The Namecoin node is unreachable. Please check the configuration value are correct. Zeronet will continue working without it.") + self.error_message = err self.cache = dict() # Checks if it's a valid address @@ -74,8 +97,12 @@ class SiteManagerPlugin(object): domain_array = domain.split(".") + if self.error_message: + self.log.error("Not able to connect to Namecoin node : {!s}".format(self.error_message)) + return None + if len(domain_array) > 2: - log("Too many subdomains! Can only handle one level (eg. staging.mixtape.bit)") + self.log.error("Too many subdomains! Can only handle one level (eg. staging.mixtape.bit)") return None subdomain = "" @@ -99,7 +126,6 @@ class SiteManagerPlugin(object): }) try: - #domain_object = self.rpc.name_show("d/"+domain) self.c.request("POST", "/", payload, headers=self.headers) response = self.c.getresponse() data = response.read()