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