Skip to content

Commit 7fe16bf

Browse files
committed
Move 100-continue behavior to use high-level request interface
1 parent 4e8102b commit 7fe16bf

File tree

2 files changed

+26
-16
lines changed

2 files changed

+26
-16
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"type": "enhancement",
3+
"category": "HTTP",
4+
"description": "Move 100-continue behavior to use `HTTPConnections` request interface."
5+
}

awscli/botocore/awsrequest.py

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -66,34 +66,34 @@ class AWSConnection:
6666
def __init__(self, *args, **kwargs):
6767
super().__init__(*args, **kwargs)
6868
self._original_response_cls = self.response_class
69-
# We'd ideally hook into httplib's states, but they're all
70-
# __mangled_vars so we use our own state var. This variable is set
71-
# when we receive an early response from the server. If this value is
72-
# set to True, any calls to send() are noops. This value is reset to
73-
# false every time _send_request is called. This is to workaround the
74-
# fact that py2.6 (and only py2.6) has a separate send() call for the
75-
# body in _send_request, as opposed to endheaders(), which is where the
76-
# body is sent in all versions > 2.6.
69+
# This variable is set when we receive an early response from the
70+
# server. If this value is set to True, any calls to send() are noops.
71+
# This value is reset to false every time _send_request is called.
72+
# This is to workaround changes in urllib3 2.0 which uses separate
73+
# send() calls in request() instead of delegating to endheaders(),
74+
# which is where the body is sent in CPython's HTTPConnection.
7775
self._response_received = False
7876
self._expect_header_set = False
77+
self._send_called = False
7978

8079
def close(self):
8180
super().close()
8281
# Reset all of our instance state we were tracking.
8382
self._response_received = False
8483
self._expect_header_set = False
84+
self._send_called = False
8585
self.response_class = self._original_response_cls
8686

87-
def _send_request(self, method, url, body, headers, *args, **kwargs):
87+
def request(self, method, url, body=None, headers=None, *args, **kwargs):
88+
if headers is None:
89+
headers = {}
8890
self._response_received = False
8991
if headers.get('Expect', b'') == b'100-continue':
9092
self._expect_header_set = True
9193
else:
9294
self._expect_header_set = False
9395
self.response_class = self._original_response_cls
94-
rval = super()._send_request(
95-
method, url, body, headers, *args, **kwargs
96-
)
96+
rval = super().request(method, url, body, headers, *args, **kwargs)
9797
self._expect_header_set = False
9898
return rval
9999

@@ -210,10 +210,15 @@ def _send_message_body(self, message_body):
210210

211211
def send(self, str):
212212
if self._response_received:
213-
logger.debug(
214-
"send() called, but reseponse already received. "
215-
"Not sending data."
216-
)
213+
if not self._send_called:
214+
# urllib3 2.0 chunks and calls send potentially
215+
# thousands of times inside `request` unlike the
216+
# standard library. Only log this once for sanity.
217+
logger.debug(
218+
"send() called, but response already received. "
219+
"Not sending data."
220+
)
221+
self._send_called = True
217222
return
218223
return super().send(str)
219224

0 commit comments

Comments
 (0)