diff --git a/app/controllers/api/v4/uploads_controller.rb b/app/controllers/api/v4/uploads_controller.rb index 13f716d..60a6331 100644 --- a/app/controllers/api/v4/uploads_controller.rb +++ b/app/controllers/api/v4/uploads_controller.rb @@ -14,10 +14,12 @@ module API return end + content_type = Marcel::MimeType.for(file.tempfile, name: file.original_filename) || file.content_type || "application/octet-stream" + blob = ActiveStorage::Blob.create_and_upload!( io: file.tempfile, filename: file.original_filename, - content_type: file.content_type + content_type: content_type ) upload = current_user.uploads.create!(blob: blob, provenance: :api) diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb index c51a57c..e959398 100644 --- a/app/controllers/uploads_controller.rb +++ b/app/controllers/uploads_controller.rb @@ -22,10 +22,12 @@ class UploadsController < ApplicationController return end + content_type = Marcel::MimeType.for(uploaded_file.tempfile, name: uploaded_file.original_filename) || uploaded_file.content_type || "application/octet-stream" + blob = ActiveStorage::Blob.create_and_upload!( io: uploaded_file.tempfile, filename: uploaded_file.original_filename, - content_type: uploaded_file.content_type + content_type: content_type ) @upload = current_user.uploads.create!( diff --git a/app/models/upload.rb b/app/models/upload.rb index aff0c39..021f8e8 100644 --- a/app/models/upload.rb +++ b/app/models/upload.rb @@ -66,15 +66,34 @@ class Upload < ApplicationRecord end # Create upload from URL (for API/rescue operations) - def self.create_from_url(url, user:, provenance:, original_url: nil, authorization: nil) - open_options = {} - open_options["Authorization"] = authorization if authorization.present? + def self.create_from_url(url, user:, provenance:, original_url: nil, authorization: nil, filename: nil) + conn = Faraday.new(ssl: { verify: true, verify_mode: OpenSSL::SSL::VERIFY_PEER }) do |f| + # f.response :follow_redirects, limit: 5 + f.adapter Faraday.default_adapter + end + # Disable CRL checking which fails on some servers + conn.options.open_timeout = 30 + conn.options.timeout = 120 - downloaded = URI.open(url, open_options) + headers = {} + headers["Authorization"] = authorization if authorization.present? + + response = conn.get(url, nil, headers) + if response.status.between?(300, 399) + location = response.headers["location"] + raise "Failed to download: #{response.status} redirect to #{location}" + end + raise "Failed to download: #{response.status}" unless response.success? + + filename ||= File.basename(URI.parse(url).path) + body = response.body + content_type = Marcel::MimeType.for(StringIO.new(body), name: filename) || response.headers["content-type"] || "application/octet-stream" blob = ActiveStorage::Blob.create_and_upload!( - io: downloaded, - filename: File.basename(URI.parse(url).path) + io: StringIO.new(body), + filename: filename, + content_type: content_type, + identify: false ) create!(