@Override protected void doGetHtml(HttpServletRequest req, HttpServletResponse res) throws IOException { MarkdownConfig cfg = MarkdownConfig.get(getAccess(req).getConfig()); if (!cfg.render) { res.setStatus(SC_NOT_FOUND); return; } GitilesView view = ViewFilter.getView(req); Repository repo = ServletUtils.getRepository(req); try (RevWalk rw = new RevWalk(repo)) { ObjectReader reader = rw.getObjectReader(); String path = view.getPathPart(); RevTree root; try { root = rw.parseTree(view.getRevision().getId()); } catch (IncorrectObjectTypeException e) { res.setStatus(SC_NOT_FOUND); return; } MarkdownFile srcmd = findFile(rw, root, path); if (srcmd == null) { res.setStatus(SC_NOT_FOUND); return; } MarkdownFile navmd = findFile(rw, root, NAVBAR_MD); String curEtag = etag(srcmd, navmd); if (etagMatch(req, curEtag)) { res.setStatus(SC_NOT_MODIFIED); return; } view = view.toBuilder().setPathPart(srcmd.path).build(); try { srcmd.read(reader, cfg); if (navmd != null) { navmd.read(reader, cfg); } } catch (LargeObjectException.ExceedsLimit errBig) { fileTooBig(res, view, errBig); return; } catch (IOException err) { readError(res, view, err); return; } MarkdownToHtml.Builder fmt = MarkdownToHtml.builder() .setConfig(cfg) .setGitilesView(view) .setRequestUri(req.getRequestURI()) .setReader(reader) .setRootTree(root); res.setHeader(HttpHeaders.ETAG, curEtag); showDoc(req, res, view, cfg, fmt, navmd, srcmd); } }
private static void readError(HttpServletResponse res, GitilesView view, IOException err) { log.error( String.format( "cannot load markdown %s/%s %s %s", view.getHostName(), view.getRepositoryName(), view.getRevision(), view.getPathPart()), err); res.setStatus(SC_INTERNAL_SERVER_ERROR); }
private void showDoc( HttpServletRequest req, HttpServletResponse res, GitilesView view, MarkdownConfig cfg, MarkdownToHtml.Builder fmt, MarkdownFile navFile, MarkdownFile srcFile) throws IOException { Map<String, Object> data = new HashMap<>(); Navbar navbar = new Navbar(); if (navFile != null) { navbar.setFormatter(fmt.setFilePath(navFile.path).build()); navbar.setMarkdown(navFile.content); } data.putAll(navbar.toSoyData()); Node doc = GitilesMarkdown.parse(srcFile.content); data.put("pageTitle", pageTitle(doc, srcFile)); if (view.getType() != GitilesView.Type.ROOTED_DOC) { data.put("sourceUrl", GitilesView.show().copyFrom(view).toUrl()); data.put("logUrl", GitilesView.log().copyFrom(view).toUrl()); data.put("blameUrl", GitilesView.blame().copyFrom(view).toUrl()); } if (cfg.analyticsId != null) { data.put("analyticsId", cfg.analyticsId); } data.put("bodyHtml", fmt.setFilePath(srcFile.path).build().toSoyHtml(doc)); String page = renderer.render(SOY_TEMPLATE, data); byte[] raw = page.getBytes(UTF_8); res.setContentType(FormatType.HTML.getMimeType()); res.setCharacterEncoding(UTF_8.name()); setCacheHeaders(res); if (acceptsGzipEncoding(req)) { res.addHeader(HttpHeaders.VARY, HttpHeaders.ACCEPT_ENCODING); res.setHeader(HttpHeaders.CONTENT_ENCODING, "gzip"); raw = gzip(raw); } res.setContentLength(raw.length); res.setStatus(HttpServletResponse.SC_OK); res.getOutputStream().write(raw); }
private static void fileTooBig( HttpServletResponse res, GitilesView view, LargeObjectException.ExceedsLimit errBig) throws IOException { if (view.getType() == GitilesView.Type.ROOTED_DOC) { log.error( String.format( "markdown too large: %s/%s %s %s: %s", view.getHostName(), view.getRepositoryName(), view.getRevision(), view.getPathPart(), errBig.getMessage())); res.setStatus(SC_INTERNAL_SERVER_ERROR); } else { res.sendRedirect(GitilesView.show().copyFrom(view).toUrl()); } }