Skip to content

Commit

Permalink
Fix to support retrieval of unquoted filenames from Content-Dispositi…
Browse files Browse the repository at this point in the history
…on. Fixes #2364
  • Loading branch information
mshibuya committed Jun 7, 2019
1 parent aab402f commit c7bebd6
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 6 deletions.
4 changes: 2 additions & 2 deletions lib/carrierwave/uploader/download.rb
Expand Up @@ -51,8 +51,8 @@ def file

def filename_from_header
if file.meta.include? 'content-disposition'
match = file.meta['content-disposition'].match(/filename="?([^"]+)/)
return match[1] unless match.nil? || match[1].empty?
match = file.meta['content-disposition'].match(/filename=(?:"([^"]+)"|([^";]+))/)
return match[1].presence || match[2].presence
end
end

Expand Down
40 changes: 36 additions & 4 deletions spec/uploader/download_spec.rb
Expand Up @@ -8,6 +8,7 @@
let(:url) { base_url + "/test.jpg" }
let(:test_file) { File.read(file_path(test_file_name)) }
let(:test_file_name) { "test.jpg" }
let(:content_disposition){ 'filename="another_test.jpg"' }
let(:unicode_named_file) { File.read(file_path(unicode_filename)) }
let(:unicode_URL) { URI.encode(base_url + "/#{unicode_filename}") }
let(:unicode_filename) { "юникод.jpg" }
Expand Down Expand Up @@ -36,7 +37,7 @@
to_return(body: test_file)

stub_request(:get, "www.example.com/content-disposition").
to_return(body: test_file, headers: { "Content-Disposition" => 'filename="another_test.jpg"' })
to_return(body: test_file, headers: { "Content-Disposition" => content_disposition })

stub_request(:get, "www.redirect.com").
to_return(status: 301, body: "Redirecting", headers: { "Location" => url })
Expand Down Expand Up @@ -145,9 +146,40 @@
expect(uploader.url).to eq("/uploads/tmp/#{cache_id}/#{test_file_name}")
end

it "reads content-disposition headers" do
uploader.download!("#{base_url}/content-disposition")
expect(uploader.url).to eq("/uploads/tmp/#{cache_id}/another_#{test_file_name}")
describe 'with content-disposition' do
context 'when filename is quoted' do
it "reads filename correctly" do
uploader.download!("#{base_url}/content-disposition")
expect(uploader.url).to eq("/uploads/tmp/#{cache_id}/another_#{test_file_name}")
end
end

context 'when filename is not quoted' do
let(:content_disposition){ 'filename=another_test.jpg' }

it "reads filename correctly" do
uploader.download!("#{base_url}/content-disposition")
expect(uploader.url).to eq("/uploads/tmp/#{cache_id}/another_#{test_file_name}")
end
end

context 'when filename is not quoted and terminated by semicolon' do
let(:content_disposition){ 'filename=another_test.jpg; size=1234' }

it "reads filename correctly" do
uploader.download!("#{base_url}/content-disposition")
expect(uploader.url).to eq("/uploads/tmp/#{cache_id}/another_#{test_file_name}")
end
end

context 'when filename is quoted and contains a semicolon' do
let(:content_disposition){ 'filename="another;_test.jpg"; size=1234' }

it "reads filename and replaces semicolon correctly" do
uploader.download!("#{base_url}/content-disposition")
expect(uploader.url).to eq("/uploads/tmp/#{cache_id}/another__#{test_file_name}")
end
end
end

it 'sets file extension based on content-type if missing' do
Expand Down

0 comments on commit c7bebd6

Please sign in to comment.