コード例 #1
0
ファイル: negotiate.py プロジェクト: ClaudioArtusio/neubot
 def __init__(self, poller):
     ServerHTTP.__init__(self, poller)
     self.begin_test = 0
     POLLER.sched(3, self._speedtest_check_timeout)
     self.test_server = ServerTest(poller)
コード例 #2
0
ファイル: negotiate.py プロジェクト: ClaudioArtusio/neubot
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)