1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.http.server;
12
13 import static org.eclipse.jgit.http.server.ServletUtils.acceptsGzipEncoding;
14 import static org.eclipse.jgit.util.HttpSupport.ENCODING_GZIP;
15 import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_ENCODING;
16
17 import java.io.IOException;
18 import java.io.OutputStream;
19 import java.util.zip.GZIPOutputStream;
20
21 import javax.servlet.http.HttpServletRequest;
22 import javax.servlet.http.HttpServletResponse;
23
24 import org.eclipse.jgit.util.TemporaryBuffer;
25
26
27
28
29
30
31
32
33
34
35
36 class SmartOutputStream extends TemporaryBuffer {
37 private static final int LIMIT = 32 * 1024;
38
39 private final HttpServletRequest req;
40 private final HttpServletResponse rsp;
41 private boolean compressStream;
42 private boolean startedOutput;
43
44 SmartOutputStream(final HttpServletRequest req,
45 final HttpServletResponse rsp,
46 boolean compressStream) {
47 super(LIMIT);
48 this.req = req;
49 this.rsp = rsp;
50 this.compressStream = compressStream;
51 }
52
53
54 @Override
55 protected OutputStream overflow() throws IOException {
56 startedOutput = true;
57
58 OutputStream out = rsp.getOutputStream();
59 if (compressStream && acceptsGzipEncoding(req)) {
60 rsp.setHeader(HDR_CONTENT_ENCODING, ENCODING_GZIP);
61 out = new GZIPOutputStream(out);
62 }
63 return out;
64 }
65
66
67 @Override
68 public void close() throws IOException {
69 super.close();
70
71 if (!startedOutput) {
72
73
74
75 if (256 < this.length() && acceptsGzipEncoding(req)) {
76 TemporaryBuffer gzbuf = new TemporaryBuffer.Heap(LIMIT);
77 try {
78 try (GZIPOutputStream gzip = new GZIPOutputStream(gzbuf)) {
79 this.writeTo(gzip, null);
80 }
81 if (gzbuf.length() < this.length()) {
82 rsp.setHeader(HDR_CONTENT_ENCODING, ENCODING_GZIP);
83 writeResponse(gzbuf);
84 return;
85 }
86 } catch (IOException err) {
87
88
89
90 }
91 }
92 writeResponse(this);
93 }
94 }
95
96 private void writeResponse(TemporaryBuffer out) throws IOException {
97
98
99
100 rsp.setContentLength((int) out.length());
101 try (OutputStream os = rsp.getOutputStream()) {
102 out.writeTo(os, null);
103 os.flush();
104 }
105 }
106 }