xref: /OpenGrok/opengrok-web/src/main/java/org/opengrok/web/GetFile.java (revision aa6abf429bacc2c0baa482bff3022e77ef23c183)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * See LICENSE.txt included in this distribution for the specific
9  * language governing permissions and limitations under the License.
10  *
11  * When distributing Covered Code, include this CDDL HEADER in each
12  * file and include the License file at LICENSE.txt.
13  * If applicable, add the following below this CDDL HEADER, with the
14  * fields enclosed by brackets "[]" replaced with your own identifying
15  * information: Portions Copyright [yyyy] [name of copyright owner]
16  *
17  * CDDL HEADER END
18  */
19 
20 /*
21  * Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
22  * Portions Copyright (c) 2020, Chris Fraire <cfraire@me.com>.
23  * Portions Copyright (c) 2011, Jens Elkner.
24  */
25 package org.opengrok.web;
26 
27 import java.io.File;
28 import java.io.FileInputStream;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.OutputStream;
32 
33 import jakarta.servlet.http.HttpServlet;
34 import jakarta.servlet.http.HttpServletRequest;
35 import jakarta.servlet.http.HttpServletResponse;
36 import org.opengrok.indexer.history.HistoryGuru;
37 import org.opengrok.indexer.web.Prefix;
38 
39 public class GetFile extends HttpServlet {
40 
41     public static final long serialVersionUID = -1;
42 
43     @Override
service(final HttpServletRequest request, final HttpServletResponse response)44     protected void service(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
45         PageConfig cfg = PageConfig.get(request);
46         cfg.checkSourceRootExistence();
47 
48         String redir = cfg.canProcess();
49         if (redir == null || redir.length() > 0) {
50             if (redir != null) {
51                 response.sendRedirect(redir);
52             } else {
53                 response.sendError(HttpServletResponse.SC_NOT_FOUND);
54             }
55             return;
56         }
57 
58         File f = cfg.getResourceFile();
59         String revision = cfg.getRequestedRevision();
60         if (revision.length() == 0) {
61             revision = null;
62         }
63 
64         InputStream in;
65         try {
66             if (revision != null) {
67                 in = HistoryGuru.getInstance().getRevision(f.getParent(),
68                         f.getName(), revision);
69             } else {
70                 long flast = cfg.getLastModified();
71                 if (request.getDateHeader("If-Modified-Since") >= flast) {
72                     response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
73                     return;
74                 }
75                 response.setContentLength((int) f.length());
76                 response.setDateHeader("Last-Modified", f.lastModified());
77                 in = new FileInputStream(f);
78             }
79         } catch (Exception e) {
80             response.sendError(HttpServletResponse.SC_NOT_FOUND);
81             return;
82         }
83 
84         try {
85             String mimeType = getServletContext().getMimeType(f.getAbsolutePath());
86             response.setContentType(mimeType);
87 
88             if (cfg.getPrefix() == Prefix.DOWNLOAD_P) {
89                 response.setHeader("content-disposition", "attachment; filename="
90                         + f.getName());
91             } else {
92                 response.setHeader("content-type", "text/plain");
93             }
94             OutputStream o = response.getOutputStream();
95             byte[] buffer = new byte[8192];
96             int nr;
97             while ((nr = in.read(buffer)) > 0) {
98                 o.write(buffer, 0, nr);
99             }
100             o.flush();
101             o.close();
102         } finally {
103             in.close();
104         }
105     }
106 }