| Dave Borowitz | 6d9bc5a | 2013-06-19 09:12:52 -0700 | [diff] [blame] | 1 | // 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 | |
| 15 | package com.google.gitiles; |
| 16 | |
| 17 | import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; |
| 18 | import static javax.servlet.http.HttpServletResponse.SC_OK; |
| 19 | |
| Dave Borowitz | ded109a | 2014-03-03 15:25:39 -0500 | [diff] [blame] | 20 | import com.google.common.base.Optional; |
| Dave Borowitz | fc41794 | 2014-04-09 07:54:42 -0700 | [diff] [blame] | 21 | import com.google.common.base.Strings; |
| Dave Borowitz | ded109a | 2014-03-03 15:25:39 -0500 | [diff] [blame] | 22 | |
| Dave Borowitz | 6d9bc5a | 2013-06-19 09:12:52 -0700 | [diff] [blame] | 23 | import org.eclipse.jgit.api.ArchiveCommand; |
| 24 | import org.eclipse.jgit.api.errors.GitAPIException; |
| Dave Borowitz | 6d9bc5a | 2013-06-19 09:12:52 -0700 | [diff] [blame] | 25 | import org.eclipse.jgit.errors.IncorrectObjectTypeException; |
| 26 | import org.eclipse.jgit.http.server.ServletUtils; |
| Dave Borowitz | 5051e67 | 2013-11-11 11:09:40 -0800 | [diff] [blame] | 27 | import org.eclipse.jgit.lib.FileMode; |
| 28 | import org.eclipse.jgit.lib.ObjectId; |
| Dave Borowitz | 6d9bc5a | 2013-06-19 09:12:52 -0700 | [diff] [blame] | 29 | import org.eclipse.jgit.lib.Repository; |
| Dave Borowitz | 5051e67 | 2013-11-11 11:09:40 -0800 | [diff] [blame] | 30 | import org.eclipse.jgit.revwalk.RevTree; |
| Dave Borowitz | 6d9bc5a | 2013-06-19 09:12:52 -0700 | [diff] [blame] | 31 | import org.eclipse.jgit.revwalk.RevWalk; |
| Dave Borowitz | 5051e67 | 2013-11-11 11:09:40 -0800 | [diff] [blame] | 32 | import org.eclipse.jgit.treewalk.TreeWalk; |
| Dave Borowitz | 6d9bc5a | 2013-06-19 09:12:52 -0700 | [diff] [blame] | 33 | |
| 34 | import java.io.IOException; |
| Dave Borowitz | 6d9bc5a | 2013-06-19 09:12:52 -0700 | [diff] [blame] | 35 | |
| 36 | import javax.servlet.ServletException; |
| 37 | import javax.servlet.http.HttpServletRequest; |
| 38 | import javax.servlet.http.HttpServletResponse; |
| 39 | |
| 40 | public class ArchiveServlet extends BaseServlet { |
| 41 | private static final long serialVersionUID = 1L; |
| 42 | |
| Dave Borowitz | ded109a | 2014-03-03 15:25:39 -0500 | [diff] [blame] | 43 | public ArchiveServlet(GitilesAccess.Factory accessFactory) { |
| Dave Borowitz | 8d6d687 | 2014-03-16 15:18:14 -0700 | [diff] [blame] | 44 | super(null, accessFactory); |
| Dave Borowitz | 6d9bc5a | 2013-06-19 09:12:52 -0700 | [diff] [blame] | 45 | } |
| 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 Borowitz | 5051e67 | 2013-11-11 11:09:40 -0800 | [diff] [blame] | 54 | ObjectId treeId = getTree(view, repo, rev); |
| 55 | if (treeId.equals(ObjectId.zeroId())) { |
| Dave Borowitz | 6d9bc5a | 2013-06-19 09:12:52 -0700 | [diff] [blame] | 56 | res.sendError(SC_NOT_FOUND); |
| 57 | return; |
| Dave Borowitz | 6d9bc5a | 2013-06-19 09:12:52 -0700 | [diff] [blame] | 58 | } |
| 59 | |
| Han-Wen Nienhuys | c0200f6 | 2016-05-02 17:34:51 +0200 | [diff] [blame] | 60 | Optional<ArchiveFormat> format = |
| 61 | ArchiveFormat.byExtension(view.getExtension(), getAccess(req).getConfig()); |
| Dave Borowitz | ded109a | 2014-03-03 15:25:39 -0500 | [diff] [blame] | 62 | if (!format.isPresent()) { |
| 63 | res.setStatus(SC_NOT_FOUND); |
| 64 | return; |
| 65 | } |
| Dave Borowitz | 6d9bc5a | 2013-06-19 09:12:52 -0700 | [diff] [blame] | 66 | String filename = getFilename(view, rev, view.getExtension()); |
| Dave Borowitz | ded109a | 2014-03-03 15:25:39 -0500 | [diff] [blame] | 67 | setDownloadHeaders(res, filename, format.get().getMimeType()); |
| Dave Borowitz | 6d9bc5a | 2013-06-19 09:12:52 -0700 | [diff] [blame] | 68 | res.setStatus(SC_OK); |
| 69 | |
| 70 | try { |
| 71 | new ArchiveCommand(repo) |
| Dave Borowitz | 36eb26d | 2014-04-19 16:42:32 -0700 | [diff] [blame] | 72 | .setFormat(format.get().getRegisteredName()) |
| Dave Borowitz | 5051e67 | 2013-11-11 11:09:40 -0800 | [diff] [blame] | 73 | .setTree(treeId) |
| Dave Borowitz | 6d9bc5a | 2013-06-19 09:12:52 -0700 | [diff] [blame] | 74 | .setOutputStream(res.getOutputStream()) |
| 75 | .call(); |
| 76 | } catch (GitAPIException e) { |
| 77 | throw new IOException(e); |
| 78 | } |
| 79 | } |
| 80 | |
| Dave Borowitz | 5051e67 | 2013-11-11 11:09:40 -0800 | [diff] [blame] | 81 | private ObjectId getTree(GitilesView view, Repository repo, Revision rev) throws IOException { |
| Shawn Pearce | b5ad0a0 | 2015-05-24 20:33:17 -0700 | [diff] [blame] | 82 | try (RevWalk rw = new RevWalk(repo)) { |
| Dave Borowitz | 5051e67 | 2013-11-11 11:09:40 -0800 | [diff] [blame] | 83 | RevTree tree = rw.parseTree(rev.getId()); |
| Dave Borowitz | fc41794 | 2014-04-09 07:54:42 -0700 | [diff] [blame] | 84 | if (Strings.isNullOrEmpty(view.getPathPart())) { |
| Dave Borowitz | 5051e67 | 2013-11-11 11:09:40 -0800 | [diff] [blame] | 85 | return tree; |
| 86 | } |
| 87 | TreeWalk tw = TreeWalk.forPath(rw.getObjectReader(), view.getPathPart(), tree); |
| Dave Borowitz | fc41794 | 2014-04-09 07:54:42 -0700 | [diff] [blame] | 88 | if (tw == null || tw.getFileMode(0) != FileMode.TREE) { |
| Dave Borowitz | 5051e67 | 2013-11-11 11:09:40 -0800 | [diff] [blame] | 89 | return ObjectId.zeroId(); |
| 90 | } |
| 91 | return tw.getObjectId(0); |
| 92 | } catch (IncorrectObjectTypeException e) { |
| 93 | return ObjectId.zeroId(); |
| Dave Borowitz | 5051e67 | 2013-11-11 11:09:40 -0800 | [diff] [blame] | 94 | } |
| 95 | } |
| 96 | |
| Dave Borowitz | 6d9bc5a | 2013-06-19 09:12:52 -0700 | [diff] [blame] | 97 | private String getFilename(GitilesView view, Revision rev, String ext) { |
| Han-Wen Nienhuys | c0200f6 | 2016-05-02 17:34:51 +0200 | [diff] [blame] | 98 | StringBuilder sb = |
| 99 | new StringBuilder() |
| 100 | .append(PathUtil.basename(view.getRepositoryName())) |
| 101 | .append('-') |
| 102 | .append(rev.getName()); |
| Dave Borowitz | 5051e67 | 2013-11-11 11:09:40 -0800 | [diff] [blame] | 103 | if (view.getPathPart() != null) { |
| Han-Wen Nienhuys | c0200f6 | 2016-05-02 17:34:51 +0200 | [diff] [blame] | 104 | sb.append('-').append(view.getPathPart().replace('/', '-')); |
| Dave Borowitz | 5051e67 | 2013-11-11 11:09:40 -0800 | [diff] [blame] | 105 | } |
| Han-Wen Nienhuys | c0200f6 | 2016-05-02 17:34:51 +0200 | [diff] [blame] | 106 | return sb.append(ext).toString(); |
| Dave Borowitz | 6d9bc5a | 2013-06-19 09:12:52 -0700 | [diff] [blame] | 107 | } |
| 108 | } |