GitLab wurde aktualisiert. Dank regelmäßiger Updates bleibt das THM GitLab sicher und Sie profitieren von den neuesten Funktionen. Vielen Dank für Ihre Geduld.

Commit 37be2007 authored by Robert Speicher's avatar Robert Speicher
Browse files

Merge branch 'workhorse-helpers' into 'master'

Add workhorse controller and API helpers

Adds `send_git_blob` and `send_git_archive` controller and API helpers to reduce duplication and make Workhorse easier for a developer to work with.

See merge request !4486
parents d6de8169 701e2df7
......@@ -55,6 +55,7 @@ v 8.9.0 (unreleased)
- Remove duplicated notification settings
- Put project Files and Commits tabs under Code tab
- Replace Colorize with Rainbow for coloring console output in Rake tasks.
- Add workhorse controller and API helpers
- An indicator is now displayed at the top of the comment field for confidential issues.
- RepositoryCheck::SingleRepositoryWorker public and private methods are now instrumented
- Improve issuables APIs performance when accessing notes !4471
......
......@@ -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 @@ def show
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
......
......@@ -61,12 +61,9 @@ def show
format.json { render json: @merge_request }
format.patch { render text: @merge_request.to_patch }
format.diff do
headers.store(*Gitlab::Workhorse.send_git_diff(@project.repository,
@merge_request.diff_base_commit.id,
@merge_request.last_commit.id))
headers['Content-Disposition'] = 'inline'
return render_404 unless @merge_request.diff_refs
head :ok
send_git_diff @project.repository, @merge_request.diff_refs
end
end
end
......
......@@ -18,10 +18,7 @@ def show
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 @@ def create
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!
......
# Helpers to send Git blobs, diffs 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
# Send a Git diff through Workhorse
def send_git_diff(repository, diff_refs)
headers.store(*Gitlab::Workhorse.send_git_diff(repository, diff_refs))
headers['Content-Disposition'] = 'inline'
head :ok
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
......@@ -408,5 +408,15 @@ def handle_member_errors(errors)
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 @@ def handle_project_member_errors(errors)
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 @@ def handle_project_member_errors(errors)
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 @@ def handle_project_member_errors(errors)
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
......
......@@ -21,27 +21,29 @@ def send_git_blob(repository, blob)
[
SEND_DATA_HEADER,
"git-blob:#{encode(params)}",
"git-blob:#{encode(params)}"
]
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?
[
SEND_DATA_HEADER,
"git-archive:#{encode(params)}",
"git-archive:#{encode(params)}"
]
end
def send_git_diff(repository, from, to)
def send_git_diff(repository, diff_refs)
from, to = diff_refs
params = {
'RepoPath' => repository.path_to_repo,
'ShaFrom' => from,
'ShaTo' => to
'RepoPath' => repository.path_to_repo,
'ShaFrom' => from.sha,
'ShaTo' => to.sha
}
[
......
......@@ -91,7 +91,7 @@
id: merge_request.iid,
format: :diff)
expect(response.headers['Gitlab-Workhorse-Send-Data']).to start_with("git-diff:")
expect(response.headers[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with("git-diff:")
end
end
......
......@@ -17,6 +17,7 @@
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 @@
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 @@
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 @@
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
......
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