def do_negotiate(self, stream, request, nodelay=False): session = TRACKER.session_negotiate(request["authorization"]) if not request["authorization"]: request["authorization"] = session.identifier # # XXX make sure we track ALSO the first connection of the # session (which is assigned an identifier in session_negotiate) # or, should this connection fail, we would not be able to # propagate quickly this information because unregister_connection # would not find an entry in self.connections{}. # if session.negotiations == 1: TRACKER.register_connection(stream, request["authorization"]) nodelay = True if not session.active: if not nodelay: NOTIFIER.subscribe(RENEGOTIATE, self._do_renegotiate, (stream, request), True) return m1 = compat.SpeedtestNegotiate_Response() m1.authorization = session.identifier m1.unchoked = session.active m1.queuePos = session.queuepos m1.publicAddress = stream.peername[0] s = marshal.marshal_object(m1, "text/xml") stringio = StringIO.StringIO(s) response = Message() response.compose(code="200", reason="Ok", body=stringio, mimetype="application/xml") stream.send_response(request, response)
def connection_ready(self, stream): LOG.progress() m = compat.RendezvousRequest() m.accept.append("speedtest") m.accept.append("bittorrent") m.version = CONFIG["rendezvous.client.version"] request = Message() request.compose(method="GET", pathquery="/rendezvous", mimetype="text/xml", keepalive=False, host=self.host_header, body=marshal.marshal_object(m, "text/xml")) stream.send_request(request)
def connection_ready(self, stream): m1 = SpeedtestCollect() m1.client = self.conf.get("uuid", "") m1.timestamp = utils.timestamp() m1.internalAddress = stream.myname[0] m1.realAddress = self.conf.get("speedtest.client.public_address", "") m1.remoteAddress = stream.peername[0] m1.latency = self.conf.get("speedtest.client.latency", 0.0) m1.downloadSpeed = self.conf.get("speedtest.client.download", 0.0) m1.uploadSpeed = self.conf.get("speedtest.client.upload", 0.0) m1.privacy_informed = self.conf.get("privacy.informed", 0) m1.privacy_can_collect = self.conf.get("privacy.can_collect", 0) m1.privacy_can_share = self.conf.get("privacy.can_publish", 0) # XXX m1.neubot_version = utils_version.NUMERIC_VERSION m1.platform = sys.platform m1.connectTime = sum(self.rtts) / len(self.rtts) # Test version (added Neubot 0.4.12) m1.testVersion = CONFIG["speedtest_test_version"] s = marshal.marshal_object(m1, "text/xml") stringio = StringIO.StringIO(s) # # Pass a dictionary because the function does not accept # anymore an object # if privacy.collect_allowed(m1.__dict__): if DATABASE.readonly: logging.warning("speedtest: readonly database") else: insertxxx(DATABASE.connection(), m1) request = Message() request.compose( method="POST", pathquery="/speedtest/collect", body=stringio, mimetype="application/xml", host=self.host_header, ) request["authorization"] = self.conf.get("speedtest.client.authorization", "") stream.send_request(request)
def connection_ready(self, stream): m1 = compat.SpeedtestCollect() m1.client = self.conf.get("uuid", "") m1.timestamp = utils.timestamp() m1.internalAddress = stream.myname[0] m1.realAddress = self.conf.get("speedtest.client.public_address", "") m1.remoteAddress = stream.peername[0] m1.latency = self.conf.get("speedtest.client.latency", 0.0) m1.downloadSpeed = self.conf.get("speedtest.client.download", 0.0) m1.uploadSpeed = self.conf.get("speedtest.client.upload", 0.0) m1.privacy_informed = self.conf.get("privacy.informed", 0) m1.privacy_can_collect = self.conf.get("privacy.can_collect", 0) m1.privacy_can_share = self.conf.get("privacy.can_share", 0) m1.neubot_version = LibVersion.to_numeric("0.4.2") m1.platform = sys.platform if self.measurer: m1.connectTime = self.measurer.measure_rtt()[0] # import pprint # if hasattr(self.measurer, "recv_hist"): # download = self.measurer.recv_hist.get("download", []) # pprint.pprint(download) # if hasattr(self.measurer, "send_hist"): # upload = self.measurer.send_hist.get("upload", []) # pprint.pprint(upload) s = marshal.marshal_object(m1, "text/xml") stringio = StringIO.StringIO(s) if privacy.collect_allowed(m1): table_speedtest.insertxxx(DATABASE.connection(), m1) request = Message() request.compose(method="POST", pathquery="/speedtest/collect", body=stringio, mimetype="application/xml", host=self.host_header) request["authorization"] = self.conf.get( "speedtest.client.authorization", "") stream.send_request(request)
def _rewrite_response(request, response): ''' Rewrite response and translate JSON to XML ''' # Do not touch error responses if response.code != '200': return # Convert JSON response to XML elif request.uri == '/negotiate/speedtest': response_body = json.loads(response.body) xmlresp = SpeedtestNegotiate_Response() xmlresp.authorization = response_body['authorization'] xmlresp.unchoked = response_body['unchoked'] xmlresp.queuePos = response_body['queue_pos'] xmlresp.publicAddress = response_body['real_address'] response.body = marshal.marshal_object(xmlresp, 'application/xml') del response['content-type'] del response['content-length'] response['content-type'] = 'application/xml' response['content-length'] = str(len(response.body)) # Suppress JSON response elif request.uri == '/collect/speedtest': del response['content-type'] del response['content-length'] response.body = '' # # We MUST NOT be too strict here because old clients # use the same stream for both negotiation and testing # and the stream already has the rewriter installed # due to that. # Probably we can remove the rewrite hook just after # usage and be more strict here, but the current code # seems to me more robust. # else: pass
def connection_ready(self, stream): LOG.progress() m = compat.RendezvousRequest() m.accept.append("speedtest") m.accept.append("bittorrent") m.version = CONFIG["rendezvous.client.version"] m.privacy_informed = CONFIG["privacy.informed"] m.privacy_can_collect = CONFIG["privacy.can_collect"] m.privacy_can_share = CONFIG["privacy.can_publish"] # XXX request = Message() request.compose( method="GET", pathquery="/rendezvous", mimetype="text/xml", keepalive=False, host=self.host_header, body=marshal.marshal_object(m, "text/xml"), ) stream.send_request(request)
def process_request(self, stream, request): m = marshal.unmarshal_object(request.body.read(), "application/xml", compat.RendezvousRequest) m1 = compat.RendezvousResponse() version = self.conf["rendezvous.server.update_version"] # # Don't offer a release candidate update if the user is not # running a release candidate as well and viceversa. # if (("-rc" in version and "-rc" in m.version) or (not "-rc" in version and not "-rc" in m.version)): if m.version and LibVersion.compare(version, m.version) > 0: m1.update["uri"] = self.conf["rendezvous.server.update_uri"] m1.update["version"] = version # # Select test server address. # The default test server is the master server itself. # If we know the country, lookup the list of servers for # that country in the database. # If there are no servers for that country, register # the master server for the country so that we can notice # we have new users and can take the proper steps to # deploy nearby servers. # server = self.conf.get("rendezvous.server.default", "master.neubot.org") LOG.debug("* default test server: %s" % server) agent_address = stream.peername[0] country = GEOLOCATOR.lookup_country(agent_address) if country: servers = table_geoloc.lookup_servers(DATABASE.connection(), country) if not servers: LOG.info("* learning new country: %s" % country) table_geoloc.insert_server(DATABASE.connection(), country, server) servers = [server] server = random.choice(servers) LOG.debug("* selected test server: %s" % server) if "speedtest" in m.accept: m1.available["speedtest"] = [ "http://%s/speedtest" % server ] if "bittorrent" in m.accept: m1.available["bittorrent"] = [ "http://%s:8000/" % server ] # # Neubot <=0.3.7 expects to receive an XML document while # newer Neubots want a JSON. I hope old clients will upgrade # pretty soon. # if m.version and LibVersion.compare(m.version, "0.3.7") >= 0: s = marshal.marshal_object(m1, "application/json") mimetype = "application/json" else: s = compat.adhoc_marshaller(m1) mimetype = "text/xml" stringio = StringIO.StringIO() stringio.write(s) stringio.seek(0) response = Message() response.compose(code="200", reason="Ok", mimetype=mimetype, body=stringio) stream.send_response(request, response)
def process_request(self, stream, request): m = marshal.unmarshal_object(request.body.read(), "application/xml", compat.RendezvousRequest) m1 = compat.RendezvousResponse() # # If we don't say anything the rendezvous server is not # going to prompt for updates. We need to specify the # updated version number explicitly when we start it up. # This should guarantee that we do not advertise -rc # releases and other weird things. # version = self.conf["rendezvous.server.update_version"] if version and m.version: diff = LibVersion.compare(version, m.version) LOG.debug('rendezvous: version=%s m.version=%s diff=%f' % ( version, m.version, diff)) if diff > 0: m1.update["uri"] = self.conf["rendezvous.server.update_uri"] m1.update["version"] = version # # Select test server address. # The default test server is the master server itself. # If we know the country, lookup the list of servers for # that country in the database. # We only redirect to other servers clients that have # agreed to give us the permission to publish, in order # to be compliant with M-Lab policy. # If there are no servers for that country, register # the master server for the country so that we can notice # we have new users and can take the proper steps to # deploy nearby servers. # server = self.conf.get("rendezvous.server.default", "master.neubot.org") LOG.debug("* default test server: %s" % server) # # Backward compatibility: the variable name changed from # can_share to can_publish after Neubot 0.4.5 # request_body = m.__dict__.copy() if 'privacy_can_share' in request_body: request_body['privacy_can_publish'] = request_body[ 'privacy_can_share'] del request_body['privacy_can_share'] # Redirect IFF have ALL privacy permissions if privacy.count_valid(request_body, 'privacy_') == 3: agent_address = stream.peername[0] country = GEOLOCATOR.lookup_country(agent_address) if country: servers = table_geoloc.lookup_servers(DATABASE.connection(), country) if not servers: LOG.info("* learning new country: %s" % country) table_geoloc.insert_server(DATABASE.connection(), country, server) servers = [server] server = random.choice(servers) LOG.debug("* selected test server: %s" % server) if "speedtest" in m.accept: m1.available["speedtest"] = [ "http://%s/speedtest" % server ] if "bittorrent" in m.accept: m1.available["bittorrent"] = [ "http://%s/" % server ] # # Neubot <=0.3.7 expects to receive an XML document while # newer Neubots want a JSON. I hope old clients will upgrade # pretty soon. # if m.version and LibVersion.compare(m.version, "0.3.7") >= 0: s = marshal.marshal_object(m1, "application/json") mimetype = "application/json" else: s = compat.adhoc_marshaller(m1) mimetype = "text/xml" stringio = StringIO.StringIO() stringio.write(s) stringio.seek(0) response = Message() response.compose(code="200", reason="Ok", mimetype=mimetype, body=stringio) stream.send_response(request, response)
def process_request(self, stream, request): """ Process rendezvous request """ if request["content-type"] == "application/json": ibody = marshal.unmarshal_object(request.body.read(), "application/json", compat.RendezvousRequest) else: ibody = marshal.unmarshal_object(request.body.read(), "application/xml", compat.RendezvousRequest) obody = compat.RendezvousResponse() # # If we don't say anything the rendezvous server is not # going to prompt for updates. We need to specify the # updated version number explicitly when we start it up. # This should guarantee that we do not advertise -rc # releases and other weird things. # version = self.conf["rendezvous.server.update_version"] if version and ibody.version: diff = utils_version.compare(version, ibody.version) logging.debug("rendezvous: version=%s ibody.version=%s diff=%f", version, ibody.version, diff) if diff > 0: obody.update["uri"] = "http://neubot.org/" obody.update["version"] = version # # Select test server address. # The default test server is the master server itself. # If we know the country, lookup the list of servers for # that country in the database. # We only redirect to other servers clients that have # agreed to give us the permission to publish, in order # to be compliant with M-Lab policy. # If there are no servers for that country, register # the master server for the country so that we can notice # we have new users and can take the proper steps to # deploy nearby servers. # server = self.conf.get("rendezvous.server.default", "master.neubot.org") logging.debug("* default test server: %s", server) # # Backward compatibility: the variable name changed from # can_share to can_publish after Neubot 0.4.5 # request_body = ibody.__dict__.copy() if "privacy_can_share" in request_body: request_body["privacy_can_publish"] = request_body["privacy_can_share"] del request_body["privacy_can_share"] # Redirect IFF have ALL privacy permissions if privacy.count_valid(request_body, "privacy_") == 3: agent_address = stream.peername[0] country = GEOLOCATOR.lookup_country(agent_address) if country: servers = table_geoloc.lookup_servers(DATABASE.connection(), country) if not servers: logging.info("* learning new country: %s", country) table_geoloc.insert_server(DATABASE.connection(), country, server) servers = [server] server = random.choice(servers) logging.info("rendezvous_server: %s[%s] -> %s", agent_address, country, server) else: logging.warning("rendezvous_server: cannot redirect to M-Lab: %s", request_body) # # We require at least informed and can_collect since 0.4.4 # (released 25 October 2011), so stop clients with empty # privacy settings, who were still using master. # if privacy.collect_allowed(request_body): # # Note: Here we will have problems if we store unquoted # IPv6 addresses into the database. Because the resulting # URI won't be valid. # if "speedtest" in ibody.accept: obody.available["speedtest"] = ["http://%s/speedtest" % server] if "bittorrent" in ibody.accept: obody.available["bittorrent"] = ["http://%s/" % server] # # Neubot <=0.3.7 expects to receive an XML document while # newer Neubots want a JSON. I hope old clients will upgrade # pretty soon. # if ibody.version and utils_version.compare(ibody.version, "0.3.7") >= 0: body = marshal.marshal_object(obody, "application/json") mimetype = "application/json" else: body = compat.adhoc_marshaller(obody) mimetype = "text/xml" response = Message() response.compose(code="200", reason="Ok", mimetype=mimetype, body=body) stream.send_response(request, response)