encode / httpcore

A minimal HTTP client. ⚙️
https://www.encode.io/httpcore/
BSD 3-Clause "New" or "Revised" License
451 stars 97 forks source link

sslv3 alert handshake failure #917

Closed DouglasBlackwood closed 3 months ago

DouglasBlackwood commented 3 months ago

Hi!

I've encountered an error lately. It happened once.

Here is the stack trace:

SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1000)
[...]
  File "httpx/_client.py", line 1574, in request
    return await self.send(request, auth=auth, follow_redirects=follow_redirects)
  File "ddtrace/contrib/httpx/patch.py", line 137, in _wrapped_async_send
    resp = await wrapped(*args, **kwargs)
  File "httpx/_client.py", line 1661, in send
    response = await self._send_handling_auth(
  File "httpx/_client.py", line 1689, in _send_handling_auth
    response = await self._send_handling_redirects(
  File "httpx/_client.py", line 1726, in _send_handling_redirects
    response = await self._send_single_request(request)
  File "httpx/_client.py", line 1763, in _send_single_request
    response = await transport.handle_async_request(request)
  File "httpx/_transports/default.py", line 373, in handle_async_request
    resp = await self._pool.handle_async_request(req)
  File "httpcore/_async/connection_pool.py", line 216, in handle_async_request
    raise exc from None
  File "httpcore/_async/connection_pool.py", line 196, in handle_async_request
    response = await connection.handle_async_request(
  File "httpcore/_async/connection.py", line 99, in handle_async_request
    raise exc
  File "httpcore/_async/connection.py", line 76, in handle_async_request
    stream = await self._connect(request)
  File "httpcore/_async/connection.py", line 154, in _connect
    stream = await stream.start_tls(**kwargs)
  File "httpcore/_backends/anyio.py", line 80, in start_tls
    raise exc
  File "httpcore/_backends/anyio.py", line 71, in start_tls
    ssl_stream = await anyio.streams.tls.TLSStream.wrap(
  File "anyio/streams/tls.py", line 132, in wrap
    await wrapper._call_sslobject_method(ssl_object.do_handshake)
  File "anyio/streams/tls.py", line 140, in _call_sslobject_method
    result = func(*args)
  File "ssl.py", line 917, in do_handshake
    self._sslobj.do_handshake()

It happened during a request to another one of our servers. We perform this kind of request pretty often without any issues. This error happened only once.

I have the feeling that this error should be mapped to another higher-level exception.

Here is my environment:

@tomchristie suggested to include and map SSLError -> httpcore.ConnectError.

https://github.com/encode/httpcore/blob/c96fdf7d31c3ab983f4eec4ef7a25cd81edc7ac9/httpcore/_backends/anyio.py#L63-L67

tomchristie commented 3 months ago

Wonderful thanks @DouglasBlackwood - would you like to create a PR to resolve this?

DouglasBlackwood commented 3 months ago

Wonderful thanks @DouglasBlackwood - would you like to create a PR to resolve this?

Why not! I'm on it!