262b974123
There were several issues:
1. With Google Cloud Storage, we can't override the Content-Type with
Response-Content-Type once it is set. Setting the value to
`application/octet-stream` doesn't buy us anything. GCS defaults to
`application/octet-stream`, and AWS uses `binary/octet-stream`. Just remove
this `Content-Type` when we upload new files.
2. CarrierWave and fog-google need to support query parameters:
https://github.com/fog/fog-google/pull/409/files, https://github.com/carrierwaveuploader/carrierwave/pull/2332/files.
CarrierWave has been monkey-patched until an official release.
3. Workhorse also needs to remove the Content-Type header in the request
(ef80978ff8/internal/objectstore/object.go (L66)
),
or we'll get a 403 error when uploading due to signed URLs not matching the headers.
Upgrading to Workhorse 6.1.0 for https://gitlab.com/gitlab-org/gitlab-workhorse/merge_requests/297
will make Workhorse use the headers that are used by Rails.
Closes #49957
35 lines
1.4 KiB
Ruby
35 lines
1.4 KiB
Ruby
module SendFileUpload
|
|
def send_upload(file_upload, send_params: {}, redirect_params: {}, attachment: nil, disposition: 'attachment')
|
|
if attachment
|
|
# Response-Content-Type will not override an existing Content-Type in
|
|
# Google Cloud Storage, so the metadata needs to be cleared on GCS for
|
|
# this to work. However, this override works with AWS.
|
|
redirect_params[:query] = { "response-content-disposition" => "#{disposition};filename=#{attachment.inspect}",
|
|
"response-content-type" => guess_content_type(attachment) }
|
|
# By default, Rails will send uploads with an extension of .js with a
|
|
# content-type of text/javascript, which will trigger Rails'
|
|
# cross-origin JavaScript protection.
|
|
send_params[:content_type] = 'text/plain' if File.extname(attachment) == '.js'
|
|
send_params.merge!(filename: attachment, disposition: disposition)
|
|
end
|
|
|
|
if file_upload.file_storage?
|
|
send_file file_upload.path, send_params
|
|
elsif file_upload.class.proxy_download_enabled?
|
|
headers.store(*Gitlab::Workhorse.send_url(file_upload.url(**redirect_params)))
|
|
head :ok
|
|
else
|
|
redirect_to file_upload.url(**redirect_params)
|
|
end
|
|
end
|
|
|
|
def guess_content_type(filename)
|
|
types = MIME::Types.type_for(filename)
|
|
|
|
if types.present?
|
|
types.first.content_type
|
|
else
|
|
"application/octet-stream"
|
|
end
|
|
end
|
|
end
|