Add workhorse controller and API helpers
This commit is contained in:
parent
3cb69f0c0b
commit
8c3ba8d6c9
12 changed files with 45 additions and 24 deletions
|
@ -6,6 +6,7 @@ class ApplicationController < ActionController::Base
|
|||
include Gitlab::GonHelper
|
||||
include GitlabRoutingHelper
|
||||
include PageLayoutHelper
|
||||
include WorkhorseHelper
|
||||
|
||||
before_action :authenticate_user_from_token!
|
||||
before_action :authenticate_user!
|
||||
|
|
|
@ -10,10 +10,7 @@ class Projects::AvatarsController < Projects::ApplicationController
|
|||
|
||||
return if cached_blob?
|
||||
|
||||
headers.store(*Gitlab::Workhorse.send_git_blob(@repository, @blob))
|
||||
headers['Content-Disposition'] = 'inline'
|
||||
headers['Content-Type'] = safe_content_type(@blob)
|
||||
head :ok # 'render nothing: true' messes up the Content-Type
|
||||
send_git_blob @repository, @blob
|
||||
else
|
||||
render_404
|
||||
end
|
||||
|
|
|
@ -18,10 +18,7 @@ class Projects::RawController < Projects::ApplicationController
|
|||
if @blob.lfs_pointer?
|
||||
send_lfs_object
|
||||
else
|
||||
headers.store(*Gitlab::Workhorse.send_git_blob(@repository, @blob))
|
||||
headers['Content-Disposition'] = 'inline'
|
||||
headers['Content-Type'] = safe_content_type(@blob)
|
||||
head :ok # 'render nothing: true' messes up the Content-Type
|
||||
send_git_blob @repository, @blob
|
||||
end
|
||||
else
|
||||
render_404
|
||||
|
|
|
@ -11,8 +11,7 @@ class Projects::RepositoriesController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def archive
|
||||
headers.store(*Gitlab::Workhorse.send_git_archive(@project, params[:ref], params[:format]))
|
||||
head :ok
|
||||
send_git_archive @repository, ref: params[:ref], format: params[:format]
|
||||
rescue => ex
|
||||
logger.error("#{self.class.name}: #{ex}")
|
||||
return git_not_found!
|
||||
|
|
17
app/helpers/workhorse_helper.rb
Normal file
17
app/helpers/workhorse_helper.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Helpers to send Git blobs or archives through Workhorse.
|
||||
# Workhorse will also serve files when using `send_file`.
|
||||
module WorkhorseHelper
|
||||
# Send a Git blob through Workhorse
|
||||
def send_git_blob(repository, blob)
|
||||
headers.store(*Gitlab::Workhorse.send_git_blob(repository, blob))
|
||||
headers['Content-Disposition'] = 'inline'
|
||||
headers['Content-Type'] = safe_content_type(blob)
|
||||
head :ok # 'render nothing: true' messes up the Content-Type
|
||||
end
|
||||
|
||||
# Archive a Git repository and send it through Workhorse
|
||||
def send_git_archive(repository, ref:, format:)
|
||||
headers.store(*Gitlab::Workhorse.send_git_archive(repository, ref: ref, format: format))
|
||||
head :ok
|
||||
end
|
||||
end
|
|
@ -12,6 +12,7 @@
|
|||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20160530150109) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
enable_extension "pg_trgm"
|
||||
|
|
|
@ -408,5 +408,15 @@ module API
|
|||
error!(errors[:access_level], 422) if errors[:access_level].any?
|
||||
not_found!(errors)
|
||||
end
|
||||
|
||||
def send_git_blob(repository, blob)
|
||||
env['api.format'] = :txt
|
||||
content_type 'text/plain'
|
||||
header *Gitlab::Workhorse.send_git_blob(repository, blob)
|
||||
end
|
||||
|
||||
def send_git_archive(repository, ref:, format:)
|
||||
header *Gitlab::Workhorse.send_git_archive(repository, ref: ref, format: format)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -56,8 +56,7 @@ module API
|
|||
blob = Gitlab::Git::Blob.find(repo, commit.id, params[:filepath])
|
||||
not_found! "File" unless blob
|
||||
|
||||
content_type 'text/plain'
|
||||
header(*Gitlab::Workhorse.send_git_blob(repo, blob))
|
||||
send_git_blob repo, blob
|
||||
end
|
||||
|
||||
# Get a raw blob contents by blob sha
|
||||
|
@ -80,10 +79,7 @@ module API
|
|||
|
||||
not_found! 'Blob' unless blob
|
||||
|
||||
env['api.format'] = :txt
|
||||
|
||||
content_type blob.mime_type
|
||||
header(*Gitlab::Workhorse.send_git_blob(repo, blob))
|
||||
send_git_blob repo, blob
|
||||
end
|
||||
|
||||
# Get a an archive of the repository
|
||||
|
@ -98,7 +94,7 @@ module API
|
|||
authorize! :download_code, user_project
|
||||
|
||||
begin
|
||||
header(*Gitlab::Workhorse.send_git_archive(user_project, params[:sha], params[:format]))
|
||||
send_git_archive user_project.repository, ref: params[:sha], format: params[:format]
|
||||
rescue
|
||||
not_found!('File')
|
||||
end
|
||||
|
|
|
@ -18,10 +18,10 @@ module Gitlab
|
|||
]
|
||||
end
|
||||
|
||||
def send_git_archive(project, ref, format)
|
||||
def send_git_archive(repository, ref:, format:)
|
||||
format ||= 'tar.gz'
|
||||
format.downcase!
|
||||
params = project.repository.archive_metadata(ref, Gitlab.config.gitlab.repository_downloads_path, format)
|
||||
params = repository.archive_metadata(ref, Gitlab.config.gitlab.repository_downloads_path, format)
|
||||
raise "Repository or ref not found" if params.empty?
|
||||
|
||||
[
|
||||
|
@ -29,9 +29,9 @@ module Gitlab
|
|||
"git-archive:#{encode(params)}",
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
|
||||
|
||||
def encode(hash)
|
||||
Base64.urlsafe_encode64(JSON.dump(hash))
|
||||
end
|
||||
|
|
|
@ -17,6 +17,7 @@ describe Projects::RawController do
|
|||
expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8')
|
||||
expect(response.header['Content-Disposition']).
|
||||
to eq("inline")
|
||||
expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with("git-blob:")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -31,6 +32,7 @@ describe Projects::RawController do
|
|||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.header['Content-Type']).to eq('image/jpeg')
|
||||
expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with("git-blob:")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -20,10 +20,11 @@ describe Projects::RepositoriesController do
|
|||
project.team << [user, :developer]
|
||||
sign_in(user)
|
||||
end
|
||||
it "uses Gitlab::Workhorse" do
|
||||
expect(Gitlab::Workhorse).to receive(:send_git_archive).with(project, "master", "zip")
|
||||
|
||||
it "uses Gitlab::Workhorse" do
|
||||
get :archive, namespace_id: project.namespace.path, project_id: project.path, ref: "master", format: "zip"
|
||||
|
||||
expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with("git-archive:")
|
||||
end
|
||||
|
||||
context "when the service raises an error" do
|
||||
|
|
|
@ -11,7 +11,7 @@ describe Gitlab::Workhorse, lib: true do
|
|||
end
|
||||
|
||||
it "raises an error" do
|
||||
expect { subject.send_git_archive(project, "master", "zip") }.to raise_error(RuntimeError)
|
||||
expect { subject.send_git_archive(project.repository, ref: "master", format: "zip") }.to raise_error(RuntimeError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue