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;