blob: 8a3b1e25041370bf03ff7cd0816535435125ddb4 [file] [log] [blame]
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -07001// Copyright 2013 Google Inc. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.gitiles;
16
17import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
18import static javax.servlet.http.HttpServletResponse.SC_OK;
19
Dave Borowitzded109a2014-03-03 15:25:39 -050020import com.google.common.base.Optional;
Dave Borowitzfc417942014-04-09 07:54:42 -070021import com.google.common.base.Strings;
Dave Borowitzded109a2014-03-03 15:25:39 -050022
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070023import org.eclipse.jgit.api.ArchiveCommand;
24import org.eclipse.jgit.api.errors.GitAPIException;
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070025import org.eclipse.jgit.errors.IncorrectObjectTypeException;
26import org.eclipse.jgit.http.server.ServletUtils;
Dave Borowitz5051e672013-11-11 11:09:40 -080027import org.eclipse.jgit.lib.FileMode;
28import org.eclipse.jgit.lib.ObjectId;
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070029import org.eclipse.jgit.lib.Repository;
Dave Borowitz5051e672013-11-11 11:09:40 -080030import org.eclipse.jgit.revwalk.RevTree;
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070031import org.eclipse.jgit.revwalk.RevWalk;
Dave Borowitz5051e672013-11-11 11:09:40 -080032import org.eclipse.jgit.treewalk.TreeWalk;
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070033
34import java.io.IOException;
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070035
36import javax.servlet.ServletException;
37import javax.servlet.http.HttpServletRequest;
38import javax.servlet.http.HttpServletResponse;
39
40public class ArchiveServlet extends BaseServlet {
41 private static final long serialVersionUID = 1L;
42
Dave Borowitzded109a2014-03-03 15:25:39 -050043 public ArchiveServlet(GitilesAccess.Factory accessFactory) {
Dave Borowitz8d6d6872014-03-16 15:18:14 -070044 super(null, accessFactory);
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070045 }
46
47 @Override
48 protected void doGet(HttpServletRequest req, HttpServletResponse res)
49 throws IOException, ServletException {
50 GitilesView view = ViewFilter.getView(req);
51 Revision rev = view.getRevision();
52 Repository repo = ServletUtils.getRepository(req);
53
Dave Borowitz5051e672013-11-11 11:09:40 -080054 ObjectId treeId = getTree(view, repo, rev);
55 if (treeId.equals(ObjectId.zeroId())) {
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070056 res.sendError(SC_NOT_FOUND);
57 return;
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070058 }
59
Han-Wen Nienhuysc0200f62016-05-02 17:34:51 +020060 Optional<ArchiveFormat> format =
61 ArchiveFormat.byExtension(view.getExtension(), getAccess(req).getConfig());
Dave Borowitzded109a2014-03-03 15:25:39 -050062 if (!format.isPresent()) {
63 res.setStatus(SC_NOT_FOUND);
64 return;
65 }
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070066 String filename = getFilename(view, rev, view.getExtension());
Dave Borowitzded109a2014-03-03 15:25:39 -050067 setDownloadHeaders(res, filename, format.get().getMimeType());
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070068 res.setStatus(SC_OK);
69
70 try {
71 new ArchiveCommand(repo)
Dave Borowitz36eb26d2014-04-19 16:42:32 -070072 .setFormat(format.get().getRegisteredName())
Dave Borowitz5051e672013-11-11 11:09:40 -080073 .setTree(treeId)
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070074 .setOutputStream(res.getOutputStream())
75 .call();
76 } catch (GitAPIException e) {
77 throw new IOException(e);
78 }
79 }
80
Dave Borowitz5051e672013-11-11 11:09:40 -080081 private ObjectId getTree(GitilesView view, Repository repo, Revision rev) throws IOException {
Shawn Pearceb5ad0a02015-05-24 20:33:17 -070082 try (RevWalk rw = new RevWalk(repo)) {
Dave Borowitz5051e672013-11-11 11:09:40 -080083 RevTree tree = rw.parseTree(rev.getId());
Dave Borowitzfc417942014-04-09 07:54:42 -070084 if (Strings.isNullOrEmpty(view.getPathPart())) {
Dave Borowitz5051e672013-11-11 11:09:40 -080085 return tree;
86 }
87 TreeWalk tw = TreeWalk.forPath(rw.getObjectReader(), view.getPathPart(), tree);
Dave Borowitzfc417942014-04-09 07:54:42 -070088 if (tw == null || tw.getFileMode(0) != FileMode.TREE) {
Dave Borowitz5051e672013-11-11 11:09:40 -080089 return ObjectId.zeroId();
90 }
91 return tw.getObjectId(0);
92 } catch (IncorrectObjectTypeException e) {
93 return ObjectId.zeroId();
Dave Borowitz5051e672013-11-11 11:09:40 -080094 }
95 }
96
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070097 private String getFilename(GitilesView view, Revision rev, String ext) {
Han-Wen Nienhuysc0200f62016-05-02 17:34:51 +020098 StringBuilder sb =
99 new StringBuilder()
100 .append(PathUtil.basename(view.getRepositoryName()))
101 .append('-')
102 .append(rev.getName());
Dave Borowitz5051e672013-11-11 11:09:40 -0800103 if (view.getPathPart() != null) {
Han-Wen Nienhuysc0200f62016-05-02 17:34:51 +0200104 sb.append('-').append(view.getPathPart().replace('/', '-'));
Dave Borowitz5051e672013-11-11 11:09:40 -0800105 }
Han-Wen Nienhuysc0200f62016-05-02 17:34:51 +0200106 return sb.append(ext).toString();
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -0700107 }
108}