Send required object storage PUT headers in /uploads/authorize API

As revealed in https://gitlab.com/gitlab-org/gitlab-ce/issues/49957, Rails
generates a signed URL with a fixed HTTP header with `Content-Type:
application/octet-stream`. However, if we change or remove that for
some reason in Workhorse, this breaks the upload with a 403 Unauthorized because
the signed URL is not valid.

We can make this more robust by doing the following:

1. In the `/uploads/authorize` request, Rails can return a `StoreHeaders` key-value
pair in the JSON response containing the required headers that the PUT
request must include.
2. Use those HTTP headers if that value is present.
3. For backwards compatibility, if that key is not present, default to
the old behavior of sending the fixed `Content-Type` header.

See https://gitlab.com/gitlab-org/gitlab-workhorse/merge_requests/297 as well.
This commit is contained in:
Stan Hu 2018-08-20 15:29:41 -07:00
parent a78c443de2
commit 97cabfb65c
3 changed files with 10 additions and 1 deletions

View File

@ -0,0 +1,5 @@
---
title: Send back required object storage PUT headers in /uploads/authorize API
merge_request: 21319
author:
type: changed

View File

@ -41,7 +41,9 @@ module ObjectStorage
GetURL: get_url,
StoreURL: store_url,
DeleteURL: delete_url,
MultipartUpload: multipart_upload_hash
MultipartUpload: multipart_upload_hash,
CustomPutHeaders: true,
PutHeaders: upload_options
}.compact
end

View File

@ -61,6 +61,8 @@ describe ObjectStorage::DirectUpload do
expect(subject[:GetURL]).to start_with(storage_url)
expect(subject[:StoreURL]).to start_with(storage_url)
expect(subject[:DeleteURL]).to start_with(storage_url)
expect(subject[:CustomPutHeaders]).to be_truthy
expect(subject[:PutHeaders]).to eq({ 'Content-Type' => 'application/octet-stream' })
end
end