[英]Posting object to Google Cloud Storage doesn't replace ${filename} variable
如此处所述https://cloud.google.com/storage/docs/xml-api/post-object
从浏览器上传文件到 GCS 时(使用签名请求),我可以使用${filename}
作为密钥的一部分。
这很好,因为它与 S3 使用的变量完全相同。 但是 - 一个问题。 当我上传时,它实际上并没有用文件名替换${filename}
。 这在 S3 上完美运行,但使用 GCS,我确实得到$%7Bfilename%7D
作为响应中的键 - 显然它没有用正确的值替换它。
我正在构建这样的请求:
export function uploadVideo(video) {
return new Promise((resolve, reject) => {
if (!video) {
resolve(null);
return;
}
// this fetches a presigned post object from the server:
request.get('/presigned_post')
.query({format: 'json'})
.end((err, response)=> {
if (!err && response.ok) {
request
.post(`https://${response.body.url.host}/`)
.field(response.body.fields)
.field('Content-Type', image.type)
.attach('file', image, image.name)
.end((err, response) => {
if (err) {
console.log("Error uploading image: ", err);
reject(err);
} else {
resolve({
location: response.text.match('<Location>' + '(.*?)' + '</Location>')[1],
bucket: response.text.match('<Bucket>' + '(.*?)' + '</Bucket>')[1],
key: response.text.match('<Key>' + '(.*?)' + '</Key>')[1],
checksum: response.text.match('<ETag>"' + '(.*?)' + '"</ETag>')[1]
});
}
});
}
});
});
}
关键是some_folder/${filename}
,这包含在 google 的表单数据中(在response.fields
中)。
您可以看到我使用.attach('file', image, image.name)
提供文件名。 它正在正确上传,只是没有替换${filename}
变量。
编辑
我已经进一步缩小了这个问题的范围。 我们查询 S3 和 GCS 以获取预签名帖子中的字段。 使用 S3,如果我给出${filename}
的键,那么我会在字段中得到准确的返回值:
def presigned_post(bucket_name:, key:, **opts)
response = s3_resource.
bucket(bucket_name).
presigned_post(key: key, content_type_starts_with: '', **opts)
{
fields: response.fields,
url: { host: URI.parse(response.url).host }
}
end
此处的字段将包含"key"=>"${filename}"
。
但是在 GCS 的情况下,以下代码在字段中返回:key=>"$%7Bfilename%7D"
:
# https://cloud.google.com/storage/docs/xml-api/post-object#usage_and_examples
# https://www.rubydoc.info/gems/google-cloud-storage/1.0.1/Google/Cloud/Storage/Bucket:post_object
def presigned_post(bucket_name:, key:, acl:, success_action_status:, expiration: nil)
expiration ||= (Time.now + 1.hour).iso8601
policy = {
expiration: expiration,
conditions: [
["starts-with", "$key", "" ],
["starts-with", "$Content-Type", "" ],
{ acl: acl },
{ success_action_status: success_action_status }
]
}
post_obj = get_bucket!(bucket_name).post_object(key, policy: policy)
url_obj = { host: URI.parse(post_obj.url).host }
# Have to manually merge in these fields
fields = post_obj.fields.merge(
acl: acl,
success_action_status: success_action_status
)
return { fields: fields, url: url_obj }
end
如果我手动更改 GCS 请求字段中的密钥,那么它可以工作。 这真的是我应该做的吗?
此问题的修复已在google-cloud-storage v1.24.0中发布。
发现问题是由以下原因引起的:
def ext_path
URI.escape "/#{@bucket}/#{@path}"
end
在 google-cloud-ruby-gem 的lib/google/cloud/storage/file.rb
中。
这由同一个文件中的def post_object
调用。
我将在他们的 Github 页面上提出一个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.