2018-09-14 01:42:05 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2017-09-07 17:27:04 -04:00
|
|
|
module SendFileUpload
|
2018-11-07 10:54:37 -05:00
|
|
|
def send_upload(file_upload, send_params: {}, redirect_params: {}, attachment: nil, proxy: false, disposition: 'attachment')
|
2020-08-28 02:10:45 -04:00
|
|
|
content_type = content_type_for(attachment)
|
|
|
|
|
2017-09-07 17:27:04 -04:00
|
|
|
if attachment
|
2020-01-29 13:08:47 -05:00
|
|
|
response_disposition = ActionDispatch::Http::ContentDisposition.format(disposition: disposition, filename: attachment)
|
2019-02-04 20:27:22 -05:00
|
|
|
|
2018-08-13 18:36:15 -04:00
|
|
|
# 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.
|
2019-02-04 20:27:22 -05:00
|
|
|
redirect_params[:query] = { "response-content-disposition" => response_disposition,
|
2020-08-28 02:10:45 -04:00
|
|
|
"response-content-type" => content_type }
|
2018-05-14 00:43:48 -04:00
|
|
|
# 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'
|
2019-02-04 20:27:22 -05:00
|
|
|
|
2020-01-29 13:08:47 -05:00
|
|
|
send_params.merge!(filename: attachment, disposition: disposition)
|
2017-09-07 17:27:04 -04:00
|
|
|
end
|
|
|
|
|
2020-08-10 14:09:54 -04:00
|
|
|
if image_scaling_request?(file_upload)
|
|
|
|
location = file_upload.file_storage? ? file_upload.path : file_upload.url
|
2020-08-28 02:10:45 -04:00
|
|
|
headers.store(*Gitlab::Workhorse.send_scaled_image(location, params[:width].to_i, content_type))
|
2020-08-10 14:09:54 -04:00
|
|
|
head :ok
|
|
|
|
elsif file_upload.file_storage?
|
2017-09-07 17:27:04 -04:00
|
|
|
send_file file_upload.path, send_params
|
2018-11-07 10:54:37 -05:00
|
|
|
elsif file_upload.class.proxy_download_enabled? || proxy
|
2018-03-22 14:37:47 -04:00
|
|
|
headers.store(*Gitlab::Workhorse.send_url(file_upload.url(**redirect_params)))
|
|
|
|
head :ok
|
2017-09-07 17:27:04 -04:00
|
|
|
else
|
|
|
|
redirect_to file_upload.url(**redirect_params)
|
|
|
|
end
|
|
|
|
end
|
2018-08-13 18:36:15 -04:00
|
|
|
|
2020-08-28 02:10:45 -04:00
|
|
|
def content_type_for(attachment)
|
|
|
|
return '' unless attachment
|
|
|
|
|
|
|
|
guess_content_type(attachment)
|
|
|
|
end
|
|
|
|
|
2018-08-13 18:36:15 -04:00
|
|
|
def guess_content_type(filename)
|
|
|
|
types = MIME::Types.type_for(filename)
|
|
|
|
|
|
|
|
if types.present?
|
|
|
|
types.first.content_type
|
|
|
|
else
|
|
|
|
"application/octet-stream"
|
|
|
|
end
|
|
|
|
end
|
2020-08-10 14:09:54 -04:00
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def image_scaling_request?(file_upload)
|
2020-08-31 14:10:43 -04:00
|
|
|
avatar_safe_for_scaling?(file_upload) &&
|
|
|
|
scaling_allowed_by_feature_flags?(file_upload) &&
|
2020-09-04 11:08:46 -04:00
|
|
|
valid_image_scaling_width?
|
2020-08-28 02:10:45 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def avatar_safe_for_scaling?(file_upload)
|
|
|
|
file_upload.try(:image_safe_for_scaling?) && mounted_as_avatar?(file_upload)
|
2020-08-10 14:09:54 -04:00
|
|
|
end
|
|
|
|
|
2020-08-28 02:10:45 -04:00
|
|
|
def mounted_as_avatar?(file_upload)
|
|
|
|
file_upload.try(:mounted_as)&.to_sym == :avatar
|
2020-08-10 14:09:54 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def valid_image_scaling_width?
|
|
|
|
Avatarable::ALLOWED_IMAGE_SCALER_WIDTHS.include?(params[:width]&.to_i)
|
|
|
|
end
|
2020-08-31 14:10:43 -04:00
|
|
|
|
|
|
|
def scaling_allowed_by_feature_flags?(file_upload)
|
2020-11-09 10:08:56 -05:00
|
|
|
Feature.enabled?(:dynamic_image_resizing, default_enabled: true, type: :ops)
|
2020-08-31 14:10:43 -04:00
|
|
|
end
|
2017-09-07 17:27:04 -04:00
|
|
|
end
|