Exemple #1
0
 def test_merge_pool_kwargs_none(self):
     """Assert false-y values to _merge_pool_kwargs result in defaults"""
     p = PoolManager(strict=True)
     merged = p._merge_pool_kwargs({})
     assert p.connection_pool_kw == merged
     merged = p._merge_pool_kwargs(None)
     assert p.connection_pool_kw == merged
    def test_cross_host_redirect(self):
        http = PoolManager()
        self.addCleanup(http.clear)

        cross_host_location = '%s/echo?a=b' % self.base_url_alt
        try:
            http.request('GET',
                         '%s/redirect' % self.base_url,
                         fields={'target': cross_host_location},
                         timeout=1,
                         retries=0)
            self.fail(
                "Request succeeded instead of raising an exception like it should."
            )

        except MaxRetryError:
            pass

        r = http.request('GET',
                         '%s/redirect' % self.base_url,
                         fields={'target': '%s/echo?a=b' % self.base_url_alt},
                         timeout=1,
                         retries=1)

        self.assertEqual(r._pool.host, self.host_alt)
    def test_too_many_redirects(self):
        http = PoolManager()
        self.addCleanup(http.clear)

        try:
            r = http.request('GET',
                             '%s/redirect' % self.base_url,
                             fields={
                                 'target':
                                 '%s/redirect?target=%s/' %
                                 (self.base_url, self.base_url)
                             },
                             retries=1)
            self.fail("Failed to raise MaxRetryError exception, returned %r" %
                      r.status)
        except MaxRetryError:
            pass

        try:
            r = http.request('GET',
                             '%s/redirect' % self.base_url,
                             fields={
                                 'target':
                                 '%s/redirect?target=%s/' %
                                 (self.base_url, self.base_url)
                             },
                             retries=Retry(total=None, redirect=1))
            self.fail("Failed to raise MaxRetryError exception, returned %r" %
                      r.status)
        except MaxRetryError:
            pass
Exemple #4
0
 def test_assert_hostname_and_fingerprint_flag(self):
     """Assert that pool manager can accept hostname and fingerprint flags."""
     fingerprint = '92:81:FE:85:F7:0C:26:60:EC:D6:B3:BF:93:CF:F9:71:CC:07:7D:0A'
     p = PoolManager(assert_hostname=True, assert_fingerprint=fingerprint)
     pool = p.connection_from_url('https://example.com/')
     assert 1 == len(p.pools)
     assert pool.assert_hostname
     assert fingerprint == pool.assert_fingerprint
Exemple #5
0
    def test_http_connection_from_url_case_insensitive(self):
        """Assert scheme case is ignored when pooling HTTP connections."""
        p = PoolManager()
        pool = p.connection_from_url('http://example.com/')
        other_pool = p.connection_from_url('HTTP://EXAMPLE.COM/')

        assert 1 == len(p.pools)
        assert pool is other_pool
        assert all(isinstance(key, PoolKey) for key in p.pools.keys())
Exemple #6
0
    def test_http_connection_from_host_case_insensitive(self):
        """Assert scheme case is ignored when getting the https key class."""
        p = PoolManager()
        pool = p.connection_from_host('example.com', scheme='http')
        other_pool = p.connection_from_host('EXAMPLE.COM', scheme='HTTP')

        assert 1 == len(p.pools)
        assert pool is other_pool
        assert all(isinstance(key, PoolKey) for key in p.pools.keys())
