diff options
| author | Bruno Wagner <bwgpro@gmail.com> | 2015-07-22 23:55:39 -0300 | 
|---|---|---|
| committer | Kali Kaneko <kali@leap.se> | 2015-07-23 16:16:36 -0400 | 
| commit | 5502318835626527d9818c360c7fd2b1a4b01145 (patch) | |
| tree | 0d50168ab691001be605a9d50e034064b20f34db /src | |
| parent | 301be892a67f88b8b9479531003403a77b36a5f2 (diff) | |
[tests] implemented http feature according to test
Two test cases were broken and were implemented here:
The first was that HTTPClient should share the connection between
clients if a pool was not passed explicitly. If you initialize an
HTTPClient without a pool, it will reuse a pool created on the class.
The second was that you should be able to pass to the HTTPCLient a pool
on initialization. Added that possibility and fixed the tests accordingly
Diffstat (limited to 'src')
| -rw-r--r-- | src/leap/common/http.py | 98 | ||||
| -rw-r--r-- | src/leap/common/tests/test_http.py | 7 | 
2 files changed, 59 insertions, 46 deletions
| diff --git a/src/leap/common/http.py b/src/leap/common/http.py index 56938b4..f67507d 100644 --- a/src/leap/common/http.py +++ b/src/leap/common/http.py @@ -56,6 +56,50 @@ __all__ = ["HTTPClient"]  DEFAULT_HTTP_TIMEOUT = 30  # seconds +class _HTTP11ClientFactory(HTTP11ClientFactory): +    """ +    A timeout-able HTTP 1.1 client protocol factory. +    """ + +    def __init__(self, quiescentCallback, timeout): +        """ +        :param quiescentCallback: The quiescent callback to be passed to +                                  protocol instances, used to return them to +                                  the connection pool. +        :type quiescentCallback: callable(Protocol) +        :param timeout: The timeout, in seconds, for requests made by +                        protocols created by this factory. +        :type timeout: float +        """ +        HTTP11ClientFactory.__init__(self, quiescentCallback) +        self._timeout = timeout + +    def buildProtocol(self, _): +        """ +        Build the HTTP 1.1 client protocol. +        """ +        return _HTTP11ClientProtocol(self._quiescentCallback, self._timeout) + + +class _HTTPConnectionPool(HTTPConnectionPool): +    """ +    A timeout-able HTTP connection pool. +    """ + +    _factory = _HTTP11ClientFactory + +    def __init__(self, reactor, persistent, timeout, maxPersistentPerHost=10): +        HTTPConnectionPool.__init__(self, reactor, persistent=persistent) +        self.maxPersistentPerHost = maxPersistentPerHost +        self._timeout = timeout + +    def _newConnection(self, key, endpoint): +        def quiescentCallback(protocol): +            self._putConnection(key, protocol) +        factory = self._factory(quiescentCallback, timeout=self._timeout) +        return endpoint.connect(factory) + +  class HTTPClient(object):      """      HTTP client done the twisted way, with a main focus on pinning the SSL @@ -69,7 +113,14 @@ class HTTPClient(object):      in order to avoid resource abuse on huge requests batches.      """ -    def __init__(self, cert_file=None, timeout=DEFAULT_HTTP_TIMEOUT): +    _pool = _HTTPConnectionPool( +        reactor, +        persistent=True, +        timeout = DEFAULT_HTTP_TIMEOUT, +        maxPersistentPerHost=10 +    ) + +    def __init__(self, cert_file=None, timeout=DEFAULT_HTTP_TIMEOUT, pool=None):          """          Init the HTTP client @@ -84,7 +135,7 @@ class HTTPClient(object):          """          self._timeout = timeout -        self._pool = self._createPool() +        self._pool = pool if pool is not None else self._pool          self._agent = Agent(              reactor,              get_compatible_ssl_context_factory(cert_file), @@ -278,46 +329,3 @@ class _HTTP11ClientProtocol(HTTP11ClientProtocol):          HTTP11ClientProtocol.dataReceived(self, bytes)          if self._timeoutCall and self._timeoutCall.active():              self._timeoutCall.reset(self._timeout) - - -class _HTTP11ClientFactory(HTTP11ClientFactory): -    """ -    A timeout-able HTTP 1.1 client protocol factory. -    """ - -    def __init__(self, quiescentCallback, timeout): -        """ -        :param quiescentCallback: The quiescent callback to be passed to -                                  protocol instances, used to return them to -                                  the connection pool. -        :type quiescentCallback: callable(Protocol) -        :param timeout: The timeout, in seconds, for requests made by -                        protocols created by this factory. -        :type timeout: float -        """ -        HTTP11ClientFactory.__init__(self, quiescentCallback) -        self._timeout = timeout - -    def buildProtocol(self, _): -        """ -        Build the HTTP 1.1 client protocol. -        """ -        return _HTTP11ClientProtocol(self._quiescentCallback, self._timeout) - - -class _HTTPConnectionPool(HTTPConnectionPool): -    """ -    A timeout-able HTTP connection pool. -    """ - -    _factory = _HTTP11ClientFactory - -    def __init__(self, reactor, persistent, timeout): -        HTTPConnectionPool.__init__(self, reactor, persistent=persistent) -        self._timeout = timeout - -    def _newConnection(self, key, endpoint): -        def quiescentCallback(protocol): -            self._putConnection(key, protocol) -        factory = self._factory(quiescentCallback, timeout=self._timeout) -        return endpoint.connect(factory) diff --git a/src/leap/common/tests/test_http.py b/src/leap/common/tests/test_http.py index e240ca3..a586fd1 100644 --- a/src/leap/common/tests/test_http.py +++ b/src/leap/common/tests/test_http.py @@ -47,7 +47,12 @@ class HTTPClientTest(BaseLeapTest):          self.assertEquals(client._agent._pool, client2._agent._pool, "Pool was not reused by default")      def test_agent_can_have_dedicated_custom_pool(self): -        custom_pool = http.createPool(maxPersistentPerHost=42, persistent=False) +        custom_pool = http._HTTPConnectionPool( +            None, +            timeout=10, +            maxPersistentPerHost=42, +            persistent=False +        )          self.assertEquals(custom_pool.maxPersistentPerHost, 42,                            "Custom persistent connections limit is not being respected")          self.assertFalse(custom_pool.persistent, | 
