【发布时间】:2015-04-23 03:16:53
【问题描述】:
我有一个使用 boto 的 Python 应用程序,我在其中为用户提供一个临时 URL 以将文件上传到 S3 存储桶。
用户上传权限受限,我利用boot的Key.generate_url方法创建了一个临时URL,接受PUT请求。
我的工作正常,但我想确保在生成密钥和实际上传时间之间不会修改用户有效负载。
因此,我尝试使用 S3 的 Content-MD5 支持来确保校验和匹配。
但是,当我在代码中添加 Content-MD5 标头时,PUT 请求失败。
在下面的代码示例中,如果我删除了每个步骤(geturl 和 uploadfile)的 Content-MD5 标头,那么一切都会按预期进行。
请注意,我已验证我的校验和是正确的:如果我上传的文件没有 Content-MD5 标头,然后我会访问 S3 上的 MD5,它确实与我的本地哈希匹配。
这是我获得钥匙的方法:
# geturl
# s3key is a Key instance
# _file is a dict with some info on a file to be uploaded
s3headers = {
'Content-Length': _file['length'],
'Content-MD5': _file['md5']
}
s3url = s3key.generate_url(self.ACCESS_KEY_EXPIRES_IN, 'PUT',
headers=s3headers, force_http=True)
_parsed = compat.parse.urlparse(s3url)
_file['upload_url'] = '{0}://{1}{2}'.format(_parsed.scheme, _parsed.netloc, _parsed.path)
_file['upload_params'] = compat.parse.parse_qs(_parsed.query)
这是我上传文件的方式:
# uploadfile
headers = {'Content-Length': _file['length'],
'Content-MD5': _file['md5'],
'Content-Type': None,
'Connection': None,
'User-Agent': None,
'Accept-Encoding': None,
'Accept': None
}
stream = io.open(_file['local'])
response = requests.put(_file['upload_url'], data=stream, headers=headers, params=_file['upload_params'])
【问题讨论】:
-
您是否打开了请求中的调试以查看正在发送的实际 HTTP 请求,包括标头?这可能会很有趣。
-
是的,当然有。它发送的正是我所要求的:
Content-Length和Content-MD5- 我将其他标头设置为None的原因是为了删除 S3 不期望的标头。
标签: python amazon-s3 python-requests boto