diff --git a/app/controllers/projects/repositories_controller.rb b/app/controllers/projects/repositories_controller.rb index c4a5e2d63598f624c6a7990cb64913cd65cc769e..ba9aea1c165335c4f1bb898409794e64963500bf 100644 --- a/app/controllers/projects/repositories_controller.rb +++ b/app/controllers/projects/repositories_controller.rb @@ -11,18 +11,9 @@ class Projects::RepositoriesController < Projects::ApplicationController end def archive - begin - file_path = ArchiveRepositoryService.new(@project, params[:ref], params[:format]).execute - rescue - return head :not_found - end - - if file_path - # Send file to user - response.headers["Content-Length"] = File.open(file_path).size.to_s - send_file file_path - else - redirect_to request.fullpath - end + render json: ArchiveRepositoryService.new(@project, params[:ref], params[:format]).execute + rescue => ex + logger.error("#{self.class.name}: #{ex}") + return git_not_found! end end diff --git a/app/services/archive_repository_service.rb b/app/services/archive_repository_service.rb index e1b41527d8dc5d5efb86d47a1f11186de9845a6c..6414b5a0184a987831c24cd1714811ae6cfc6c49 100644 --- a/app/services/archive_repository_service.rb +++ b/app/services/archive_repository_service.rb @@ -9,17 +9,10 @@ class ArchiveRepositoryService def execute(options = {}) project.repository.clean_old_archives - raise "No archive file path" unless file_path + metadata = project.repository.archive_metadata(ref, storage_path, format) + raise "Repository or ref not found" if metadata.empty? - return file_path if archived? - - unless archiving? - RepositoryArchiveWorker.perform_async(project.id, ref, format) - end - - archived = wait_until_archived(options[:timeout] || 5.0) - - file_path if archived + metadata end private @@ -27,36 +20,4 @@ class ArchiveRepositoryService def storage_path Gitlab.config.gitlab.repository_downloads_path end - - def file_path - @file_path ||= project.repository.archive_file_path(ref, storage_path, format) - end - - def pid_file_path - @pid_file_path ||= project.repository.archive_pid_file_path(ref, storage_path, format) - end - - def archived? - File.exist?(file_path) - end - - def archiving? - File.exist?(pid_file_path) - end - - def wait_until_archived(timeout = 5.0) - return archived? if timeout == 0.0 - - t1 = Time.now - - begin - sleep 0.1 - - success = archived? - - t2 = Time.now - end until success || t2 - t1 >= timeout - - success - end end diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb index 2d96c9666d2a907119fecdfcf8948a19e16a0478..20d568cf4626ed9b7b292a11c066c30b0daccc6e 100644 --- a/lib/api/repositories.rb +++ b/lib/api/repositories.rb @@ -133,7 +133,7 @@ module API authorize! :download_code, user_project begin - file_path = ArchiveRepositoryService.new( + ArchiveRepositoryService.new( user_project, params[:sha], params[:format] @@ -141,17 +141,6 @@ module API rescue not_found!('File') end - - if file_path && File.exists?(file_path) - data = File.open(file_path, 'rb').read - basename = File.basename(file_path) - header['Content-Disposition'] = "attachment; filename=\"#{basename}\"" - content_type MIME::Types.type_for(file_path).first.content_type - env['api.format'] = :binary - present data - else - redirect request.fullpath - end end # Compare two branches, tags or commits diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index 0353b3b7ed3dc627661ba1b3d0bc1e5a865d1655..6830a916bcb619c8ce9b3f691ab8322a7e8910d4 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -193,7 +193,14 @@ module Grack end def render_grack_auth_ok - [200, { "Content-Type" => "application/json" }, [JSON.dump({ 'GL_ID' => Gitlab::ShellEnv.gl_id(@user) })]] + [ + 200, + { "Content-Type" => "application/json" }, + [JSON.dump({ + 'GL_ID' => Gitlab::ShellEnv.gl_id(@user), + 'RepoPath' => project.repository.path_to_repo, + })] + ] end def render_not_found diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab index 7218a4d2f2092c57eb21da7d3a88f41c81df29ea..ffc0eb0585ceb7f0babcda5ba03333ec5660c8dc 100644 --- a/lib/support/nginx/gitlab +++ b/lib/support/nginx/gitlab @@ -113,7 +113,25 @@ server { proxy_pass http://gitlab; } - location ~ [-\/\w\.]+\.git\/ { + location ~ ^/[\w\.-]+/[\w\.-]+/(info/refs|git-upload-pack|git-receive-pack)$ { + # 'Error' 418 is a hack to re-use the @gitlab-git-http-server block + error_page 418 = @gitlab-git-http-server; + return 418; + } + + location ~ ^/[\w\.-]+/[\w\.-]+/repository/archive { + # 'Error' 418 is a hack to re-use the @gitlab-git-http-server block + error_page 418 = @gitlab-git-http-server; + return 418; + } + + location ~ ^/api/v3/projects/[0-9]+/repository/archive { + # 'Error' 418 is a hack to re-use the @gitlab-git-http-server block + error_page 418 = @gitlab-git-http-server; + return 418; + } + + location @gitlab-git-http-server { ## If you use HTTPS make sure you disable gzip compression ## to be safe against BREACH attack. # gzip off; diff --git a/lib/support/nginx/gitlab-ssl b/lib/support/nginx/gitlab-ssl index 7dabfba87e22f73c48d6147f949d7e6f2a2c3a8b..c2e9f8864f82e1122bfbe53b3800a6da169d09f9 100644 --- a/lib/support/nginx/gitlab-ssl +++ b/lib/support/nginx/gitlab-ssl @@ -160,7 +160,25 @@ server { proxy_pass http://gitlab; } - location ~ [-\/\w\.]+\.git\/ { + location ~ ^/[\w\.-]+/[\w\.-]+/(info/refs|git-upload-pack|git-receive-pack)$ { + # 'Error' 418 is a hack to re-use the @gitlab-git-http-server block + error_page 418 = @gitlab-git-http-server; + return 418; + } + + location ~ ^/[\w\.-]+/[\w\.-]+/repository/archive { + # 'Error' 418 is a hack to re-use the @gitlab-git-http-server block + error_page 418 = @gitlab-git-http-server; + return 418; + } + + location ~ ^/api/v3/projects/[0-9]+/repository/archive { + # 'Error' 418 is a hack to re-use the @gitlab-git-http-server block + error_page 418 = @gitlab-git-http-server; + return 418; + } + + location @gitlab-git-http-server { ## If you use HTTPS make sure you disable gzip compression ## to be safe against BREACH attack. gzip off;