awscli2/urllib3-v2.patch
Kseniia Nivnia 0889e2db6a
Update to 2.27.0
Resolves: RHEL-75536
Signed-off-by: Kseniia Nivnia <knivnia@redhat.com>
2025-07-24 15:30:41 +01:00

125 lines
5.1 KiB
Diff

diff --git a/awscli/botocore/awsrequest.py b/awscli/botocore/awsrequest.py
index 4ce0449..2b14009 100644
--- a/awscli/botocore/awsrequest.py
+++ b/awscli/botocore/awsrequest.py
@@ -14,6 +14,7 @@
import functools
import io
import logging
+from collections.abc import Mapping
import socket
import sys
@@ -24,6 +25,7 @@ from botocore.compat import (
HTTPResponse,
MutableMapping,
urlencode,
+ urlparse,
urlsplit,
urlunsplit,
)
@@ -66,32 +68,34 @@ class AWSConnection:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._original_response_cls = self.response_class
- # We'd ideally hook into httplib's states, but they're all
- # __mangled_vars so we use our own state var. This variable is set
- # when we receive an early response from the server. If this value is
- # set to True, any calls to send() are noops. This value is reset to
- # false every time _send_request is called. This is to workaround the
- # fact that py2.6 (and only py2.6) has a separate send() call for the
- # body in _send_request, as opposed to endheaders(), which is where the
- # body is sent in all versions > 2.6.
+ # This variable is set when we receive an early response from the
+ # server. If this value is set to True, any calls to send() are noops.
+ # This value is reset to false every time _send_request is called.
+ # This is to workaround changes in urllib3 2.0 which uses separate
+ # send() calls in request() instead of delegating to endheaders(),
+ # which is where the body is sent in CPython's HTTPConnection.
self._response_received = False
self._expect_header_set = False
+ self._send_called = False
def close(self):
super().close()
# Reset all of our instance state we were tracking.
self._response_received = False
self._expect_header_set = False
+ self._send_called = False
self.response_class = self._original_response_cls
- def _send_request(self, method, url, body, headers, *args, **kwargs):
+ def request(self, method, url, body=None, headers=None, *args, **kwargs):
+ if headers is None:
+ headers = {}
self._response_received = False
if headers.get('Expect', b'') == b'100-continue':
self._expect_header_set = True
else:
self._expect_header_set = False
self.response_class = self._original_response_cls
- rval = super()._send_request(
+ rval = super().request(
method, url, body, headers, *args, **kwargs
)
self._expect_header_set = False
@@ -210,10 +214,13 @@ class AWSConnection:
def send(self, str):
if self._response_received:
- logger.debug(
- "send() called, but reseponse already received. "
- "Not sending data."
- )
+ if not self._send_called:
+ # urllib3 2.0 chunks and calls send potentially
+ # thousands of times inside `request` unlike the
+ # standard library. Only log this once for sanity.
+ logger.debug("send() called, but reseponse already received. "
+ "Not sending data.")
+ self._send_called = True
return
return super().send(str)
@@ -370,8 +377,14 @@ class AWSRequestPreparer:
def _prepare_url(self, original):
url = original.url
if original.params:
- params = urlencode(list(original.params.items()), doseq=True)
- url = f'{url}?{params}'
+ url_parts = urlparse(url)
+ delim = '&' if url_parts.query else '?'
+ if isinstance(original.params, Mapping):
+ params_to_encode = list(original.params.items())
+ else:
+ params_to_encode = original.params
+ params = urlencode(params_to_encode, doseq=True)
+ url = delim.join((url, params))
return url
def _prepare_headers(self, original, prepared_body=None):
diff --git a/awscli/botocore/httpsession.py b/awscli/botocore/httpsession.py
index 516bb3f..25f982d 100644
--- a/awscli/botocore/httpsession.py
+++ b/awscli/botocore/httpsession.py
@@ -328,7 +328,6 @@ class URLLib3Session:
def _get_pool_manager_kwargs(self, **extra_kwargs):
pool_manager_kwargs = {
- 'strict': True,
'timeout': self._timeout,
'maxsize': self._max_pool_connections,
'ssl_context': self._get_ssl_context(),
diff --git a/tests/unit/botocore/test_http_session.py b/tests/unit/botocore/test_http_session.py
index 90ed7d4..0a10c15 100644
--- a/tests/unit/botocore/test_http_session.py
+++ b/tests/unit/botocore/test_http_session.py
@@ -148,7 +148,6 @@ class TestURLLib3Session(unittest.TestCase):
def _assert_manager_call(self, manager, *assert_args, **assert_kwargs):
call_kwargs = {
- 'strict': True,
'maxsize': mock.ANY,
'timeout': mock.ANY,
'ssl_context': mock.ANY,