⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 connectionratelimitreactor.py

📁 bittorrent source by python. please enjoy
💻 PY
字号:
# usage:## from twisted.internet import reactor# from ConnectionRateLimitReactor import connectionRateLimitReactor# connectionRateLimitReactor(reactor, max_incomplete=10)## by Greg Hazelimport threadingfrom twisted.python import threadablefrom twisted.internet import interfacestry:    from zope.interface import implements    zope = Trueexcept ImportError:    zope = Falseclass HookedFactory(object):    def __init__(self, reactor, factory, host):        self.reactor = reactor        self.factory = factory        self.host = host    def clientConnectionFailed(self, *a, **kw):        self.reactor._remove_pending_connection(self.host)        return self.factory.clientConnectionFailed(*a, **kw)    def buildProtocol(self, *a, **kw):        p = self.factory.buildProtocol(*a, **kw)        old_connectionMade = p.connectionMade        def connectionMade(*a2, **kw2):            self.reactor._remove_pending_connection(self.host)            return old_connectionMade(*a2, **kw2)        p.connectionMade = connectionMade        return p    def __getattr__(self, attr):        return getattr(self.factory, attr)    class IRobotConnector(object):    if zope:        try:            implements(interfaces.IConnector)        except:            # stupid zope verisons!            pass    def __init__(self, reactor, host, port, factory, timeout, bindAddress):        self.reactor = reactor        self.host = host        self.port = port        self.factory = factory        self.timeout = timeout        self.connector = None        self.bindAddress = bindAddress        self.do_not_connect = False        self.factory = HookedFactory(self.reactor, self.factory, self.host)    def disconnect(self):        if self.connector:            self.connector.disconnect()        else:            self.do_not_connect = True    stopConnecting = disconnect    def connect(self):        #print 'connecting', self.host, self.port        self.reactor.add_pending_connection(self.host)        self.connector = self.reactor.old_connectTCP(self.host, self.port,                                                     self.factory, self.timeout,                                                     self.bindAddress)        # hm, this might briefly connect, but at least it fires the callback        if self.do_not_connect:            self.connector.disconnect()        return self.connector    def getDestination(self):        return address.IPv4Address('TCP', self.host, self.port, 'INET')class ConnectionRateLimiter(object):    def __init__(self, reactor, max_incomplete):        self.reactor = reactor        self.pending_starters = []        self.max_incomplete = max_incomplete        # this can go away when urllib does        self.pending_sockets_lock = threading.RLock()        self.pending_sockets = {}        self.old_connectTCP = self.reactor.connectTCP    # safe from any thread        def add_pending_connection(self, host):        #print 'adding', host, 'iot', threadable.isInIOThread()        self.pending_sockets_lock.acquire()        self.pending_sockets.setdefault(host, 0)        self.pending_sockets[host] += 1        self.pending_sockets_lock.release()    # thread footwork, because _remove actually starts new connections    def remove_pending_connection(self, host):        if not threadable.isInIOThread():            self.reactor.callFromThread(self._remove_pending_connection, host)        else:            self._remove_pending_connection(host)    def _remove_pending_connection(self, host):        #print 'removing', host        self.pending_sockets_lock.acquire()        self.pending_sockets[host] -= 1        if self.pending_sockets[host] <= 0:            del self.pending_sockets[host]            self._push_new_connections()        self.pending_sockets_lock.release()    def _push_new_connections(self):        if not self.pending_starters:            return        c = self.pending_starters.pop(0)        c.connect()    def connectTCP(self, host, port, factory, timeout=30, bindAddress=None):        c = IRobotConnector(self, host, port, factory, timeout, bindAddress)                # the XP connection rate limiting is unique at the IP level        if (len(self.pending_sockets) >= self.max_incomplete and            host not in self.pending_sockets):            #print 'postponing', host, port            self.pending_starters.append(c)        else:            c.connect()                    return cdef connectionRateLimitReactor(reactor, max_incomplete):    limiter = ConnectionRateLimiter(reactor, max_incomplete)    assert not hasattr(reactor, 'crl_installed'), \           "reactor already has conncetion rate limiter installed"    reactor.connectTCP = limiter.connectTCP    reactor.add_pending_connection = limiter.add_pending_connection    reactor.remove_pending_connection = limiter.remove_pending_connection    reactor.crl_installed = True

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -