elastic / elastic-transport-python

Transport classes and utilities shared among Python Elastic client libraries
https://elastic-transport-python.readthedocs.io
Apache License 2.0
20 stars 13 forks source link

8.13.1: requests tests related to TLS versions fails #173

Closed mtelka closed 3 months ago

mtelka commented 3 months ago

I'm testing version 8.13.1 and I noticed that the following tests fails:

=========================== short test summary info ============================
FAILED tests/node/test_tls_versions.py::test_supported_tls_versions[https://tls-v1-0.badssl.com:1010-_SSLMethod.PROTOCOL_TLSv1-RequestsHttpNode] - elastic_transport.TlsError: TLS error caused by: SSLError(HTTPSConnectionPool(host='tls-v1-0.badssl.com', port=1010): Max retries exceeded with url: / (Caused by SSLError(SSLError(1, '[SSL: UNSUPPORTED_PROTOCOL] unsupported protocol (_ssl.c:1133)'))))
FAILED tests/node/test_tls_versions.py::test_supported_tls_versions[https://tls-v1-1.badssl.com:1011-_SSLMethod.PROTOCOL_TLSv1_1-RequestsHttpNode] - elastic_transport.TlsError: TLS error caused by: SSLError(HTTPSConnectionPool(host='tls-v1-1.badssl.com', port=1011): Max retries exceeded with url: / (Caused by SSLError(SSLError(1, '[SSL: UNSUPPORTED_PROTOCOL] unsupported protocol (_ssl.c:1133)'))))
FAILED tests/node/test_tls_versions.py::test_supported_tls_versions[https://tls-v1-0.badssl.com:1010-TLSVersion.TLSv1-RequestsHttpNode] - elastic_transport.TlsError: TLS error caused by: SSLError(HTTPSConnectionPool(host='tls-v1-0.badssl.com', port=1010): Max retries exceeded with url: / (Caused by SSLError(SSLError(1, '[SSL: UNSUPPORTED_PROTOCOL] unsupported protocol (_ssl.c:1133)'))))
FAILED tests/node/test_tls_versions.py::test_supported_tls_versions[https://tls-v1-1.badssl.com:1011-TLSVersion.TLSv1_1-RequestsHttpNode] - elastic_transport.TlsError: TLS error caused by: SSLError(HTTPSConnectionPool(host='tls-v1-1.badssl.com', port=1011): Max retries exceeded with url: / (Caused by SSLError(SSLError(1, '[SSL: UNSUPPORTED_PROTOCOL] unsupported protocol (_ssl.c:1133)'))))
FAILED tests/node/test_tls_versions.py::test_unsupported_tls_versions[https://tls-v1-2.badssl.com:1012-TLSVersion.TLSv1_3-RequestsHttpNode] - Failed: DID NOT RAISE <class 'elastic_transport.TlsError'>
== 5 failed, 405 passed, 10 skipped, 2 xfailed, 1 warning in 62.23s (0:01:02) ==

Here is detailed traceback for one test failure:

_ test_supported_tls_versions[https://tls-v1-0.badssl.com:1010-_SSLMethod.PROTOCOL_TLSv1-RequestsHttpNode] _

node_class = <class 'elastic_transport.RequestsHttpNode'>
url = 'https://tls-v1-0.badssl.com:1010'
ssl_version = <_SSLMethod.PROTOCOL_TLSv1: 3>

    @node_classes
    @pytest.mark.parametrize(
        ["url", "ssl_version"],
        supported_version_params,
    )
    @pytest.mark.asyncio
    async def test_supported_tls_versions(node_class, url: str, ssl_version: int):
        if url in (TLSv1_0_URL, TLSv1_1_URL) and not tlsv1_1_supported():
            pytest.skip("TLSv1.1 isn't supported by this OpenSSL distribution")
        node_config = url_to_node_config(url).replace(ssl_version=ssl_version)
        node = node_class(node_config)

>       resp, _ = await await_if_coro(node.perform_request("GET", "/"))

tests/node/test_tls_versions.py:108:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <RequestsHttpNode(https://tls-v1-0.badssl.com:1010)>, method = 'GET'
target = '/', body = None, headers = {}, request_timeout = <DEFAULT>

    def perform_request(
        self,
        method: str,
        target: str,
        body: Optional[bytes] = None,
        headers: Optional[HttpHeaders] = None,
        request_timeout: Union[DefaultType, Optional[float]] = DEFAULT,
    ) -> NodeApiResponse:
        url = self.base_url + target
        headers = HttpHeaders(headers or ())

        request_headers = self._headers.copy()
        if headers:
            request_headers.update(headers)

        body_to_send: Optional[bytes]
        if body:
            if self._http_compress:
                body_to_send = gzip.compress(body)
                request_headers["content-encoding"] = "gzip"
            else:
                body_to_send = body
        else:
            body_to_send = None

        start = time.time()
        request = requests.Request(
            method=method, headers=request_headers, url=url, data=body_to_send
        )
        prepared_request = self.session.prepare_request(request)
        send_kwargs = {
            "timeout": (
                request_timeout
                if request_timeout is not DEFAULT
                else self.config.request_timeout
            )
        }
        send_kwargs.update(
            self.session.merge_environment_settings(  # type: ignore[arg-type]
                prepared_request.url, {}, None, None, None
            )
        )
        try:
            response = self.session.send(prepared_request, **send_kwargs)  # type: ignore[arg-type]
            data = response.content
            duration = time.time() - start
            response_headers = HttpHeaders(response.headers)

        except RERAISE_EXCEPTIONS:
            raise
        except Exception as e:
            err: Exception
            if isinstance(e, requests.Timeout):
                err = ConnectionTimeout(
                    "Connection timed out during request", errors=(e,)
                )
            elif isinstance(e, (ssl.SSLError, requests.exceptions.SSLError)):
                err = TlsError(str(e), errors=(e,))
            elif isinstance(e, BUILTIN_EXCEPTIONS):
                raise
            else:
                err = ConnectionError(str(e), errors=(e,))
            self._log_request(
                method=method,
                target=target,
                headers=request_headers,
                body=body,
                exception=err,
            )
>           raise err from None
E           elastic_transport.TlsError: TLS error caused by: SSLError(HTTPSConnectionPool(host='tls-v1-0.badssl.com', port=1010): Max retries exceeded with url: / (Caused by SSLError(SSLError(1, '[SSL: UNSUPPORTED_PROTOCOL] unsupported protocol (_ssl.c:1133)'))))

elastic_transport/_node/_http_requests.py:255: TlsError
pquentin commented 3 months ago

This is a Requests issue that will be fixed when https://github.com/psf/requests/pull/6716 gets released in 2.32.3. Tests should work today with 2.31 or lower.

pquentin commented 3 months ago

Requests 2.32.3 is out, and the test suite should pass again. Closing, thanks!

By the way, you should consider using an OpenSSL version that disables TLS 1.0 and 1.1.