Note: This is a public test instance of Red Hat Bugzilla. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback at bugzilla.redhat.com.
Bug 1855876 - python-requests: FTBFS in Fedora rawhide: pytest-httpbin server hit an exception serving request: [SSL: CA_MD_TOO_WEAK] ca md too weak (_ssl.c:4020)
Summary: python-requests: FTBFS in Fedora rawhide: pytest-httpbin server hit an except...
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: python-requests
Version: rawhide
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Miro Hrončok
QA Contact: Fedora Extras Quality Assurance
URL: https://koschei.fedoraproject.org/pac...
Whiteboard:
Depends On: 1676023
Blocks: F33FTBFS 1848104
TreeView+ depends on / blocked
 
Reported: 2020-07-10 19:25 UTC by Miro Hrončok
Modified: 2020-07-11 08:45 UTC (History)
4 users (show)

Fixed In Version: python-requests-2.23.0-5.fc33
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2020-07-11 08:45:40 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Miro Hrončok 2020-07-10 19:25:55 UTC
Description of problem:
Package python-requests fails to build from source in Fedora rawhide.

Version-Release number of selected component (if applicable):
2.23.0-4.fc33

Steps to Reproduce:
fedpkg build





=================================== FAILURES ===================================
_____________________ TestRequests.test_pyopenssl_redirect _____________________
...
self = <urllib3.connectionpool.HTTPSConnectionPool object at 0xf5e89c70>
method = 'GET', url = '/status/301', body = None
headers = {'User-Agent': 'python-requests/2.23.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
retries = Retry(total=0, connect=None, read=False, redirect=None, status=None)
redirect = False, assert_same_host = False
timeout = <urllib3.util.timeout.Timeout object at 0xf59a86b8>
pool_timeout = None, release_conn = False, chunked = False, body_pos = None
response_kw = {'decode_content': False, 'preload_content': False}, conn = None
release_this_conn = True, err = None, clean_exit = False
timeout_obj = <urllib3.util.timeout.Timeout object at 0xf59a8a18>
is_new_proxy_conn = False
    def urlopen(
        self,
        method,
        url,
        body=None,
        headers=None,
        retries=None,
        redirect=True,
        assert_same_host=True,
        timeout=_Default,
        pool_timeout=None,
        release_conn=None,
        chunked=False,
        body_pos=None,
        **response_kw
    ):
        """
        Get a connection from the pool and perform an HTTP request. This is the
        lowest level call for making a request, so you'll need to specify all
        the raw details.
    
        .. note::
    
           More commonly, it's appropriate to use a convenience method provided
           by :class:`.RequestMethods`, such as :meth:`request`.
    
        .. note::
    
           `release_conn` will only behave as expected if
           `preload_content=False` because we want to make
           `preload_content=False` the default behaviour someday soon without
           breaking backwards compatibility.
    
        :param method:
            HTTP request method (such as GET, POST, PUT, etc.)
    
        :param body:
            Data to send in the request body (useful for creating
            POST requests, see HTTPConnectionPool.post_url for
            more convenience).
    
        :param headers:
            Dictionary of custom headers to send, such as User-Agent,
            If-None-Match, etc. If None, pool headers are used. If provided,
            these headers completely replace any pool-specific headers.
    
        :param retries:
            Configure the number of retries to allow before raising a
            :class:`~urllib3.exceptions.MaxRetryError` exception.
    
            Pass ``None`` to retry until you receive a response. Pass a
            :class:`~urllib3.util.retry.Retry` object for fine-grained control
            over different types of retries.
            Pass an integer number to retry connection errors that many times,
            but no other types of errors. Pass zero to never retry.
    
            If ``False``, then retries are disabled and any exception is raised
            immediately. Also, instead of raising a MaxRetryError on redirects,
            the redirect response will be returned.
    
        :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int.
    
        :param redirect:
            If True, automatically handle redirects (status codes 301, 302,
            303, 307, 308). Each redirect counts as a retry. Disabling retries
            will disable redirect, too.
    
        :param assert_same_host:
            If ``True``, will make sure that the host of the pool requests is
            consistent else will raise HostChangedError. When False, you can
            use the pool on an HTTP proxy and request foreign hosts.
    
        :param timeout:
            If specified, overrides the default timeout for this one
            request. It may be a float (in seconds) or an instance of
            :class:`urllib3.util.Timeout`.
    
        :param pool_timeout:
            If set and the pool is set to block=True, then this method will
            block for ``pool_timeout`` seconds and raise EmptyPoolError if no
            connection is available within the time period.
    
        :param release_conn:
            If False, then the urlopen call will not release the connection
            back into the pool once a response is received (but will release if
            you read the entire contents of the response such as when
            `preload_content=True`). This is useful if you're not preloading
            the response's content immediately. You will need to call
            ``r.release_conn()`` on the response ``r`` to return the connection
            back into the pool. If None, it takes the value of
            ``response_kw.get('preload_content', True)``.
    
        :param chunked:
            If True, urllib3 will send the body using chunked transfer
            encoding. Otherwise, urllib3 will send the body using the standard
            content-length form. Defaults to False.
    
        :param int body_pos:
            Position to seek to in file-like body in the event of a retry or
            redirect. Typically this won't need to be set because urllib3 will
            auto-populate the value when needed.
    
        :param \\**response_kw:
            Additional parameters are passed to
            :meth:`urllib3.response.HTTPResponse.from_httplib`
        """
        if headers is None:
            headers = self.headers
    
        if not isinstance(retries, Retry):
            retries = Retry.from_int(retries, redirect=redirect, default=self.retries)
    
        if release_conn is None:
            release_conn = response_kw.get("preload_content", True)
    
        # Check host
        if assert_same_host and not self.is_same_host(url):
            raise HostChangedError(self, url, retries)
    
        # Ensure that the URL we're connecting to is properly encoded
        if url.startswith("/"):
            url = six.ensure_str(_encode_target(url))
        else:
            url = six.ensure_str(parse_url(url).url)
    
        conn = None
    
        # Track whether `conn` needs to be released before
        # returning/raising/recursing. Update this variable if necessary, and
        # leave `release_conn` constant throughout the function. That way, if
        # the function recurses, the original value of `release_conn` will be
        # passed down into the recursive call, and its value will be respected.
        #
        # See issue #651 [1] for details.
        #
        # [1] <https://github.com/urllib3/urllib3/issues/651>
        release_this_conn = release_conn
    
        # Merge the proxy headers. Only do this in HTTP. We have to copy the
        # headers dict so we can safely change it without those changes being
        # reflected in anyone else's copy.
        if self.scheme == "http":
            headers = headers.copy()
            headers.update(self.proxy_headers)
    
        # Must keep the exception bound to a separate variable or else Python 3
        # complains about UnboundLocalError.
        err = None
    
        # Keep track of whether we cleanly exited the except block. This
        # ensures we do proper cleanup in finally.
        clean_exit = False
    
        # Rewind body position, if needed. Record current position
        # for future rewinds in the event of a redirect/retry.
        body_pos = set_file_position(body, body_pos)
    
        try:
            # Request a connection from the queue.
            timeout_obj = self._get_timeout(timeout)
            conn = self._get_conn(timeout=pool_timeout)
    
            conn.timeout = timeout_obj.connect_timeout
    
            is_new_proxy_conn = self.proxy is not None and not getattr(
                conn, "sock", None
            )
            if is_new_proxy_conn:
                self._prepare_proxy(conn)
    
            # Make the request on the httplib connection object.
>           httplib_response = self._make_request(
                conn,
                method,
                url,
                timeout=timeout_obj,
                body=body,
                headers=headers,
                chunked=chunked,
            )
/usr/lib/python3.9/site-packages/urllib3/connectionpool.py:665: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <urllib3.connectionpool.HTTPSConnectionPool object at 0xf5e89c70>
conn = <urllib3.connection.VerifiedHTTPSConnection object at 0xf59a8aa8>
method = 'GET', url = '/status/301'
timeout = <urllib3.util.timeout.Timeout object at 0xf59a8a18>, chunked = False
httplib_request_kw = {'body': None, 'headers': {'User-Agent': 'python-requests/2.23.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}}
timeout_obj = <urllib3.util.timeout.Timeout object at 0xf59a8118>
    def _make_request(
        self, conn, method, url, timeout=_Default, chunked=False, **httplib_request_kw
    ):
        """
        Perform a request on a given urllib connection object taken from our
        pool.
    
        :param conn:
            a connection from one of our connection pools
    
        :param timeout:
            Socket timeout in seconds for the request. This can be a
            float or integer, which will set the same timeout value for
            the socket connect and the socket read, or an instance of
            :class:`urllib3.util.Timeout`, which gives you more fine-grained
            control over your timeouts.
        """
        self.num_requests += 1
    
        timeout_obj = self._get_timeout(timeout)
        timeout_obj.start_connect()
        conn.timeout = timeout_obj.connect_timeout
    
        # Trigger any extra validation we need to do.
        try:
>           self._validate_conn(conn)
/usr/lib/python3.9/site-packages/urllib3/connectionpool.py:376: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <urllib3.connectionpool.HTTPSConnectionPool object at 0xf5e89c70>
conn = <urllib3.connection.VerifiedHTTPSConnection object at 0xf59a8aa8>
    def _validate_conn(self, conn):
        """
        Called right before a request is made, after the socket is created.
        """
        super(HTTPSConnectionPool, self)._validate_conn(conn)
    
        # Force connect early to allow us to validate the connection.
        if not getattr(conn, "sock", None):  # AppEngine might not have  `.sock`
>           conn.connect()
/usr/lib/python3.9/site-packages/urllib3/connectionpool.py:994: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <urllib3.connection.VerifiedHTTPSConnection object at 0xf59a8aa8>
    def connect(self):
        # Add certificate verification
        conn = self._new_conn()
        hostname = self.host
    
        # Google App Engine's httplib does not define _tunnel_host
        if getattr(self, "_tunnel_host", None):
            self.sock = conn
            # Calls self._set_hostport(), so self.host is
            # self._tunnel_host below.
            self._tunnel()
            # Mark this connection as not reusable
            self.auto_open = 0
    
            # Override the host with the one we're requesting data from.
            hostname = self._tunnel_host
    
        server_hostname = hostname
        if self.server_hostname is not None:
            server_hostname = self.server_hostname
    
        is_time_off = datetime.date.today() < RECENT_DATE
        if is_time_off:
            warnings.warn(
                (
                    "System time is way off (before {0}). This will probably "
                    "lead to SSL verification errors"
                ).format(RECENT_DATE),
                SystemTimeWarning,
            )
    
        # Wrap socket using verification with the root certs in
        # trusted_root_certs
        default_ssl_context = False
        if self.ssl_context is None:
            default_ssl_context = True
            self.ssl_context = create_urllib3_context(
                ssl_version=resolve_ssl_version(self.ssl_version),
                cert_reqs=resolve_cert_reqs(self.cert_reqs),
            )
    
        context = self.ssl_context
        context.verify_mode = resolve_cert_reqs(self.cert_reqs)
    
        # Try to load OS default certs if none are given.
        # Works well on Windows (requires Python3.4+)
        if (
            not self.ca_certs
            and not self.ca_cert_dir
            and default_ssl_context
            and hasattr(context, "load_default_certs")
        ):
            context.load_default_certs()
    
>       self.sock = ssl_wrap_socket(
            sock=conn,
            keyfile=self.key_file,
            certfile=self.cert_file,
            key_password=self.key_password,
            ca_certs=self.ca_certs,
            ca_cert_dir=self.ca_cert_dir,
            server_hostname=server_hostname,
            ssl_context=context,
        )
/usr/lib/python3.9/site-packages/urllib3/connection.py:352: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
sock = <socket.socket [closed] fd=-1, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6>
keyfile = None, certfile = None, cert_reqs = None
ca_certs = '/usr/lib/python3.9/site-packages/pytest_httpbin/certs/cacert.pem'
server_hostname = '127.0.0.1', ssl_version = None, ciphers = None
ssl_context = <ssl.SSLContext object at 0xf5dfb658>, ca_cert_dir = None
key_password = None
    def ssl_wrap_socket(
        sock,
        keyfile=None,
        certfile=None,
        cert_reqs=None,
        ca_certs=None,
        server_hostname=None,
        ssl_version=None,
        ciphers=None,
        ssl_context=None,
        ca_cert_dir=None,
        key_password=None,
    ):
        """
        All arguments except for server_hostname, ssl_context, and ca_cert_dir have
        the same meaning as they do when using :func:`ssl.wrap_socket`.
    
        :param server_hostname:
            When SNI is supported, the expected hostname of the certificate
        :param ssl_context:
            A pre-made :class:`SSLContext` object. If none is provided, one will
            be created using :func:`create_urllib3_context`.
        :param ciphers:
            A string of ciphers we wish the client to support.
        :param ca_cert_dir:
            A directory containing CA certificates in multiple separate files, as
            supported by OpenSSL's -CApath flag or the capath argument to
            SSLContext.load_verify_locations().
        :param key_password:
            Optional password if the keyfile is encrypted.
        """
        context = ssl_context
        if context is None:
            # Note: This branch of code and all the variables in it are no longer
            # used by urllib3 itself. We should consider deprecating and removing
            # this code.
            context = create_urllib3_context(ssl_version, cert_reqs, ciphers=ciphers)
    
        if ca_certs or ca_cert_dir:
            try:
                context.load_verify_locations(ca_certs, ca_cert_dir)
            except IOError as e:  # Platform-specific: Python 2.7
                raise SSLError(e)
            # Py33 raises FileNotFoundError which subclasses OSError
            # These are not equivalent unless we check the errno attribute
            except OSError as e:  # Platform-specific: Python 3.3 and beyond
                if e.errno == errno.ENOENT:
                    raise SSLError(e)
                raise
    
        elif ssl_context is None and hasattr(context, "load_default_certs"):
            # try to load OS default certs; works well on Windows (require Python3.4+)
            context.load_default_certs()
    
        # Attempt to detect if we get the goofy behavior of the
        # keyfile being encrypted and OpenSSL asking for the
        # passphrase via the terminal and instead error out.
        if keyfile and key_password is None and _is_key_file_encrypted(keyfile):
            raise SSLError("Client private key is encrypted, password is required")
    
        if certfile:
            if key_password is None:
                context.load_cert_chain(certfile, keyfile)
            else:
                context.load_cert_chain(certfile, keyfile, key_password)
    
        # If we detect server_hostname is an IP address then the SNI
        # extension should not be used according to RFC3546 Section 3.1
        # We shouldn't warn the user if SNI isn't available but we would
        # not be using SNI anyways due to IP address for server_hostname.
        if (
            server_hostname is not None and not is_ipaddress(server_hostname)
        ) or IS_SECURETRANSPORT:
            if HAS_SNI and server_hostname is not None:
                return context.wrap_socket(sock, server_hostname=server_hostname)
    
            warnings.warn(
                "An HTTPS request has been made, but the SNI (Server Name "
                "Indication) extension to TLS is not available on this platform. "
                "This may cause the server to present an incorrect TLS "
                "certificate, which can cause validation failures. You can upgrade to "
                "a newer version of Python to solve this. For more information, see "
                "https://urllib3.readthedocs.io/en/latest/advanced-usage.html"
                "#ssl-warnings",
                SNIMissingWarning,
            )
    
>       return context.wrap_socket(sock)
/usr/lib/python3.9/site-packages/urllib3/util/ssl_.py:383: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <ssl.SSLContext object at 0xf5dfb658>
sock = <socket.socket [closed] fd=-1, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6>
server_side = False, do_handshake_on_connect = True, suppress_ragged_eofs = True
server_hostname = None, session = None
    def wrap_socket(self, sock, server_side=False,
                    do_handshake_on_connect=True,
                    suppress_ragged_eofs=True,
                    server_hostname=None, session=None):
        # SSLSocket class handles server_hostname encoding before it calls
        # ctx._wrap_socket()
>       return self.sslsocket_class._create(
            sock=sock,
            server_side=server_side,
            do_handshake_on_connect=do_handshake_on_connect,
            suppress_ragged_eofs=suppress_ragged_eofs,
            server_hostname=server_hostname,
            context=self,
            session=session
        )
/usr/lib/python3.9/ssl.py:500: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cls = <class 'ssl.SSLSocket'>
sock = <socket.socket [closed] fd=-1, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6>
server_side = False, do_handshake_on_connect = True, suppress_ragged_eofs = True
server_hostname = None, context = <ssl.SSLContext object at 0xf5dfb658>
session = None
    @classmethod
    def _create(cls, sock, server_side=False, do_handshake_on_connect=True,
                suppress_ragged_eofs=True, server_hostname=None,
                context=None, session=None):
        if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM:
            raise NotImplementedError("only stream sockets are supported")
        if server_side:
            if server_hostname:
                raise ValueError("server_hostname can only be specified "
                                 "in client mode")
            if session is not None:
                raise ValueError("session can only be specified in "
                                 "client mode")
        if context.check_hostname and not server_hostname:
            raise ValueError("check_hostname requires server_hostname")
    
        kwargs = dict(
            family=sock.family, type=sock.type, proto=sock.proto,
            fileno=sock.fileno()
        )
        self = cls.__new__(cls, **kwargs)
        super(SSLSocket, self).__init__(**kwargs)
        self.settimeout(sock.gettimeout())
        sock.detach()
    
        self._context = context
        self._session = session
        self._closed = False
        self._sslobj = None
        self.server_side = server_side
        self.server_hostname = context._encode_hostname(server_hostname)
        self.do_handshake_on_connect = do_handshake_on_connect
        self.suppress_ragged_eofs = suppress_ragged_eofs
    
        # See if we are connected
        try:
            self.getpeername()
        except OSError as e:
            if e.errno != errno.ENOTCONN:
                raise
            connected = False
        else:
            connected = True
    
        self._connected = connected
        if connected:
            # create the SSL object
            try:
                self._sslobj = self._context._wrap_socket(
                    self, server_side, self.server_hostname,
                    owner=self, session=self._session,
                )
                if do_handshake_on_connect:
                    timeout = self.gettimeout()
                    if timeout == 0.0:
                        # non-blocking
                        raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
>                   self.do_handshake()
/usr/lib/python3.9/ssl.py:1040: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <ssl.SSLSocket [closed] fd=-1, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6>
block = False
    @_sslcopydoc
    def do_handshake(self, block=False):
        self._check_connected()
        timeout = self.gettimeout()
        try:
            if timeout == 0.0 and block:
                self.settimeout(None)
>           self._sslobj.do_handshake()
E           urllib3.exceptions.ProtocolError: ('Connection aborted.', OSError(0, 'Error'))
/usr/lib/python3.9/ssl.py:1309: ProtocolError
During handling of the above exception, another exception occurred:
self = <tests.test_requests.TestRequests object at 0xf5e4b7a8>
httpbin_secure = <function prepare_url.<locals>.inner at 0xf5dfb4f0>
httpbin_ca_bundle = None
    def test_pyopenssl_redirect(self, httpbin_secure, httpbin_ca_bundle):
>       requests.get(httpbin_secure('status', '301'), verify=httpbin_ca_bundle)
tests/test_requests.py:814: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
requests/api.py:76: in get
    return request('get', url, params=params, **kwargs)
requests/api.py:61: in request
    return session.request(method=method, url=url, **kwargs)
requests/sessions.py:530: in request
    resp = self.send(prep, **send_kwargs)
requests/sessions.py:643: in send
    r = adapter.send(request, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <requests.adapters.HTTPAdapter object at 0xf5e4b4c0>
request = <PreparedRequest [GET]>, stream = False
timeout = <urllib3.util.timeout.Timeout object at 0xf59a86b8>
verify = '/usr/lib/python3.9/site-packages/pytest_httpbin/certs/cacert.pem'
cert = None, proxies = OrderedDict()
    def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None):
        """Sends PreparedRequest object. Returns Response object.
    
        :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
        :param stream: (optional) Whether to stream the request content.
        :param timeout: (optional) How long to wait for the server to send
            data before giving up, as a float, or a :ref:`(connect timeout,
            read timeout) <timeouts>` tuple.
        :type timeout: float or tuple or urllib3 Timeout object
        :param verify: (optional) Either a boolean, in which case it controls whether
            we verify the server's TLS certificate, or a string, in which case it
            must be a path to a CA bundle to use
        :param cert: (optional) Any user-provided SSL certificate to be trusted.
        :param proxies: (optional) The proxies dictionary to apply to the request.
        :rtype: requests.Response
        """
    
        try:
            conn = self.get_connection(request.url, proxies)
        except LocationValueError as e:
            raise InvalidURL(e, request=request)
    
        self.cert_verify(conn, request.url, verify, cert)
        url = self.request_url(request, proxies)
        self.add_headers(request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies)
    
        chunked = not (request.body is None or 'Content-Length' in request.headers)
    
        if isinstance(timeout, tuple):
            try:
                connect, read = timeout
                timeout = TimeoutSauce(connect=connect, read=read)
            except ValueError as e:
                # this may raise a string formatting error.
                err = ("Invalid timeout {}. Pass a (connect, read) "
                       "timeout tuple, or a single float to set "
                       "both timeouts to the same value".format(timeout))
                raise ValueError(err)
        elif isinstance(timeout, TimeoutSauce):
            pass
        else:
            timeout = TimeoutSauce(connect=timeout, read=timeout)
    
        try:
            if not chunked:
                resp = conn.urlopen(
                    method=request.method,
                    url=url,
                    body=request.body,
                    headers=request.headers,
                    redirect=False,
                    assert_same_host=False,
                    preload_content=False,
                    decode_content=False,
                    retries=self.max_retries,
                    timeout=timeout
                )
    
            # Send the request.
            else:
                if hasattr(conn, 'proxy_pool'):
                    conn = conn.proxy_pool
    
                low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT)
    
                try:
                    low_conn.putrequest(request.method,
                                        url,
                                        skip_accept_encoding=True)
    
                    for header, value in request.headers.items():
                        low_conn.putheader(header, value)
    
                    low_conn.endheaders()
    
                    for i in request.body:
                        low_conn.send(hex(len(i))[2:].encode('utf-8'))
                        low_conn.send(b'\r\n')
                        low_conn.send(i)
                        low_conn.send(b'\r\n')
                    low_conn.send(b'0\r\n\r\n')
    
                    # Receive the response from the server
                    try:
                        # For Python 2.7, use buffering of HTTP responses
                        r = low_conn.getresponse(buffering=True)
                    except TypeError:
                        # For compatibility with Python 3.3+
                        r = low_conn.getresponse()
    
                    resp = HTTPResponse.from_httplib(
                        r,
                        pool=conn,
                        connection=low_conn,
                        preload_content=False,
                        decode_content=False
                    )
                except:
                    # If we hit any problems here, clean up the connection.
                    # Then, reraise so that we can handle the actual exception.
                    low_conn.close()
                    raise
    
        except (ProtocolError, socket.error) as err:
>           raise ConnectionError(err, request=request)
E           requests.exceptions.ConnectionError: ('Connection aborted.', OSError(0, 'Error'))
requests/adapters.py:498: ConnectionError
----------------------------- Captured stdout call -----------------------------
pytest-httpbin server hit an exception serving request: [SSL: CA_MD_TOO_WEAK] ca md too weak (_ssl.c:4020)
attempting to ignore so the rest of the tests can run
...
========= 4 failed, 523 passed, 12 skipped, 1 xfailed in 65.31 seconds =========

Comment 2 Fedora Admin user for bugzilla script actions 2020-07-11 02:48:18 UTC
This package has changed maintainer in the Fedora.
Reassigning to the new maintainer of this component.


Note You need to log in before you can comment on or make changes to this bug.