Exemplo n.º 1
0
 async def arequest(self, method, url, headers=None, stream=None, ext=None):
     retry = 2
     while retry > 0:
         retry -= 1
         try:
             return await super().arequest(method, url, headers, stream,
                                           ext)
         except (python_socks._errors.ProxyConnectionError,
                 python_socks._errors.ProxyTimeoutError,
                 python_socks._errors.ProxyError) as e:
             raise httpcore.ProxyError(e)
         except OSError as e:
             # socket.gaierror when DNS resolution fails
             raise httpcore.NetworkError(e)
         except httpcore.RemoteProtocolError as e:
             # in case of httpcore.RemoteProtocolError: Server disconnected
             await close_connections_for_url(self, url)
             logger.warning('httpcore.RemoteProtocolError: retry',
                            exc_info=e)
             # retry
         except (httpcore.NetworkError, httpcore.ProtocolError) as e:
             # httpcore.WriteError on HTTP/2 connection leaves a new opened stream
             # then each new request creates a new stream and raise the same WriteError
             await close_connections_for_url(self, url)
             raise e
Exemplo n.º 2
0
async def test_retries_enabled(server: Server) -> None:
    """
    When retries are enabled, connection failures are retried on with
    a fixed exponential backoff.
    """
    method = b"GET"
    url = (b"http", *server.netloc, b"/")
    headers = [server.host_header]
    backend = AsyncMockBackend()
    retries = 10  # Large enough to not run out of retries within this test.

    async with httpcore.AsyncConnectionPool(retries=retries,
                                            max_keepalive_connections=0,
                                            backend=backend) as http:
        # Standard case, no failures.
        response = await http.arequest(method, url, headers)
        assert backend.pop_open_tcp_stream_intervals() == []
        status_code, _, stream, _ = response
        assert status_code == 200
        await read_body(stream)

        # One failure, then success.
        backend.push(httpcore.ConnectError(), None)
        response = await http.arequest(method, url, headers)
        assert backend.pop_open_tcp_stream_intervals() == [
            pytest.approx(0, abs=1e-3),  # Retry immediately.
        ]
        status_code, _, stream, _ = response
        assert status_code == 200
        await read_body(stream)

        # Three failures, then success.
        backend.push(
            httpcore.ConnectError(),
            httpcore.ConnectTimeout(),
            httpcore.ConnectTimeout(),
            None,
        )
        response = await http.arequest(method, url, headers)
        assert backend.pop_open_tcp_stream_intervals() == [
            pytest.approx(0, abs=1e-3),  # Retry immediately.
            pytest.approx(0.5, rel=0.1),  # First backoff.
            pytest.approx(1.0, rel=0.1),  # Second (increased) backoff.
        ]
        status_code, _, stream, _ = response
        assert status_code == 200
        await read_body(stream)

        # Non-connect exceptions are not retried on.
        backend.push(httpcore.ReadTimeout(), httpcore.NetworkError())
        with pytest.raises(httpcore.ReadTimeout):
            await http.arequest(method, url, headers)
        with pytest.raises(httpcore.NetworkError):
            await http.arequest(method, url, headers)
Exemplo n.º 3
0
def test_side_effect_exception():
    router = Router()
    router.get("https://foo.bar/").side_effect(httpx.ConnectError)
    router.get("https://ham.spam/").side_effect(httpcore.NetworkError)
    router.get("https://egg.plant/").side_effect(httpcore.NetworkError())

    request = httpx.Request("GET", "https://foo.bar")
    with pytest.raises(httpx.ConnectError) as e:
        router.resolve(request)
    assert e.value.request == request

    request = httpx.Request("GET", "https://ham.spam")
    with pytest.raises(httpcore.NetworkError) as e:
        router.resolve(request)

    request = httpx.Request("GET", "https://egg.plant")
    with pytest.raises(httpcore.NetworkError) as e:
        router.resolve(request)
Exemplo n.º 4
0
 def _callback(request):
     raise httpcore.NetworkError()