Commit b14c484b authored by Grzegorz Bizon's avatar Grzegorz Bizon Committed by Kamil Trzciński

Merge branch 'use-send-url-for-incompatible-runners' into 'master'

Support SendURL for performing indirect download of artifacts if clients does…

See merge request gitlab-org/gitlab-ee!4401
parent a7dae52e
---
title: Support SendURL for performing indirect download of artifacts if clients does
not specify that it supports that
merge_request:
author:
type: fixed
...@@ -418,13 +418,17 @@ module API ...@@ -418,13 +418,17 @@ module API
end end
end end
def present_artifacts!(artifacts_file) def present_artifacts!(artifacts_file, direct_download: true)
return not_found! unless artifacts_file.exists? return not_found! unless artifacts_file.exists?
if artifacts_file.file_storage? if artifacts_file.file_storage?
present_file!(artifacts_file.path, artifacts_file.filename) present_file!(artifacts_file.path, artifacts_file.filename)
else elsif direct_download
redirect(artifacts_file.url) redirect(artifacts_file.url)
else
header(*Gitlab::Workhorse.send_url(artifacts_file.url))
status :ok
body
end end
end end
......
...@@ -244,11 +244,12 @@ module API ...@@ -244,11 +244,12 @@ module API
params do params do
requires :id, type: Integer, desc: %q(Job's ID) requires :id, type: Integer, desc: %q(Job's ID)
optional :token, type: String, desc: %q(Job's authentication token) optional :token, type: String, desc: %q(Job's authentication token)
optional :direct_download, default: false, type: Boolean, desc: %q(Perform direct download from remote storage instead of proxying artifacts)
end end
get '/:id/artifacts' do get '/:id/artifacts' do
job = authenticate_job! job = authenticate_job!
present_artifacts!(job.artifacts_file) present_artifacts!(job.artifacts_file, direct_download: params[:direct_download])
end end
end end
end end
......
...@@ -151,6 +151,18 @@ module Gitlab ...@@ -151,6 +151,18 @@ module Gitlab
] ]
end end
def send_url(url, allow_redirects: false)
params = {
'URL' => url,
'AllowRedirects' => allow_redirects
}
[
SEND_DATA_HEADER,
"send-url:#{encode(params)}"
]
end
def terminal_websocket(terminal) def terminal_websocket(terminal)
details = { details = {
'Terminal' => { 'Terminal' => {
......
...@@ -451,4 +451,21 @@ describe Gitlab::Workhorse do ...@@ -451,4 +451,21 @@ describe Gitlab::Workhorse do
end end
end end
end end
describe '.send_url' do
let(:url) { 'http://example.com' }
subject { described_class.send_url(url) }
it 'sets the header correctly' do
key, command, params = decode_workhorse_header(subject)
expect(key).to eq("Gitlab-Workhorse-Send-Data")
expect(command).to eq("send-url")
expect(params).to eq({
'URL' => url,
'AllowRedirects' => false
}.deep_stringify_keys)
end
end
end end
...@@ -1157,8 +1157,6 @@ describe API::Runner do ...@@ -1157,8 +1157,6 @@ describe API::Runner do
before do before do
create(:ci_job_artifact, :archive, file_store: store, job: job) create(:ci_job_artifact, :archive, file_store: store, job: job)
download_artifact
end end
context 'when using job token' do context 'when using job token' do
...@@ -1168,6 +1166,10 @@ describe API::Runner do ...@@ -1168,6 +1166,10 @@ describe API::Runner do
'Content-Disposition' => 'attachment; filename=ci_build_artifacts.zip' } 'Content-Disposition' => 'attachment; filename=ci_build_artifacts.zip' }
end end
before do
download_artifact
end
it 'download artifacts' do it 'download artifacts' do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(response.headers).to include download_headers expect(response.headers).to include download_headers
...@@ -1178,8 +1180,27 @@ describe API::Runner do ...@@ -1178,8 +1180,27 @@ describe API::Runner do
let(:store) { JobArtifactUploader::Store::REMOTE } let(:store) { JobArtifactUploader::Store::REMOTE }
let!(:job) { create(:ci_build) } let!(:job) { create(:ci_build) }
it 'download artifacts' do context 'when proxy download is being used' do
expect(response).to have_http_status(302) before do
download_artifact(direct_download: false)
end
it 'uses workhorse send-url' do
expect(response).to have_gitlab_http_status(200)
expect(response.headers).to include(
'Gitlab-Workhorse-Send-Data' => /send-url:/)
end
end
context 'when direct download is being used' do
before do
download_artifact(direct_download: true)
end
it 'receive redirect for downloading artifacts' do
expect(response).to have_gitlab_http_status(302)
expect(response.headers).to include('Location')
end
end end
end end
end end
...@@ -1187,6 +1208,10 @@ describe API::Runner do ...@@ -1187,6 +1208,10 @@ describe API::Runner do
context 'when using runnners token' do context 'when using runnners token' do
let(:token) { job.project.runners_token } let(:token) { job.project.runners_token }
before do
download_artifact
end
it 'responds with forbidden' do it 'responds with forbidden' do
expect(response).to have_gitlab_http_status(403) expect(response).to have_gitlab_http_status(403)
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