Add support for various archive formats.

Used mime-types gem instead of hardcoding content types.
Allow multiple extensions in archive route (.tar.gz, .tar.bz2).
Change content disposition from infile(?) to attachment for api.
Fixed api would return “archive” instead of {project}-{hash}.{ext}
This commit is contained in:
Jason Hollingsworth 2013-12-20 13:12:44 -06:00
parent b512fbc0ec
commit 7cc2520541
6 changed files with 44 additions and 8 deletions

View file

@ -16,7 +16,7 @@ class Projects::RepositoriesController < Projects::ApplicationController
storage_path = Rails.root.join("tmp", "repositories")
file_path = @repository.archive_repo(params[:ref], storage_path)
file_path = @repository.archive_repo(params[:ref], storage_path, params[:format].downcase)
if file_path
# Send file to user

View file

@ -217,7 +217,7 @@ Gitlab::Application.routes.draw do
resource :repository, only: [:show] do
member do
get "stats"
get "archive"
get "archive", constraints: { format: Gitlab::Regex.archive_formats_regex }
end
end

View file

@ -1,3 +1,5 @@
require 'mime/types'
module API
# Projects API
class Repositories < Grape::API
@ -206,18 +208,20 @@ module API
# sha (optional) - the commit sha to download defaults to the tip of the default branch
# Example Request:
# GET /projects/:id/repository/archive
get ":id/repository/archive" do
get ":id/repository/archive", requirements: { format: Gitlab::Regex.archive_formats_regex } do
authorize! :download_code, user_project
repo = user_project.repository
ref = params[:sha]
format = params[:format]
storage_path = Rails.root.join("tmp", "repositories")
file_path = repo.archive_repo(ref, storage_path)
file_path = repo.archive_repo(ref, storage_path, format)
if file_path && File.exists?(file_path)
data = File.open(file_path, 'rb').read
header "Content-Disposition:", " infile; filename=\"#{File.basename(file_path)}\""
content_type 'application/x-gzip'
header["Content-Disposition"] = "attachment; filename=\"#{File.basename(file_path)}\""
content_type MIME::Types.type_for(file_path).first.content_type
env['api.format'] = :binary

View file

@ -17,6 +17,11 @@ module Gitlab
def path_regex
default_regex
end
def archive_formats_regex
#|zip|tar| tar.gz | tar.bz2 |
/(zip|tar|tar\.gz|tgz|gz|tar\.bz2|tbz|tbz2|tb2|bz2)/
end
def git_reference_regex
# Valid git ref regex, see:

View file

@ -1,4 +1,5 @@
require 'spec_helper'
require 'mime/types'
describe API::API do
include ApiHelpers
@ -232,11 +233,29 @@ describe API::API do
end
end
describe "GET /projects/:id/repository/archive/:sha" do
describe "GET /projects/:id/repository/archive(.:format)?:sha" do
it "should get the archive" do
get api("/projects/#{project.id}/repository/archive", user)
repo_name = project.repository.name.gsub("\.git", "")
response.status.should == 200
response.content_type.should == 'application/x-gzip'
response.headers['Content-Disposition'].should =~ /filename\=\"#{repo_name}\-[^\.]+\.tar.gz\"/
response.content_type.should == MIME::Types.type_for('file.tar.gz').first.content_type
end
it "should get the archive.zip" do
get api("/projects/#{project.id}/repository/archive.zip", user)
repo_name = project.repository.name.gsub("\.git", "")
response.status.should == 200
response.headers['Content-Disposition'].should =~ /filename\=\"#{repo_name}\-[^\.]+\.zip\"/
response.content_type.should == MIME::Types.type_for('file.zip').first.content_type
end
it "should get the archive.tar.bz2" do
get api("/projects/#{project.id}/repository/archive.tar.bz2", user)
repo_name = project.repository.name.gsub("\.git", "")
response.status.should == 200
response.headers['Content-Disposition'].should =~ /filename\=\"#{repo_name}\-[^\.]+\.tar.bz2\"/
response.content_type.should == MIME::Types.type_for('file.tar.bz2').first.content_type
end
it "should return 404 for invalid sha" do

View file

@ -130,6 +130,14 @@ describe Projects::RepositoriesController, "routing" do
get("/gitlab/gitlabhq/repository/archive").should route_to('projects/repositories#archive', project_id: 'gitlab/gitlabhq')
end
it "to #archive format:zip" do
get("/gitlab/gitlabhq/repository/archive.zip").should route_to('projects/repositories#archive', project_id: 'gitlab/gitlabhq', format: 'zip')
end
it "to #archive format:tar.bz2" do
get("/gitlab/gitlabhq/repository/archive.tar.bz2").should route_to('projects/repositories#archive', project_id: 'gitlab/gitlabhq', format: 'tar.bz2')
end
it "to #show" do
get("/gitlab/gitlabhq/repository").should route_to('projects/repositories#show', project_id: 'gitlab/gitlabhq')
end