Commit 360bd831 authored by Tomasz Maczukin's avatar Tomasz Maczukin

Add range checking

parent 38a1378e
...@@ -230,6 +230,14 @@ module Ci ...@@ -230,6 +230,14 @@ module Ci
end end
end end
def trace_length
unless trace.present?
0
else
trace.length
end
end
def trace=(trace) def trace=(trace)
recreate_trace_dir recreate_trace_dir
File.write(path_to_trace, trace) File.write(path_to_trace, trace)
......
...@@ -23,6 +23,8 @@ module Ci ...@@ -23,6 +23,8 @@ module Ci
rack_response({ 'message' => '500 Internal Server Error' }, 500) rack_response({ 'message' => '500 Internal Server Error' }, 500)
end end
content_type :txt, 'text/plain'
content_type :json, 'application/json'
format :json format :json
helpers ::Ci::API::Helpers helpers ::Ci::API::Helpers
......
...@@ -51,12 +51,24 @@ module Ci ...@@ -51,12 +51,24 @@ module Ci
end end
patch ":id/trace.txt" do patch ":id/trace.txt" do
authenticate_runner! build = Ci::Build.find_by_id(params[:id])
update_runner_last_contact not_found! unless build
build = Ci::Build.where(runner_id: current_runner.id).running.find(params[:id]) authenticate_build_token!(build)
forbidden!('Build has been erased!') if build.erased? forbidden!('Build has been erased!') if build.erased?
build.append_trace(params[:trace_part]) error!('400 Missing header Content-Range', 400) unless request.headers.has_key?('Content-Range')
content_range = request.headers['Content-Range']
content_range = content_range.split('-')
unless build.trace_length == content_range[0].to_i
return error!('416 Range Not Satisfiable', 416, { 'Range' => "0-#{build.trace_length}" })
end
build.append_trace(request.body.read)
status 202
header 'Build-Status', build.status
header 'Range', "0-#{build.trace_length}"
end end
# Authorize artifacts uploading for build - Runners only # Authorize artifacts uploading for build - Runners only
......
...@@ -158,23 +158,47 @@ describe Ci::API::API do ...@@ -158,23 +158,47 @@ describe Ci::API::API do
describe 'PATCH /builds/:id/trace.txt' do describe 'PATCH /builds/:id/trace.txt' do
let(:build) { create(:ci_build, :trace, runner_id: runner.id) } let(:build) { create(:ci_build, :trace, runner_id: runner.id) }
let(:headers) { { Ci::API::Helpers::BUILD_TOKEN_HEADER => build.token, 'Content-Type' => 'text/plain' } }
let(:headers_with_range) { headers.merge({ 'Content-Range' => '11-20' }) }
before do before do
build.run! build.run!
patch ci_api("/builds/#{build.id}/trace.txt"), trace_part: ' appended', token: runner.token patch ci_api("/builds/#{build.id}/trace.txt"), ' appended', headers_with_range
end end
it 'should append trace part to the trace' do context 'when request is valid' do
expect(response.status).to eq 200 it { expect(response.status).to eq 202 }
expect(build.reload.trace).to eq 'BUILD TRACE appended' it { expect(build.reload.trace).to eq 'BUILD TRACE appended' }
it { expect(response.header).to have_key 'Range' }
it { expect(response.header).to have_key 'Build-Status' }
end
context 'when content-range start is too big' do
let(:headers_with_range) { headers.merge({ 'Content-Range' => '15-20' }) }
it { expect(response.status).to eq 416 }
it { expect(response.header).to have_key 'Range' }
it { expect(response.header['Range']).to eq '0-11' }
end
context 'when content-range start is too small' do
let(:headers_with_range) { headers.merge({ 'Content-Range' => '8-20' }) }
it { expect(response.status).to eq 416 }
it { expect(response.header).to have_key 'Range' }
it { expect(response.header['Range']).to eq '0-11' }
end
context 'when Content-Range header is missing' do
let(:headers_with_range) { headers.merge({}) }
it { expect(response.status).to eq 400 }
end end
context 'when build has been erased' do context 'when build has been erased' do
let(:build) { create(:ci_build, runner_id: runner.id, erased_at: Time.now) } let(:build) { create(:ci_build, runner_id: runner.id, erased_at: Time.now) }
it 'should respond with forbidden' do it { expect(response.status).to eq 403 }
expect(response.status).to eq 403
end
end end
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