Commit 997301e1 authored by Felipe Artur's avatar Felipe Artur Committed by Douglas Barbosa Alexandre

Allow pdf files to be opened on browser

When clicking on PDF attachment links open
on browserinstead of downloading it.
parent d386a553
...@@ -44,15 +44,14 @@ module UploadsActions ...@@ -44,15 +44,14 @@ module UploadsActions
expires_in ttl, directives expires_in ttl, directives
disposition = uploader.embeddable? ? 'inline' : 'attachment' file_uploader = [uploader, *uploader.versions.values].find do |version|
version.filename == params[:filename]
uploaders = [uploader, *uploader.versions.values] end
uploader = uploaders.find { |version| version.filename == params[:filename] }
return render_404 unless uploader return render_404 unless file_uploader
workhorse_set_content_type! workhorse_set_content_type!
send_upload(uploader, attachment: uploader.filename, disposition: disposition) send_upload(file_uploader, attachment: file_uploader.filename, disposition: content_disposition)
end end
def authorize def authorize
...@@ -83,6 +82,14 @@ module UploadsActions ...@@ -83,6 +82,14 @@ module UploadsActions
end end
end end
def content_disposition
if uploader.embeddable? || uploader.pdf?
'inline'
else
'attachment'
end
end
def uploader_class def uploader_class
raise NotImplementedError raise NotImplementedError
end end
......
---
title: Allow PDF attachments to be opened on browser
merge_request: 21272
author:
type: added
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
module Gitlab module Gitlab
module FileTypeDetection module FileTypeDetection
SAFE_IMAGE_EXT = %w[png jpg jpeg gif bmp tiff ico].freeze SAFE_IMAGE_EXT = %w[png jpg jpeg gif bmp tiff ico].freeze
PDF_EXT = 'pdf'
# We recommend using the .mp4 format over .mov. Videos in .mov format can # We recommend using the .mp4 format over .mov. Videos in .mov format can
# still be used but you really need to make sure they are served with the # still be used but you really need to make sure they are served with the
# proper MIME type video/mp4 and not video/quicktime or your videos won't play # proper MIME type video/mp4 and not video/quicktime or your videos won't play
...@@ -46,6 +47,10 @@ module Gitlab ...@@ -46,6 +47,10 @@ module Gitlab
extension_match?(SAFE_AUDIO_EXT) extension_match?(SAFE_AUDIO_EXT)
end end
def pdf?
extension_match?([PDF_EXT])
end
def embeddable? def embeddable?
image? || video? || audio? image? || video? || audio?
end end
......
...@@ -196,24 +196,39 @@ describe UploadsController do ...@@ -196,24 +196,39 @@ describe UploadsController do
describe "GET show" do describe "GET show" do
context 'Content-Disposition security measures' do context 'Content-Disposition security measures' do
let(:expected_disposition) { 'inline;' }
let(:project) { create(:project, :public) } let(:project) { create(:project, :public) }
context 'for PNG files' do shared_examples_for 'uploaded file with disposition' do
it 'returns Content-Disposition: inline' do it 'returns correct Content-Disposition' do
note = create(:note, :with_attachment, project: project) get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: filename }
get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' }
expect(response['Content-Disposition']).to start_with('inline;') expect(response['Content-Disposition']).to start_with(expected_disposition)
end end
end end
context 'for PNG files' do
let(:filename) { 'dk.png' }
let(:expected_disposition) { 'inline;' }
let(:note) { create(:note, :with_attachment, project: project) }
it_behaves_like 'uploaded file with disposition'
end
context 'for PDF files' do
let(:filename) { 'git-cheat-sheet.pdf' }
let(:expected_disposition) { 'inline;' }
let(:note) { create(:note, :with_pdf_attachment, project: project) }
it_behaves_like 'uploaded file with disposition'
end
context 'for SVG files' do context 'for SVG files' do
it 'returns Content-Disposition: attachment' do let(:filename) { 'unsanitized.svg' }
note = create(:note, :with_svg_attachment, project: project) let(:expected_disposition) { 'attachment;' }
get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'unsanitized.svg' } let(:note) { create(:note, :with_svg_attachment, project: project) }
expect(response['Content-Disposition']).to start_with('attachment;') it_behaves_like 'uploaded file with disposition'
end
end end
end end
......
...@@ -167,6 +167,10 @@ FactoryBot.define do ...@@ -167,6 +167,10 @@ FactoryBot.define do
attachment { fixture_file_upload("spec/fixtures/unsanitized.svg", "image/svg+xml") } attachment { fixture_file_upload("spec/fixtures/unsanitized.svg", "image/svg+xml") }
end end
trait :with_pdf_attachment do
attachment { fixture_file_upload("spec/fixtures/git-cheat-sheet.pdf", "application/pdf") }
end
transient do transient do
in_reply_to { nil } in_reply_to { nil }
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment