diff --git a/app/controllers/projects/repositories_controller.rb b/app/controllers/projects/repositories_controller.rb
index 20e2a9311ee8dab7df8161b60ede132c31d23e7a..f686db70bd4771e8e9eecc6dd885b2463b60f130 100644
--- a/app/controllers/projects/repositories_controller.rb
+++ b/app/controllers/projects/repositories_controller.rb
@@ -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
diff --git a/config/routes.rb b/config/routes.rb
index 8322d6a9d4e0d76ee1ab683da1806c53564c16d9..734421ede1df0e68c61cadc1a5ee23b7c31e2525 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -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
 
diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb
index 6a9dc9a39f14d1eb54fa983e9e9d75361394eec2..0a32135ff10e02b888990a102f927bdcecd474a5 100644
--- a/lib/api/repositories.rb
+++ b/lib/api/repositories.rb
@@ -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
 
diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb
index 93e013ab1b3b2bd97aebaa8a75bb1732999b31fa..943dc9dc7eaad7f45f269837bb7da3e6d1709b61 100644
--- a/lib/gitlab/regex.rb
+++ b/lib/gitlab/regex.rb
@@ -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:
diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb
index e078efcc50a6e8499a83607d40678ad1b1509460..f73ac4372b29504d47caa5b282e45ab94fb6a6e7 100644
--- a/spec/requests/api/repositories_spec.rb
+++ b/spec/requests/api/repositories_spec.rb
@@ -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
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index 5597f08d1861dfe10131366909e5e9e72b298c91..97f7392e50aae6a9fa973d06abc3a4ce5335a0cb 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -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