我有一個Python應用程序,使用博託,在那裏我給用戶一個臨時URL上傳文件到S3存儲桶。如何在使用boto的Key.generate_url方法將文件放在S3上時正確傳遞Content-MD5頭文件?
用戶的上傳訪問受限,我利用引導的Key.generate_url
方法創建了一個接受PUT
請求的臨時URL。
我有這個工作正常,但我想確保用戶有效載荷不會在我生成密鑰的時間和實際上傳時間之間進行修改。
因此,我試圖使用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請求中發送,包括頭文件?這可能很有趣。 – garnaat
是的,當然有。它的發送正是我所要求的:'Content-Length'和'Content-MD5' - 我將其他頭部設置爲'None'的原因是刪除S3不期望的頭文件。 – pwalsh