// Copyright (C) 2010 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.gerrit.httpd.raw; import static com.google.gerrit.httpd.HtmlDomUtil.compress; import static com.google.gerrit.httpd.HtmlDomUtil.newDocument; import static com.google.gerrit.httpd.HtmlDomUtil.toUTF8; import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; import static org.eclipse.jgit.util.HttpSupport.HDR_CACHE_CONTROL; import static org.eclipse.jgit.util.HttpSupport.HDR_EXPIRES; import static org.eclipse.jgit.util.HttpSupport.HDR_PRAGMA; import com.google.gerrit.common.Version; import com.google.gerrit.server.tools.ToolsCatalog; import com.google.gerrit.server.tools.ToolsCatalog.Entry; import com.google.gwtjsonrpc.server.RPCServletUtils; import com.google.inject.Inject; import com.google.inject.Singleton; import org.w3c.dom.Document; import org.w3c.dom.Element; import java.io.IOException; import java.io.OutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** Sends the client side tools we keep within our software. */ @Singleton public class ToolServlet extends HttpServlet { private static final long serialVersionUID = 1L; private final ToolsCatalog toc; @Inject ToolServlet(ToolsCatalog toc) { this.toc = toc; } @Override protected void doGet(HttpServletRequest req, HttpServletResponse rsp) throws IOException { Entry ent = toc.get(req.getPathInfo()); if (ent == null) { rsp.sendError(SC_NOT_FOUND); return; } switch (ent.getType()) { case FILE: doGetFile(ent, req, rsp); break; case DIR: doGetDirectory(ent, req, rsp); break; default: rsp.sendError(SC_NOT_FOUND); break; } } private void doGetFile(Entry ent, HttpServletRequest req, HttpServletResponse rsp) throws IOException { byte[] tosend = ent.getBytes(); rsp.setDateHeader(HDR_EXPIRES, 0L); rsp.setHeader(HDR_PRAGMA, "no-cache"); rsp.setHeader(HDR_CACHE_CONTROL, "no-cache, must-revalidate"); rsp.setContentType("application/octet-stream"); rsp.setContentLength(tosend.length); final OutputStream out = rsp.getOutputStream(); try { out.write(tosend); } finally { out.close(); } } private void doGetDirectory(Entry ent, HttpServletRequest req, HttpServletResponse rsp) throws IOException { String path = "/tools/" + ent.getPath(); Document page = newDocument(); Element html = page.createElement("html"); Element head = page.createElement("head"); Element title = page.createElement("title"); Element body = page.createElement("body"); page.appendChild(html); html.appendChild(head); html.appendChild(body); head.appendChild(title); title.setTextContent("Gerrit Code Review - " + path); Element h1 = page.createElement("h1"); h1.setTextContent(title.getTextContent()); body.appendChild(h1); Element ul = page.createElement("ul"); body.appendChild(ul); for (Entry e : ent.getChildren()) { String name = e.getName(); if (e.getType() == Entry.Type.DIR && !name.endsWith("/")) { name += "/"; } Element li = page.createElement("li"); Element a = page.createElement("a"); a.setAttribute("href", name); a.setTextContent(name); li.appendChild(a); ul.appendChild(li); } body.appendChild(page.createElement("hr")); Element footer = page.createElement("p"); footer.setAttribute("style", "text-align: right; font-style: italic"); footer.setTextContent("Powered by Gerrit Code Review " + Version.getVersion()); body.appendChild(footer); byte[] tosend = toUTF8(page); if (RPCServletUtils.acceptsGzipEncoding(req)) { rsp.setHeader("Content-Encoding", "gzip"); tosend = compress(tosend); } rsp.setDateHeader(HDR_EXPIRES, 0L); rsp.setHeader(HDR_PRAGMA, "no-cache"); rsp.setHeader(HDR_CACHE_CONTROL, "no-cache, must-revalidate"); rsp.setContentType("text/html"); rsp.setCharacterEncoding("UTF-8"); rsp.setContentLength(tosend.length); final OutputStream out = rsp.getOutputStream(); try { out.write(tosend); } finally { out.close(); } } }