Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: header parsing in a 100 continue response. #3010

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion botocore/awsrequest.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def request(self, method, url, body=None, headers=None, *args, **kwargs):
self._expect_header_set = True
else:
self._expect_header_set = False
self.response_class = self._original_response_cls
self.response_class = self._original_response_cls
rval = super().request(method, url, body, headers, *args, **kwargs)
self._expect_header_set = False
return rval
Expand Down
40 changes: 40 additions & 0 deletions tests/unit/test_awsrequest.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,46 @@ def test_expect_100_continue_no_response_from_server(self):
response = conn.getresponse()
self.assertEqual(response.status, 307)

def test_expect_100_continue_followed_by_another_request(self):
with mock.patch('urllib3.util.wait_for_read') as wait_mock:
# Shows the server first sending a 200 ok response
# then a 200 ok response.
s = FakeSocket(
b'HTTP/1.1 200 OK\r\n'
b'Content-Length: 0\r\n'
b'\r\n'
b'HTTP/1.1 100 Continue\r\n'
b'\r\n'
b'HTTP/1.1 200 OK\r\n'
b'Content-Length: 0\r\n'
)
conn = AWSHTTPConnection('s3.amazonaws.com', 443)
conn.sock = s
wait_mock.return_value = True

# The first request expecting a 100 continue response.
# But the server will send a 200 ok instead.
conn.request(
'PUT', '/bucket/foo', b'body', {'Expect': b'100-continue'}
)
# Assert that we waited for the 100-continue response
self.assertEqual(wait_mock.call_count, 1)
response = conn.getresponse()
self.assertEqual(response.status, 200)
response.close()

# The client send the second request, expecting 100 continue either,
# using the same connection
conn.request(
'PUT', '/bucket/foo', b'body', {'Expect': b'100-continue'}
)
self.assertEqual(wait_mock.call_count, 2)
response = conn.getresponse()

# The second 'HTTP/1.1 200 OK\r\n' should be consumed by http.client.HTTPResponse._read_status().
# Only after this, the following header will be parsed correctly by email.parser.Parser.parsestr().
assert not getattr(response.headers, "defects", [])

def test_message_body_is_file_like_object(self):
# Shows the server first sending a 100 continue response
# then a 200 ok response.
Expand Down