From 30c6146c6c864e40d292e7201185624795986dc2 Mon Sep 17 00:00:00 2001 From: Samuel Remis Date: Wed, 14 Feb 2024 14:46:12 -0500 Subject: [PATCH] Add experimental flag for checking the request body before setting 100 continue --- botocore/handlers.py | 8 ++++++++ tests/functional/test_s3.py | 26 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/botocore/handlers.py b/botocore/handlers.py index aa0ae98c0e..155442424b 100644 --- a/botocore/handlers.py +++ b/botocore/handlers.py @@ -346,6 +346,14 @@ def add_expect_header(model, params, **kwargs): if 'body' in params: body = params['body'] if hasattr(body, 'read'): + check_body = utils.ensure_boolean( + os.environ.get( + 'BOTO_EXPERIMENTAL__CHECK_BODY_BEFORE_CONTINUE', + '', + ) + ) + if check_body and utils.determine_content_length(body) == 0: + return # Any file like object will use an expect 100-continue # header regardless of size. logger.debug("Adding expect 100 continue header to request.") diff --git a/tests/functional/test_s3.py b/tests/functional/test_s3.py index f51f41d264..dab3775cef 100644 --- a/tests/functional/test_s3.py +++ b/tests/functional/test_s3.py @@ -3619,3 +3619,29 @@ def test_escape_keys_in_xml_put_bucket_lifecycle_configuration(self): self.assertNotIn(b"my\r\n\rprefix", request.body) self.assertIn(b"my prefix", request.body) self.assert_correct_content_md5(request) + + +class TestExpectContinueBehavior(BaseSessionTest): + def test_sets_100_continute_with_body(self): + op_kwargs = { + "Bucket": "mybucket", + "Key": "mykey", + "Body": b"foo", + } + s3 = _create_s3_client() + with ClientHTTPStubber(s3) as http_stubber: + http_stubber.add_response() + s3.put_object(**op_kwargs) + expect_header = http_stubber.requests[-1].headers.get("Expect") + self.assertIsNotNone(expect_header) + self.assertEqual(expect_header, b"100-continue") + + def test_does_not_set_100_continute_with_empty_body(self): + self.environ["BOTO_EXPERIMENTAL__CHECK_BODY_BEFORE_CONTINUE"] = "True" + op_kwargs = {"Bucket": "mybucket", "Key": "mykey", "Body": ""} + s3 = _create_s3_client() + with ClientHTTPStubber(s3) as http_stubber: + http_stubber.add_response() + s3.put_object(**op_kwargs) + expect_header = http_stubber.requests[-1].headers.get("Expect") + self.assertIsNone(expect_header)