Exemple #7
0
    def test_https_pool_key_fields(self):
        """Assert the HTTPSPoolKey fields are honored when selecting a pool."""
        connection_pool_kw = [
            ('timeout', timeout.Timeout(3.14)),
            ('retries', retry.Retry(total=6, connect=2)),
            ('block', True),
            ('source_address', '127.0.0.1'),
            ('key_file', DEFAULT_CERTS['keyfile']),
            ('cert_file', DEFAULT_CERTS['certfile']),
            ('cert_reqs', 'CERT_REQUIRED'),
            ('ca_certs', DEFAULT_CA),
            ('ca_cert_dir', DEFAULT_CA_DIR),
            ('ssl_version', 'SSLv23'),
            ('ssl_context', ssl_.create_urllib3_context()),
        ]
        p = PoolManager()
        conn_pools = [
            p.connection_from_url('https://example.com/'),
            p.connection_from_url('https://example.com:4333/'),
            p.connection_from_url('https://other.example.com/'),
        ]
        # Asking for a connection pool with the same key should give us an
        # existing pool.
        dup_pools = []

        for key, value in connection_pool_kw:
            p.connection_pool_kw[key] = value
            conn_pools.append(p.connection_from_url('https://example.com/'))
            dup_pools.append(p.connection_from_url('https://example.com/'))

        assert all(x is not y for i, x in enumerate(conn_pools)
                   for j, y in enumerate(conn_pools) if i != j)
        assert all(pool in conn_pools for pool in dup_pools)
        assert all(isinstance(key, PoolKey) for key in p.pools.keys())
Exemple #8
0
    def test_override_pool_kwargs_url(self):
        """Assert overriding pool kwargs works with connection_from_url."""
        p = PoolManager(block=False)
        pool_kwargs = {'retries': 100, 'block': True}

        default_pool = p.connection_from_url('http://example.com/')
        override_pool = p.connection_from_url('http://example.com/',
                                              pool_kwargs=pool_kwargs)

        assert retry.Retry.DEFAULT == default_pool.retries
        assert not default_pool.block

        assert 100 == override_pool.retries
        assert override_pool.block
    def test_headers(self):
        http = PoolManager(headers={'Foo': 'bar'})
        self.addCleanup(http.clear)

        r = http.request('GET', '%s/headers' % self.base_url)
        returned_headers = json.loads(r.data.decode())
        self.assertEqual(returned_headers.get('Foo'), 'bar')

        r = http.request('POST', '%s/headers' % self.base_url)
        returned_headers = json.loads(r.data.decode())
        self.assertEqual(returned_headers.get('Foo'), 'bar')

        r = http.request_encode_url('GET', '%s/headers' % self.base_url)
        returned_headers = json.loads(r.data.decode())
        self.assertEqual(returned_headers.get('Foo'), 'bar')

        r = http.request_encode_body('POST', '%s/headers' % self.base_url)
        returned_headers = json.loads(r.data.decode())
        self.assertEqual(returned_headers.get('Foo'), 'bar')

        r = http.request_encode_url('GET',
                                    '%s/headers' % self.base_url,
                                    headers={'Baz': 'quux'})
        returned_headers = json.loads(r.data.decode())
        self.assertEqual(returned_headers.get('Foo'), None)
        self.assertEqual(returned_headers.get('Baz'), 'quux')

        r = http.request_encode_body('GET',
                                     '%s/headers' % self.base_url,
                                     headers={'Baz': 'quux'})
        returned_headers = json.loads(r.data.decode())
        self.assertEqual(returned_headers.get('Foo'), None)
        self.assertEqual(returned_headers.get('Baz'), 'quux')
