我正在尝试制作一个代理服务器来拦截和修改上传到 Amazon S3 的对象,但是当该对象应该由客户端发送时,PUT 请求挂起。以下是我使用 boto3 SDK 的单元测试:
import logging
import unittest
import boto3
from botocore import config
from botocore.exceptions import ClientError
import sys
sys.path.append('.')
s3_bucket_name = <removed>
region = "eu-west-2"
access_key = <removed>
secret_key = <removed>
class UploadTestCase(unittest.TestCase):
config = config.Config(
region_name=region,
proxies={'https': 'debian:3128'},
)
session = boto3.session.Session(
aws_access_key_id=access_key,
aws_secret_access_key=secret_key
)
s3 = session.resource('s3', config=config, verify='./myCA.pem')
def test_buckets(self):
buckets = [<removed>]
for bucket in self.s3.buckets.all():
self.assertIn(bucket.name, buckets)
def test_upload(self):
boto3.set_stream_logger('boto3.resources', logging.INFO)
data = "This is a text file.\nThis is a new line\nThis is another new line" * 100
bucket = self.s3.Bucket(s3_bucket_name)
obj = bucket.Object("testfile.txt")
try:
f = open('temp_upload_file', 'wb')
f.write(data.encode())
f.close()
obj.upload_file('temp_upload_file', s3_bucket_name, 'test_file.txt')
except ClientError as e:
self.fail("Client error: " + str(e))
finally:
f.close()
self.assertTrue(True)
if __name__ == '__main__':
unittest.main()
代理服务器运行 Squid 3.5,使用这个ICAP 实现。当我使用网络浏览器发出 PUT 请求时,一切正常。当我尝试使用 boto3 上传对象时会出现问题,这会导致 ICAP 服务器在等待接收数据时挂起。我已将挂起范围缩小到第 200 行,在 read_chunk()
line = self.rfile.readline()
在这一点上,对象数据本身永远不会被传输,我已经通过抓包确认了这一点。Boto3 然后无限期地重试。我不知道ICAP服务器是否尝试不正确地接收数据,或者boto3本身没有发送它。任何帮助表示赞赏。
编辑:似乎 boto3 不使用分块传输编码。较旧的 boto SDK 具有此选项,如本 API 参考中所示。有没有办法让 boto3 使用分块编码?