diff --git a/app/controllers/profiles/keys_controller.rb b/app/controllers/profiles/keys_controller.rb index 3c3dc03a4ee..912421e3d08 100644 --- a/app/controllers/profiles/keys_controller.rb +++ b/app/controllers/profiles/keys_controller.rb @@ -40,7 +40,8 @@ class Profiles::KeysController < Profiles::ApplicationController begin user = UserFinder.new(params[:username]).find_by_username if user.present? - render text: user.all_ssh_keys.join("\n"), content_type: "text/plain" + headers['Content-Disposition'] = 'attachment' + render text: user.all_ssh_keys.join("\n"), content_type: 'text/plain' else return render_404 end diff --git a/changelogs/unreleased/fj-force-content-disposition.yml b/changelogs/unreleased/fj-force-content-disposition.yml new file mode 100644 index 00000000000..d84555a489f --- /dev/null +++ b/changelogs/unreleased/fj-force-content-disposition.yml @@ -0,0 +1,5 @@ +--- +title: Force content disposition attachment to several endpoints +merge_request: 23223 +author: +type: other diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 60bf977f0e4..9fda73d5b92 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -494,6 +494,7 @@ module API def send_git_blob(repository, blob) env['api.format'] = :txt content_type 'text/plain' + header['Content-Disposition'] = "attachment; filename=#{blob.name.inspect}" header(*Gitlab::Workhorse.send_git_blob(repository, blob)) end diff --git a/lib/api/snippets.rb b/lib/api/snippets.rb index 1ae144ca9c1..326d55afd0e 100644 --- a/lib/api/snippets.rb +++ b/lib/api/snippets.rb @@ -146,6 +146,7 @@ module API env['api.format'] = :txt content_type 'text/plain' + header['Content-Disposition'] = 'attachment' present snippet.content end # rubocop: enable CodeReuse/ActiveRecord diff --git a/spec/controllers/profiles/keys_controller_spec.rb b/spec/controllers/profiles/keys_controller_spec.rb index ea26bc83353..685db8488f0 100644 --- a/spec/controllers/profiles/keys_controller_spec.rb +++ b/spec/controllers/profiles/keys_controller_spec.rb @@ -62,8 +62,15 @@ describe Profiles::KeysController do it "responds with text/plain content type" do get :get_keys, username: user.username + expect(response.content_type).to eq("text/plain") end + + it "responds with attachment content disposition" do + get :get_keys, username: user.username + + expect(response.headers['Content-Disposition']).to eq('attachment') + end end end end diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb index a2b41d56b8b..334dbb1c34c 100644 --- a/spec/requests/api/files_spec.rb +++ b/spec/requests/api/files_spec.rb @@ -178,6 +178,14 @@ describe API::Files do expect(response).to have_gitlab_http_status(200) end + it 'forces attachment content disposition' do + url = route(file_path) + "/raw" + + get api(url, current_user), params + + expect(headers['Content-Disposition']).to match(/^attachment/) + end + context 'when mandatory params are not given' do it_behaves_like '400 response' do let(:request) { get api(route("any%2Ffile"), current_user) } diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb index fa38751fe58..de141377793 100644 --- a/spec/requests/api/repositories_spec.rb +++ b/spec/requests/api/repositories_spec.rb @@ -168,6 +168,12 @@ describe API::Repositories do expect(response).to have_gitlab_http_status(200) end + it 'forces attachment content disposition' do + get api(route, current_user) + + expect(headers['Content-Disposition']).to match(/^attachment/) + end + context 'when sha does not exist' do it_behaves_like '404 response' do let(:request) { get api(route.sub(sample_blob.oid, '123456'), current_user) } diff --git a/spec/requests/api/snippets_spec.rb b/spec/requests/api/snippets_spec.rb index 6da769cb3ed..c546ba3e127 100644 --- a/spec/requests/api/snippets_spec.rb +++ b/spec/requests/api/snippets_spec.rb @@ -94,6 +94,12 @@ describe API::Snippets do expect(response.body).to eq(snippet.content) end + it 'forces attachment content disposition' do + get api("/snippets/#{snippet.id}/raw", user) + + expect(headers['Content-Disposition']).to match(/^attachment/) + end + it 'returns 404 for invalid snippet id' do get api("/snippets/1234/raw", user)