S3 对象返回八位字节流,但上传为 png
Posted
技术标签:
【中文标题】S3 对象返回八位字节流,但上传为 png【英文标题】:S3 object returns octet-stream but was uploaded as png 【发布时间】:2020-10-01 15:46:00 【问题描述】:我有这段现有的代码,用于将文件上传到我的 s3 存储桶。
def get_user_upload_url(customer_id, filename, content_type):
s3_client = boto3.client('s3')
object_name = "userfiles/uploads//".format(customer_id, filename)
try:
url = s3_client.generate_presigned_url('put_object',
Params='Bucket': BUCKET,
'Key': object_name,
"ContentType": content_type # set to "image/png"
,
ExpiresIn=100)
except Exception as e:
print(e)
return None
return url
这会向我的客户返回一个预签名的 URL,我可以使用该 URL 毫无问题地上传我的文件。我在上传 png 的地方添加了它的新用途,并且我已经进行了上传到预签名 url 的行为测试。问题是如果我去查看 s3 中的文件,我无法预览它。如果我下载它,它也不会打开。 s3 Web 客户端显示它具有 Content-Type image/png。我视觉比较了原始文件和下载文件的二进制文件,我可以看到差异。文件类型工具检测到它是八位字节流。
signature_file_name = "signature.png"
with open("features/steps/".format(signature_file_name), 'rb') as f:
files = 'file': (signature_file_name, f)
headers =
'Content-Type': "image/png" # without this or with a different value the presigned url will error with a signatureDoesNotMatch
context.upload_signature_response = requests.put(response, files=files, headers=headers)
我本来希望返回的是 PNG 而不是八位字节流,但是我不确定我做错了什么。谷歌搜索这通常会导致人们对签名有问题,因为没有正确设置或传递内容类型,我觉得我已经有效地做到了这一点,事实证明,如果我更改内容类型,一切都会失败。我猜我上传文件的方式有问题,或者可能是读取文件以进行上传?
【问题讨论】:
【参考方案1】:所以这与我如何上传有关。因此,如果我这样上传,它会起作用。
context.upload_signature_response = requests.put(response, data=open("features/steps/".format(signature_file_name), 'rb'), headers=headers)
所以这一定与put_object的使用有关。它必须期望正文是已定义内容类型的文件。此方法完成了前一个方法将其设为多部分上传的位置。所以我认为可以肯定地说分段上传与 put_object 的预签名 URL 不兼容。
我还在拼凑,所以请随意填补空白。
【讨论】:
以上是关于S3 对象返回八位字节流,但上传为 png的主要内容,如果未能解决你的问题,请参考以下文章