Line data Source code
1 : // Copyright (C) 2010 The Android Open Source Project 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.gerrit.httpd.raw; 16 : 17 : import static com.google.gerrit.httpd.HtmlDomUtil.compress; 18 : import static com.google.gerrit.httpd.HtmlDomUtil.newDocument; 19 : import static com.google.gerrit.httpd.HtmlDomUtil.toUTF8; 20 : import static java.nio.charset.StandardCharsets.UTF_8; 21 : import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; 22 : import static org.eclipse.jgit.util.HttpSupport.HDR_CACHE_CONTROL; 23 : import static org.eclipse.jgit.util.HttpSupport.HDR_EXPIRES; 24 : import static org.eclipse.jgit.util.HttpSupport.HDR_PRAGMA; 25 : 26 : import com.google.gerrit.common.Version; 27 : import com.google.gerrit.server.tools.ToolsCatalog; 28 : import com.google.gerrit.util.http.RequestUtil; 29 : import com.google.inject.Inject; 30 : import com.google.inject.Singleton; 31 : import java.io.IOException; 32 : import java.io.OutputStream; 33 : import javax.servlet.http.HttpServlet; 34 : import javax.servlet.http.HttpServletRequest; 35 : import javax.servlet.http.HttpServletResponse; 36 : import org.w3c.dom.Document; 37 : import org.w3c.dom.Element; 38 : 39 : /** Sends the client side tools we keep within our software. */ 40 : @Singleton 41 : public class ToolServlet extends HttpServlet { 42 : private static final long serialVersionUID = 1L; 43 : private final ToolsCatalog toc; 44 : 45 : @Inject 46 99 : ToolServlet(ToolsCatalog toc) { 47 99 : this.toc = toc; 48 99 : } 49 : 50 : @Override 51 : protected void doGet(HttpServletRequest req, HttpServletResponse rsp) throws IOException { 52 0 : ToolsCatalog.Entry ent = toc.get(req.getPathInfo()); 53 0 : if (ent == null) { 54 0 : rsp.sendError(SC_NOT_FOUND); 55 0 : return; 56 : } 57 : 58 0 : switch (ent.getType()) { 59 : case FILE: 60 0 : doGetFile(ent, rsp); 61 0 : break; 62 : 63 : case DIR: 64 0 : doGetDirectory(ent, req, rsp); 65 0 : break; 66 : 67 : default: 68 0 : rsp.sendError(SC_NOT_FOUND); 69 : break; 70 : } 71 0 : } 72 : 73 : private void doGetFile(ToolsCatalog.Entry ent, HttpServletResponse rsp) throws IOException { 74 0 : byte[] tosend = ent.getBytes(); 75 : 76 0 : rsp.setDateHeader(HDR_EXPIRES, 0L); 77 0 : rsp.setHeader(HDR_PRAGMA, "no-cache"); 78 0 : rsp.setHeader(HDR_CACHE_CONTROL, "no-cache, must-revalidate"); 79 0 : rsp.setContentType("application/octet-stream"); 80 0 : rsp.setContentLength(tosend.length); 81 0 : try (OutputStream out = rsp.getOutputStream()) { 82 0 : out.write(tosend); 83 : } 84 0 : } 85 : 86 : private void doGetDirectory( 87 : ToolsCatalog.Entry ent, HttpServletRequest req, HttpServletResponse rsp) throws IOException { 88 0 : String path = "/tools/" + ent.getPath(); 89 0 : Document page = newDocument(); 90 : 91 0 : Element html = page.createElement("html"); 92 0 : Element head = page.createElement("head"); 93 0 : Element title = page.createElement("title"); 94 0 : Element body = page.createElement("body"); 95 : 96 0 : page.appendChild(html); 97 0 : html.appendChild(head); 98 0 : html.appendChild(body); 99 0 : head.appendChild(title); 100 : 101 0 : title.setTextContent("Gerrit Code Review - " + path); 102 : 103 0 : Element h1 = page.createElement("h1"); 104 0 : h1.setTextContent(title.getTextContent()); 105 0 : body.appendChild(h1); 106 : 107 0 : Element ul = page.createElement("ul"); 108 0 : body.appendChild(ul); 109 : 110 0 : for (ToolsCatalog.Entry e : ent.getChildren()) { 111 0 : String name = e.getName(); 112 0 : if (e.getType() == ToolsCatalog.Entry.Type.DIR && !name.endsWith("/")) { 113 0 : name += "/"; 114 : } 115 : 116 0 : Element li = page.createElement("li"); 117 0 : Element a = page.createElement("a"); 118 0 : a.setAttribute("href", name); 119 0 : a.setTextContent(name); 120 0 : li.appendChild(a); 121 0 : ul.appendChild(li); 122 0 : } 123 : 124 0 : body.appendChild(page.createElement("hr")); 125 : 126 0 : Element footer = page.createElement("p"); 127 0 : footer.setAttribute("style", "text-align: right; font-style: italic"); 128 0 : footer.setTextContent("Powered by Gerrit Code Review " + Version.getVersion()); 129 0 : body.appendChild(footer); 130 : 131 0 : byte[] tosend = toUTF8(page); 132 0 : if (RequestUtil.acceptsGzipEncoding(req)) { 133 0 : rsp.setHeader("Content-Encoding", "gzip"); 134 0 : tosend = compress(tosend); 135 : } 136 : 137 0 : rsp.setDateHeader(HDR_EXPIRES, 0L); 138 0 : rsp.setHeader(HDR_PRAGMA, "no-cache"); 139 0 : rsp.setHeader(HDR_CACHE_CONTROL, "no-cache, must-revalidate"); 140 0 : rsp.setContentType("text/html"); 141 0 : rsp.setCharacterEncoding(UTF_8.name()); 142 0 : rsp.setContentLength(tosend.length); 143 0 : try (OutputStream out = rsp.getOutputStream()) { 144 0 : out.write(tosend); 145 : } 146 0 : } 147 : }