Skip to content
Snippets Groups Projects
Commit 8c3ba8d6 authored by Douwe Maan's avatar Douwe Maan
Browse files

Add workhorse controller and API helpers

parent 3cb69f0c
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -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!
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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!
Loading
Loading
# 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
Loading
Loading
@@ -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"
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
@@ -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
Loading
Loading
@@ -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
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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?
 
[
Loading
Loading
@@ -29,9 +29,9 @@ module Gitlab
"git-archive:#{encode(params)}",
]
end
protected
def encode(hash)
Base64.urlsafe_encode64(JSON.dump(hash))
end
Loading
Loading
Loading
Loading
@@ -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
 
Loading
Loading
@@ -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
 
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment