Skip to content

Botocore mistakenly expects a reason phrase in "100 Continue" responses #3455

@afranken

Description

@afranken

Describe the bug

When making HTTP requests, botocore sends a 100-continue request to the server, expecting a HTTP/1.1 100 Continue response.

Regression Issue

  • Select this option if this issue appears to be a regression.

Expected Behavior

The reason phrase is optional, so a HTTP/1.1 100 response from the server is the correct behaviour.
Botocore should accept a HTTP/1.1 100 response as correct.

Current Behavior

If Botocore receives a HTTP/1.1 100, it interprets the response as not correct, and does not continue with the original request.

Reproduction Steps

Start a service (locally) that sends HTTP/1.1 100 responses to 100-continue requests, e.g. S3Mock:

docker run -e initialBuckets=my-bucket --rm -it -p 9090:9090 adobe/s3mock:4.0.0

Execute a PutObject request with a random file, e.g. the README.rst from the root of this repository, e.g. through aws-cli which uses boto3/botocore internally:

aws s3api put-object \
    --bucket x \
    --key y.txt \
    --content-type text/plain \
    --endpoint http://localhost:9090 \
    --body README.rst \
    --debug

The request will fail, as the Tomcat server used in S3Mock sends a HTTP/1.1 100 as a response to the 100-continue request from botocore.

Example output:

2025-04-10 01:41:22,320 - MainThread - botocore.hooks - DEBUG - Event request-created.s3.PutObject: calling handler <bound method UserAgentString.rebuild_and_replace_user_agent_handler of <botocore.useragent.UserAgentString object at 0x1052779b0>>
2025-04-10 01:41:22,320 - MainThread - botocore.endpoint - DEBUG - Sending http request: <AWSPreparedRequest stream_output=False, method=PUT, url=http://localhost:9090/x/y.txt, headers={'Content-Type': b'text/plain', 'x-amz-sdk-checksum-algorithm': b'CRC32', 'User-Agent': b'aws-cli/2.25.13 md/awscrt#0.25.4 ua/2.1 os/macos#24.4.0 md/arch#arm64 lang/python#3.12.10 md/pyimpl#CPython m/N cfg/retry-mode#standard md/installer#source md/prompt#off md/command#s3api.put-object', 'Expect': b'100-continue', 'x-amz-checksum-crc32': b'NGSOug==', 'X-Amz-Date': b'20250409T234122Z', 'X-Amz-Content-SHA256': b'65dbc69741c062892a2842cc5d6099bbf02eefd4628d352d446c6c37cb0967da', 'Authorization': b'AWS4-HMAC-SHA256 Credential=NONE/20250409/us-east-1/s3/aws4_request, SignedHeaders=content-type;host;x-amz-checksum-crc32;x-amz-content-sha256;x-amz-date;x-amz-sdk-checksum-algorithm, Signature=e6a74e4aafab3b1c03e282cf2064d65dbb22af4396cb34460f69439d180f36d3', 'Content-Length': '42443'}>
2025-04-10 01:41:22,320 - MainThread - urllib3.connectionpool - DEBUG - Starting new HTTP connection (1): localhost:9090
2025-04-10 01:41:22,321 - MainThread - botocore.awsrequest - DEBUG - Waiting for 100 Continue response.
2025-04-10 01:41:22,324 - MainThread - botocore.hooks - DEBUG - Event needs-retry.s3.PutObject: calling handler <function _update_status_code at 0x101d1c2c0>
2025-04-10 01:41:22,324 - MainThread - botocore.hooks - DEBUG - Event needs-retry.s3.PutObject: calling handler <bound method RetryHandler.needs_retry of <botocore.retries.standard.RetryHandler object at 0x105277c80>>
2025-04-10 01:41:22,324 - MainThread - botocore.retries.standard - DEBUG - Retry needed, retrying request after delay of: 0.2322557477907542

Possible Solution

In botocore/awsrequest.py, check for only 2 parts in the response instead of 3 since the reason phrase is optional.
This will let a HTTP/1.1 100 response be detected correctly.

    def _is_100_continue_status(self, maybe_status_line):
        parts = maybe_status_line.split(None, 2)

        # Check for HTTP/<version> 100 (Continue)\r\n
        return (
            len(parts) >= 2
            and parts[0].startswith(b'HTTP/')
            and parts[1] == b'100'
        )

Additional Information/Context

S3Mock is a library/service to locally test applications that integrate with AWS S3.

aws-cli version:

❯ aws --version
aws-cli/2.22.16 Python/3.12.8 Darwin/24.4.0 source/arm64

Reason phrase is optional, see https://www.rfc-editor.org/rfc/rfc9110.html#section-15.1

SDK version used

1.37.36

Environment details (OS name and version, etc.)

macOS, 15.4.1, 24E263

Metadata

Metadata

Assignees

Labels

bugThis issue is a confirmed bug.feature-requestThis issue requests a feature.p3This is a minor priority issues3

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions