如何在Boto3 put_object方法中绕过S3服务器100-continue响应要求
解决方案
1. 修正Config配置(核心修复)
你的问题在于expect_100_continue=False被错误地放在了s3子配置中,Botocore不会识别这个位置的参数。正确的做法是将其作为Config的顶层参数:
config = Config( signature_version='s3', retries={'max_attempts': 0}, expect_100_continue=False, # 移到顶层配置 s3={ 'use_accelerate_endpoint': False } )
这个参数会全局禁用Botocore的100-continue等待逻辑,不再自动添加Expect: 100-continue请求头。
2. 额外保险:通过事件钩子强制移除Expect头
如果上述配置仍未生效(例如某些版本的Botocore存在逻辑优先级问题),可以添加一个请求事件钩子,在请求发送前手动删除Expect头:
# 在初始化s3客户端后添加这段代码 def remove_expect_header(request, **kwargs): if 'Expect' in request.headers: del request.headers['Expect'] # 针对所有S3 PutObject请求生效 s3.meta.events.register('request-created.s3.PutObject', remove_expect_header) # 如果需要对所有S3请求生效,改用: # s3.meta.events.register('request-created.s3.*', remove_expect_header)
3. 修改后的完整代码
import boto3 import botocore import logging import warnings from boto3.compat import PythonDeprecationWarning from botocore.config import Config # Suppress deprecation warnings warnings.filterwarnings("ignore", category=PythonDeprecationWarning) # Configure logging logging.basicConfig(level=logging.DEBUG) # 修正配置:将expect_100_continue移到顶层 config = Config( signature_version='s3', retries={'max_attempts': 0}, expect_100_continue=False, s3={ 'use_accelerate_endpoint': False } ) # Initialize the S3 client with the custom endpoint and configuration s3 = boto3.client('s3', endpoint_url='http://<my-domain>:80', config=config) # 添加钩子移除Expect头(可选,作为保险) def remove_expect_header(request, **kwargs): if 'Expect' in request.headers: del request.headers['Expect'] s3.meta.events.register('request-created.s3.PutObject', remove_expect_header) # Upload the file try: with open('jeremy_test.txt', 'rb') as data: s3.put_object( Bucket='a-bucket', Key='jeremy_upload.txt', Body=data.read(), ContentType='text/plain' ) print("File uploaded successfully.") except Exception as e: print(f"An error occurred: {e}")
原理说明
- 当
expect_100_continue=False时,Botocore不会在请求头中添加Expect: 100-continue,也不会等待服务器的100响应,而是直接发送完整的请求头和请求体。 - 事件钩子作为兜底方案,确保即使配置未生效,也能手动移除可能被添加的
Expect头,避免客户端陷入等待超时。
测试后,你可以查看日志,如果请求头中不再出现Expect: 100-continue,且客户端直接发送请求体,问题即可解决。
内容的提问来源于stack exchange,提问作者Jeremy
相关产品推荐
相关产品推荐

