Публикация объекта в Google Cloud Storage не заменяет переменную $ {filename} - PullRequest
0 голосов
/ 19 сентября 2019

Как описано здесь https://cloud.google.com/storage/docs/xml-api/post-object

Я могу использовать ${filename} как часть ключа при загрузке файла в GCS из браузера (используя подписанный запрос).

Это здорово, потому что это та же самая переменная, которую использует 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).

Вы видите, что я am , предоставляя имя файла с.attach('file', image, image.name).Это это загрузка корректно, только не заменяет ${filename} var.

edit

Я сузил проблему больше.Мы запрашиваем 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, тогда он работает.Это действительно то, что я должен делать?

1 Ответ

0 голосов
/ 20 сентября 2019

Выяснил, что проблема вызвана:

      def ext_path
        URI.escape "/#{@bucket}/#{@path}"
      end

в lib/google/cloud/storage/file.rb из google-cloud-ruby-gem.

Это вызывается def post_object в том жефайл.

Я собираюсь поднять вопрос на их странице Github.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...