aboutsummaryrefslogtreecommitdiff
path: root/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/CatServlet.java
diff options
context:
space:
mode:
Diffstat (limited to 'gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/CatServlet.java')
-rw-r--r--gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/CatServlet.java78
1 files changed, 53 insertions, 25 deletions
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/CatServlet.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/CatServlet.java
index 3ecfa627..57e0c0ce 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/CatServlet.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/CatServlet.java
@@ -33,14 +33,16 @@ import eu.medsea.mimeutil.MimeType;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.util.NB;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.MessageDigest;
@@ -162,7 +164,7 @@ public class CatServlet extends HttpServlet {
return;
}
- final byte[] blobData;
+ final ObjectLoader blobLoader;
final RevCommit fromCommit;
final String suffix;
final String path = patchKey.getFileName();
@@ -196,7 +198,7 @@ public class CatServlet extends HttpServlet {
}
if (tw.getFileMode(0).getObjectType() == Constants.OBJ_BLOB) {
- blobData = repo.openBlob(tw.getObjectId(0)).getCachedBytes();
+ blobLoader = repo.open(tw.getObjectId(0), Constants.OBJ_BLOB);
} else {
rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
@@ -214,14 +216,20 @@ public class CatServlet extends HttpServlet {
repo.close();
}
+ final byte[] raw =
+ blobLoader.isLarge() ? null : blobLoader.getCachedBytes();
final long when = fromCommit.getCommitTime() * 1000L;
- MimeType contentType = registry.getMimeType(path, blobData);
- final byte[] outData;
- if (registry.isSafeInline(contentType)) {
- outData = blobData;
+ rsp.setDateHeader("Last-Modified", when);
+ rsp.setDateHeader("Expires", 0L);
+ rsp.setHeader("Pragma", "no-cache");
+ rsp.setHeader("Cache-Control", "no-cache, must-revalidate");
- } else {
+ OutputStream out;
+ ZipOutputStream zo;
+
+ final MimeType contentType = registry.getMimeType(path, raw);
+ if (!registry.isSafeInline(contentType)) {
// The content may not be safe to transmit inline, as a browser might
// interpret it as HTML or JavaScript hosted by this site. Such code
// might then run in the site's security domain, and may be able to use
@@ -230,31 +238,51 @@ public class CatServlet extends HttpServlet {
// Usually, wrapping the content into a ZIP file forces the browser to
// save the content to the local system instead.
//
- final ByteArrayOutputStream zip = new ByteArrayOutputStream();
- final ZipOutputStream zo = new ZipOutputStream(zip);
+
+ rsp.setContentType(ZIP.toString());
+ rsp.setHeader("Content-Disposition", "attachment; filename=\""
+ + safeFileName(path, suffix) + ".zip" + "\"");
+
+ zo = new ZipOutputStream(rsp.getOutputStream());
+
final ZipEntry e = new ZipEntry(safeFileName(path, rand(req, suffix)));
e.setComment(fromCommit.name() + ":" + path);
- e.setSize(blobData.length);
+ e.setSize(blobLoader.getSize());
e.setTime(when);
zo.putNextEntry(e);
- zo.write(blobData);
- zo.closeEntry();
- zo.close();
+ out = zo;
- outData = zip.toByteArray();
- contentType = ZIP;
+ } else {
+ rsp.setContentType(contentType.toString());
+ rsp.setHeader("Content-Length", "" + blobLoader.getSize());
- rsp.setHeader("Content-Disposition", "attachment; filename=\""
- + safeFileName(path, suffix) + ".zip" + "\"");
+ out = rsp.getOutputStream();
+ zo = null;
}
- rsp.setContentType(contentType.toString());
- rsp.setContentLength(outData.length);
- rsp.setDateHeader("Last-Modified", when);
- rsp.setDateHeader("Expires", 0L);
- rsp.setHeader("Pragma", "no-cache");
- rsp.setHeader("Cache-Control", "no-cache, must-revalidate");
- rsp.getOutputStream().write(outData);
+ if (raw != null) {
+ out.write(raw);
+ } else {
+ InputStream in = blobLoader.openStream();
+ try {
+ byte[] buf = new byte[8192];
+ for (;;) {
+ int n = in.read(buf);
+ if (0 < n) {
+ out.write(buf, 0, n);
+ } else {
+ break;
+ }
+ }
+ } finally {
+ in.close();
+ }
+ }
+
+ if (zo != null) {
+ zo.closeEntry();
+ }
+ out.close();
}
private static String safeFileName(String fileName, final String suffix) {