mirror of
https://github.com/discourse/discourse.git
synced 2025-06-04 09:34:41 +08:00
FIX: Make sure S3 object headers are preserved on copy (#14302)
When copying an existing upload stub temporary object on S3 to its final destination we were not copying across its additional headers such as content-disposition and cache-control, which led to issues like attachments not downloading with their original filename when clicking the download links in posts. This is because the metadata_directive = REPLACE option was not being passed to object.copy_from(), so only the source object's headers were being used. Added an option for apply_metadata_to_destination to apply this option conditionally, because we may not always want to replace this metadata, but we definitely do when copying a temporary upload.
This commit is contained in:
@ -95,4 +95,38 @@ describe "S3Helper" do
|
||||
expect(object1.key).to eq("folder_path/original/1X/def.xyz")
|
||||
expect(object2.key).to eq("#{FileStore::BaseStore::TEMPORARY_UPLOAD_PREFIX}folder_path/uploads/default/blah/def.xyz")
|
||||
end
|
||||
|
||||
describe "#copy" do
|
||||
let(:source_key) { "#{FileStore::BaseStore::TEMPORARY_UPLOAD_PREFIX}uploads/default/blah/source.jpg" }
|
||||
let(:destination_key) { "original/1X/destination.jpg" }
|
||||
let(:s3_helper) { S3Helper.new("test-bucket", "", client: client) }
|
||||
|
||||
it "can copy an object from the source to the destination" do
|
||||
destination_stub = Aws::S3::Object.new(bucket_name: "test-bucket", key: destination_key, client: client)
|
||||
s3_helper.send(:s3_bucket).expects(:object).with(destination_key).returns(destination_stub)
|
||||
destination_stub.expects(:copy_from).with(copy_source: "test-bucket/#{source_key}").returns(
|
||||
stub(copy_object_result: stub(etag: "\"etag\""))
|
||||
)
|
||||
response = s3_helper.copy(source_key, destination_key)
|
||||
expect(response.first).to eq(destination_key)
|
||||
expect(response.second).to eq("etag")
|
||||
end
|
||||
|
||||
it "puts the metadata from options onto the destination if apply_metadata_to_destination" do
|
||||
content_disposition = "attachment; filename=\"source.jpg\"; filename*=UTF-8''source.jpg"
|
||||
destination_stub = Aws::S3::Object.new(bucket_name: "test-bucket", key: destination_key, client: client)
|
||||
s3_helper.send(:s3_bucket).expects(:object).with(destination_key).returns(destination_stub)
|
||||
destination_stub.expects(:copy_from).with(
|
||||
copy_source: "test-bucket/#{source_key}", content_disposition: content_disposition, metadata_directive: "REPLACE"
|
||||
).returns(
|
||||
stub(copy_object_result: stub(etag: "\"etag\""))
|
||||
)
|
||||
response = s3_helper.copy(
|
||||
source_key, destination_key,
|
||||
options: { apply_metadata_to_destination: true, content_disposition: content_disposition }
|
||||
)
|
||||
expect(response.first).to eq(destination_key)
|
||||
expect(response.second).to eq("etag")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Reference in New Issue
Block a user