def test_total_timeout(self): url = '/sleep?seconds=0.005' timeout = util.Timeout(connect=3, read=5, total=0.001) pool = HTTPConnectionPool(TARPIT_HOST, self.port, timeout=timeout) conn = pool._get_conn() self.assertRaises(ConnectTimeoutError, pool._make_request, conn, 'GET', url) # This will get the socket to raise an EAGAIN on the read timeout = util.Timeout(connect=3, read=0) pool = HTTPConnectionPool(self.host, self.port, timeout=timeout) conn = pool._get_conn() self.assertRaises(ReadTimeoutError, pool._make_request, conn, 'GET', url) # The connect should succeed and this should hit the read timeout timeout = util.Timeout(connect=3, read=5, total=0.002) pool = HTTPConnectionPool(self.host, self.port, timeout=timeout) conn = pool._get_conn() self.assertRaises(ReadTimeoutError, pool._make_request, conn, 'GET', url) timeout = util.Timeout(total=None, connect=0.001) pool = HTTPConnectionPool(TARPIT_HOST, self.port, timeout=timeout) conn = pool._get_conn() self.assertRaises(ConnectTimeoutError, pool._make_request, conn, 'GET', url)
def test_connect_timeout(self): url = '/sleep' timeout = util.Timeout(connect=0.001) # Pool-global timeout pool = HTTPConnectionPool(TARPIT_HOST, self.port, timeout=timeout) conn = pool._get_conn() self.assertRaises(ConnectTimeoutError, pool._make_request, conn, 'GET', url) pool._put_conn(conn) self.assertRaises(ConnectTimeoutError, pool.request, 'GET', url) # Request-specific connection timeouts big_timeout = util.Timeout(read=0.5, connect=0.5) pool = HTTPConnectionPool(TARPIT_HOST, self.port, timeout=big_timeout) conn = pool._get_conn() self.assertRaises(ConnectTimeoutError, pool._make_request, conn, 'GET', url, timeout=timeout) pool._put_conn(conn) self.assertRaises(ConnectTimeoutError, pool.request, 'GET', url, timeout=timeout)
def test_timeout_success(self): timeout = util.Timeout(connect=3, read=5, total=None) pool = HTTPConnectionPool(self.host, self.port, timeout=timeout) pool.request('GET', '/') # This should not raise a "Timeout already started" error pool.request('GET', '/') pool = HTTPConnectionPool(self.host, self.port, timeout=timeout) # This should also not raise a "Timeout already started" error pool.request('GET', '/') timeout = util.Timeout(total=None) pool = HTTPConnectionPool(self.host, self.port, timeout=timeout) pool.request('GET', '/')
def test_delayed_body_read_timeout(self): timed_out = Event() def socket_handler(listener): sock = listener.accept()[0] buf = b'' body = 'Hi' while not buf.endswith(b'\r\n\r\n'): buf = sock.recv(65536) sock.send(('HTTP/1.1 200 OK\r\n' 'Content-Type: text/plain\r\n' 'Content-Length: %d\r\n' '\r\n' % len(body)).encode('utf-8')) timed_out.wait(timeout=0.05) sock.send(body.encode('utf-8')) sock.close() self._start_server(socket_handler) pool = HTTPConnectionPool(self.host, self.port) response = pool.urlopen('GET', '/', retries=0, preload_content=False, timeout=util.Timeout(connect=1, read=0.001)) self.assertRaises(ReadTimeoutError, response.read) timed_out.set()
def test_timeout_reset(self): """ If the read timeout isn't set, socket timeout should reset """ url = '/sleep?seconds=0.005' timeout = util.Timeout(connect=0.001) pool = HTTPConnectionPool(self.host, self.port, timeout=timeout) conn = pool._get_conn() try: pool._make_request(conn, 'GET', url) except ReadTimeoutError: self.fail("This request shouldn't trigger a read timeout.")
def test_tunnel(self): # note the actual httplib.py has no tests for this functionality timeout = util.Timeout(total=None) pool = HTTPConnectionPool(self.host, self.port, timeout=timeout) conn = pool._get_conn() try: conn.set_tunnel(self.host, self.port) except AttributeError: # python 2.6 conn._set_tunnel(self.host, self.port) conn._tunnel = mock.Mock(return_value=None) pool._make_request(conn, 'GET', '/') conn._tunnel.assert_called_once_with() # test that it's not called when tunnel is not set timeout = util.Timeout(total=None) pool = HTTPConnectionPool(self.host, self.port, timeout=timeout) conn = pool._get_conn() conn._tunnel = mock.Mock(return_value=None) pool._make_request(conn, 'GET', '/') self.assertEqual(conn._tunnel.called, False)
def test_timeout(self): url = '/sleep?seconds=0.005' timeout = util.Timeout(read=0.001) # Pool-global timeout pool = HTTPConnectionPool(self.host, self.port, timeout=timeout) conn = pool._get_conn() self.assertRaises(ReadTimeoutError, pool._make_request, conn, 'GET', url) pool._put_conn(conn) self.assertRaises(ReadTimeoutError, pool.request, 'GET', url) # Request-specific timeouts should raise errors pool = HTTPConnectionPool(self.host, self.port, timeout=0.5) conn = pool._get_conn() self.assertRaises(ReadTimeoutError, pool._make_request, conn, 'GET', url, timeout=timeout) pool._put_conn(conn) self.assertRaises(ReadTimeoutError, pool.request, 'GET', url, timeout=timeout) # Timeout int/float passed directly to request and _make_request should # raise a request timeout self.assertRaises(ReadTimeoutError, pool.request, 'GET', url, timeout=0.001) conn = pool._new_conn() self.assertRaises(ReadTimeoutError, pool._make_request, conn, 'GET', url, timeout=0.001) pool._put_conn(conn) # Timeout int/float passed directly to _make_request should not raise a # request timeout if it's a high value pool.request('GET', url, timeout=5)
def test_timeout_errors_cause_retries(self): def socket_handler(listener): sock = listener.accept()[0] # First request. # Pause before responding so the first request times out. time.sleep(0.002) sock.close() sock = listener.accept()[0] # Second request. buf = b'' while not buf.endswith(b'\r\n\r\n'): buf += sock.recv(65536) # Now respond immediately. body = 'Response 2' sock.send(('HTTP/1.1 200 OK\r\n' 'Content-Type: text/plain\r\n' 'Content-Length: %d\r\n' '\r\n' '%s' % (len(body), body)).encode('utf-8')) sock.close() # Close the socket. # In situations where the main thread throws an exception, the server # thread can hang on an accept() call. This ensures everything times # out within 3 seconds. This should be long enough for any socket # operations in the test suite to complete default_timeout = socket.getdefaulttimeout() socket.setdefaulttimeout(1) try: self._start_server(socket_handler) t = util.Timeout(connect=0.001, read=0.001) pool = HTTPConnectionPool(self.host, self.port, timeout=t) response = pool.request('GET', '/', retries=1) self.assertEqual(response.status, 200) self.assertEqual(response.data, b'Response 2') finally: socket.setdefaulttimeout(default_timeout)