Exemple #10
0
    def test_pool_kwargs_socket_options(self):
        """Assert passing socket options works with connection_from_host"""
        p = PoolManager(socket_options=[])
        override_opts = [(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1),
                         (socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]
        pool_kwargs = {'socket_options': override_opts}

        default_pool = p.connection_from_host('example.com', scheme='http')
        override_pool = p.connection_from_host('example.com',
                                               scheme='http',
                                               pool_kwargs=pool_kwargs)

        assert default_pool.conn_kw['socket_options'] == []
        assert override_pool.conn_kw['socket_options'] == override_opts
Exemple #11
0
    def test_http_connection_from_context_case_insensitive(self):
        """Assert scheme case is ignored when getting the https key class."""
        p = PoolManager()
        context = {'scheme': 'http', 'host': 'example.com', 'port': '8080'}
        other_context = {
            'scheme': 'HTTP',
            'host': 'EXAMPLE.COM',
            'port': '8080'
        }
        pool = p.connection_from_context(context)
        other_pool = p.connection_from_context(other_context)

        assert 1 == len(p.pools)
        assert pool is other_pool
        assert all(isinstance(key, PoolKey) for key in p.pools.keys())
    def test_cleanup_on_connection_error(self):
        '''
        Test that connections are recycled to the pool on
        connection errors where no http response is received.
        '''
        poolsize = 3

        with PoolManager(maxsize=poolsize, block=True) as http:
            pool = http.connection_from_host(self.host, self.port)
            self.assertEqual(pool.pool.qsize(), poolsize)

            # force a connection error by supplying a non-existent
            # url. We won't get a response for this  and so the
            # conn won't be implicitly returned to the pool.
            url = "%s/redirect" % self.base_url
            self.assertRaises(MaxRetryError,
                              http.request,
                              'GET',
                              url,
                              fields={'target': '/'},
                              retries=0)

            r = http.request('GET', url, fields={'target': '/'}, retries=1)
            r.release_conn()

            # the pool should still contain poolsize elements
            self.assertEqual(pool.pool.qsize(), poolsize)
    def test_multi_redirect_history(self):
        with PoolManager() as http:
            r = http.request('GET',
                             '%s/multi_redirect' % self.base_url,
                             fields={'redirect_codes': '303,302,200'},
                             redirect=False)
            self.assertEqual(r.status, 303)
            self.assertEqual(r.retries.history, tuple())

            r = http.request(
                'GET',
                '%s/multi_redirect' % self.base_url,
                retries=10,
                fields={'redirect_codes': '303,302,301,307,302,200'})
            self.assertEqual(r.status, 200)
            self.assertEqual(r.data, b'Done redirecting')

            expected = [
                (303, '/multi_redirect?redirect_codes=302,301,307,302,200'),
                (302, '/multi_redirect?redirect_codes=301,307,302,200'),
                (301, '/multi_redirect?redirect_codes=307,302,200'),
                (307, '/multi_redirect?redirect_codes=302,200'),
                (302, '/multi_redirect?redirect_codes=200')
            ]
            actual = [(history.status, history.redirect_location)
                      for history in r.retries.history]
            self.assertEqual(actual, expected)
    def test_redirect_after(self):
        with PoolManager() as http:
            r = http.request('GET',
                             '%s/redirect_after' % self.base_url,
                             retries=False)
            self.assertEqual(r.status, 303)

            t = time.time()
            r = http.request('GET', '%s/redirect_after' % self.base_url)
            self.assertEqual(r.status, 200)
            delta = time.time() - t
            self.assertTrue(delta >= 1)

            t = time.time()
            timestamp = t + 2
            r = http.request(
                'GET',
                self.base_url + '/redirect_after?date=' + str(timestamp))
            self.assertEqual(r.status, 200)
            delta = time.time() - t
            self.assertTrue(delta >= 1)

            # Retry-After is past
            t = time.time()
            timestamp = t - 1
            r = http.request(
                'GET',
                self.base_url + '/redirect_after?date=' + str(timestamp))
            delta = time.time() - t
            self.assertEqual(r.status, 200)
            self.assertTrue(delta < 1)
    def test_raise_on_redirect(self):
        http = PoolManager()
        self.addCleanup(http.clear)

        r = http.request('GET',
                         '%s/redirect' % self.base_url,
                         fields={
                             'target':
                             '%s/redirect?target=%s/' %
                             (self.base_url, self.base_url)
                         },
                         retries=Retry(total=None,
                                       redirect=1,
                                       raise_on_redirect=False))

        self.assertEqual(r.status, 303)
    def test_redirect_to_relative_url(self):
        http = PoolManager()
        self.addCleanup(http.clear)

        r = http.request('GET',
                         '%s/redirect' % self.base_url,
                         fields={'target': '/redirect'},
                         redirect=False)

        self.assertEqual(r.status, 303)

        r = http.request('GET',
                         '%s/redirect' % self.base_url,
                         fields={'target': '/redirect'})

        self.assertEqual(r.status, 200)
        self.assertEqual(r.data, b'Dummy server!')
    def test_missing_port(self):
        # Can a URL that lacks an explicit port like ':80' succeed, or
        # will all such URLs fail with an error?

        http = PoolManager()
        self.addCleanup(http.clear)

        # By globally adjusting `DEFAULT_PORTS` we pretend for a moment
        # that HTTP's default port is not 80, but is the port at which
        # our test server happens to be listening.
        DEFAULT_PORTS['http'] = self.port
        try:
            r = http.request('GET', 'http://%s/' % self.host, retries=0)
        finally:
            DEFAULT_PORTS['http'] = 80

        self.assertEqual(r.status, 200)
        self.assertEqual(r.data, b'Dummy server!')
    def test_read_retries_unsuccessful(self):
        headers = {'test-name': 'test_read_retries_unsuccessful'}

        with PoolManager() as http:
            resp = http.request('GET',
                                '%s/successful_retry' % self.base_url,
                                headers=headers,
                                retries=1)
            self.assertEqual(resp.status, 418)
    def test_retries_wrong_whitelist(self):
        """HTTP response w/ status code not in whitelist shouldn't be retried"""
        retry = Retry(total=1, status_forcelist=[202])

        with PoolManager() as http:
            resp = http.request('GET',
                                '%s/successful_retry' % self.base_url,
                                headers={'test-name': 'test_wrong_whitelist'},
                                retries=retry)
            self.assertEqual(resp.status, 418)
 def test_retry_redirect_history(self):
     with PoolManager() as http:
         resp = http.request('GET',
                             '%s/redirect' % self.base_url,
                             fields={'target': '/'})
         self.assertEqual(resp.status, 200)
         self.assertEqual(
             resp.retries.history,
             (RequestHistory('GET', self.base_url + '/redirect?target=%2F',
                             None, 303, '/'), ))
    def test_read_retries(self):
        """ Should retry for status codes in the whitelist """
        retry = Retry(read=1, status_forcelist=[418])

        with PoolManager() as http:
            resp = http.request('GET',
                                '%s/successful_retry' % self.base_url,
                                headers={'test-name': 'test_read_retries'},
                                retries=retry)
            self.assertEqual(resp.status, 200)
    def test_read_total_retries(self):
        """ HTTP response w/ status code in the whitelist should be retried """
        headers = {'test-name': 'test_read_total_retries'}
        retry = Retry(total=1, status_forcelist=[418])

        with PoolManager() as http:
            resp = http.request('GET',
                                '%s/successful_retry' % self.base_url,
                                headers=headers,
                                retries=retry)
            self.assertEqual(resp.status, 200)
    def test_default_method_whitelist_retried(self):
        """ urllib3 should retry methods in the default method whitelist """
        retry = Retry(total=1, status_forcelist=[418])

        with PoolManager() as http:
            resp = http.request(
                'OPTIONS',
                '%s/successful_retry' % self.base_url,
                headers={'test-name': 'test_default_whitelist'},
                retries=retry)
            self.assertEqual(resp.status, 200)
Exemple #24
0
    def test_manager_clear(self):
        p = PoolManager(5)

        conn_pool = p.connection_from_url('http://google.com')
        assert len(p.pools) == 1

        conn = conn_pool._get_conn()

        p.clear()
        assert len(p.pools) == 0

        with pytest.raises(ClosedPoolError):
            conn_pool._get_conn()

        conn_pool._put_conn(conn)

        with pytest.raises(ClosedPoolError):
            conn_pool._get_conn()

        assert len(p.pools) == 0
Exemple #25
0
    def test_many_urls(self):
        urls = [
            "http://localhost:8081/foo",
            "http://www.google.com/mail",
            "http://localhost:8081/bar",
            "https://www.google.com/",
            "https://www.google.com/mail",
            "http://yahoo.com",
            "http://bing.com",
            "http://yahoo.com/",
        ]

        connections = set()

        p = PoolManager(10)

        for url in urls:
            conn = p.connection_from_url(url)
            connections.add(conn)

        assert len(connections) == 5
 def test_max_retry(self):
     with PoolManager() as http:
         try:
             r = http.request('GET',
                              '%s/redirect' % self.base_url,
                              fields={'target': '/'},
                              retries=0)
             self.fail(
                 "Failed to raise MaxRetryError exception, returned %r" %
                 r.status)
         except MaxRetryError:
             pass
    def test_retry_return_in_response(self):
        headers = {'test-name': 'test_retry_return_in_response'}
        retry = Retry(total=2, status_forcelist=[418])

        with PoolManager() as http:
            resp = http.request('GET',
                                '%s/successful_retry' % self.base_url,
                                headers=headers,
                                retries=retry)
            self.assertEqual(resp.status, 200)
            self.assertEqual(resp.retries.total, 1)
            self.assertEqual(resp.retries.history, (RequestHistory(
                'GET', '/successful_retry', None, 418, None), ))
    def test_retries_wrong_method_list(self):
        """Method not in our whitelist should not be retried, even if code matches"""
        headers = {'test-name': 'test_wrong_method_whitelist'}
        retry = Retry(total=1,
                      status_forcelist=[418],
                      method_whitelist=['POST'])

        with PoolManager() as http:
            resp = http.request('GET',
                                '%s/successful_retry' % self.base_url,
                                headers=headers,
                                retries=retry)
            self.assertEqual(resp.status, 418)
    def test_raise_on_status(self):
        http = PoolManager()
        self.addCleanup(http.clear)

        try:
            # the default is to raise
            r = http.request('GET',
                             '%s/status' % self.base_url,
                             fields={'status': '500 Internal Server Error'},
                             retries=Retry(total=1,
                                           status_forcelist=range(500, 600)))
            self.fail("Failed to raise MaxRetryError exception, returned %r" %
                      r.status)
        except MaxRetryError:
            pass

        try:
            # raise explicitly
            r = http.request('GET',
                             '%s/status' % self.base_url,
                             fields={'status': '500 Internal Server Error'},
                             retries=Retry(total=1,
                                           status_forcelist=range(500, 600),
                                           raise_on_status=True))
            self.fail("Failed to raise MaxRetryError exception, returned %r" %
                      r.status)
        except MaxRetryError:
            pass

        # don't raise
        r = http.request('GET',
                         '%s/status' % self.base_url,
                         fields={'status': '500 Internal Server Error'},
                         retries=Retry(total=1,
                                       status_forcelist=range(500, 600),
                                       raise_on_status=False))

        self.assertEqual(r.status, 500)
Exemple #30
0
    def test_pools_keyed_with_from_host(self):
        """Assert pools are still keyed correctly with connection_from_host."""
        ssl_kw = [
            ('key_file', DEFAULT_CERTS['keyfile']),
            ('cert_file', DEFAULT_CERTS['certfile']),
            ('cert_reqs', 'CERT_REQUIRED'),
            ('ca_certs', DEFAULT_CA),
            ('ca_cert_dir', DEFAULT_CA_DIR),
            ('ssl_version', 'SSLv23'),
            ('ssl_context', ssl_.create_urllib3_context()),
        ]
        p = PoolManager()
        conns = []
        conns.append(p.connection_from_host('example.com', 443,
                                            scheme='https'))

        for k, v in ssl_kw:
            p.connection_pool_kw[k] = v
            conns.append(
                p.connection_from_host('example.com', 443, scheme='https'))

        assert all(x is not y for i, x in enumerate(conns)
                   for j, y in enumerate(conns) if i != j)