def __init__(self, poller): ServerHTTP.__init__(self, poller) self.begin_test = 0 POLLER.sched(3, self._speedtest_check_timeout) self.test_server = ServerTest(poller)
class ServerSpeedtest(ServerHTTP): def __init__(self, poller): ServerHTTP.__init__(self, poller) self.begin_test = 0 POLLER.sched(3, self._speedtest_check_timeout) self.test_server = ServerTest(poller) def configure(self, conf, measurer=None): conf["http.server.rootdir"] = "" ServerHTTP.configure(self, conf, measurer) def got_request_headers(self, stream, request): ret = True TRACKER.register_connection(stream, request["authorization"]) if request.uri == "/speedtest/upload": request.body.write = lambda octets: None only_auth = self.conf.get("speedtest.negotiate.auth_only", False) if (only_auth and request.uri != "/speedtest/negotiate" and not TRACKER.session_active(request["authorization"])): LOG.warning("* Connection %s: Forbidden" % stream.logname) ret = False return ret def process_request(self, stream, request): if request.uri == "/speedtest/negotiate": self.do_negotiate(stream, request) elif request.uri == "/speedtest/collect": self.do_collect(stream, request) else: self.test_server.process_request(stream, request) # # A client is allowed to access restricted URIs if: (i) either # only_auth is False, (ii) or the authorization token is valid. # Here we decide how to give clients authorization tokens. # We start with a very simple (to implement) rule. We give the # client a token and we remove the token after 30+ seconds, or # when the authorized client uploads the results. # Wish list: # - Avoid client synchronization # def _do_renegotiate(self, event, atuple): stream, request = atuple self.do_negotiate(stream, request, True) def _speedtest_check_timeout(self, *args, **kwargs): POLLER.sched(3, self._speedtest_check_timeout) if TRACKER.session_prune(): NOTIFIER.publish(RENEGOTIATE) def _speedtest_complete(self, request): TRACKER.session_delete(request["authorization"]) NOTIFIER.publish(RENEGOTIATE) 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 do_collect(self, stream, request): self._speedtest_complete(request) s = request.body.read() m = marshal.unmarshal_object(s, "text/xml", compat.SpeedtestCollect) if privacy.collect_allowed(m): table_speedtest.insertxxx(DATABASE.connection(), m) response = Message() response.compose(code="200", reason="Ok") stream.send_response(request, response) def connection_lost(self, stream): TRACKER.unregister_connection(stream) NOTIFIER.publish(RENEGOTIATE)