1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.http.server;
12
13 import static java.nio.charset.StandardCharsets.UTF_8;
14 import static org.eclipse.jgit.util.HttpSupport.ENCODING_GZIP;
15 import static org.eclipse.jgit.util.HttpSupport.ENCODING_X_GZIP;
16 import static org.eclipse.jgit.util.HttpSupport.HDR_ACCEPT_ENCODING;
17 import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_ENCODING;
18 import static org.eclipse.jgit.util.HttpSupport.HDR_ETAG;
19 import static org.eclipse.jgit.util.HttpSupport.TEXT_PLAIN;
20
21 import java.io.ByteArrayOutputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.OutputStream;
25 import java.security.MessageDigest;
26 import java.text.MessageFormat;
27 import java.util.zip.GZIPInputStream;
28 import java.util.zip.GZIPOutputStream;
29
30 import javax.servlet.ServletRequest;
31 import javax.servlet.http.HttpServletRequest;
32 import javax.servlet.http.HttpServletResponse;
33
34 import org.eclipse.jgit.lib.Constants;
35 import org.eclipse.jgit.lib.ObjectId;
36 import org.eclipse.jgit.lib.Repository;
37
38
39
40
41 public final class ServletUtils {
42
43 public static final String ATTRIBUTE_REPOSITORY = "org.eclipse.jgit.Repository";
44
45
46 public static final String ATTRIBUTE_HANDLER = "org.eclipse.jgit.transport.UploadPackOrReceivePack";
47
48
49
50
51
52
53
54
55
56
57
58
59
60 public static Repository getRepository(ServletRequest req) {
61 Repository db = (Repository) req.getAttribute(ATTRIBUTE_REPOSITORY);
62 if (db == null)
63 throw new IllegalStateException(HttpServerText.get().expectedRepositoryAttribute);
64 return db;
65 }
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 public static InputStream getInputStream(HttpServletRequest req)
81 throws IOException {
82 InputStream in = req.getInputStream();
83 final String enc = req.getHeader(HDR_CONTENT_ENCODING);
84 if (ENCODING_GZIP.equals(enc) || ENCODING_X_GZIP.equals(enc))
85 in = new GZIPInputStream(in);
86 else if (enc != null)
87 throw new IOException(MessageFormat.format(HttpServerText.get().encodingNotSupportedByThisLibrary
88 , HDR_CONTENT_ENCODING, enc));
89 return in;
90 }
91
92
93
94
95
96
97
98 public static void consumeRequestBody(HttpServletRequest req) {
99 if (0 < req.getContentLength() || isChunked(req)) {
100 try {
101 consumeRequestBody(req.getInputStream());
102 } catch (IOException e) {
103
104 }
105 }
106 }
107
108 static boolean isChunked(HttpServletRequest req) {
109 return "chunked".equals(req.getHeader("Transfer-Encoding"));
110 }
111
112
113
114
115
116
117
118 public static void consumeRequestBody(InputStream in) {
119 if (in == null)
120 return;
121 try {
122 while (0 < in.skip(2048) || 0 <= in.read()) {
123
124 }
125 } catch (IOException err) {
126
127 } finally {
128 try {
129 in.close();
130 } catch (IOException err) {
131
132 }
133 }
134 }
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158 public static void sendPlainText(final String content,
159 final HttpServletRequest req, final HttpServletResponse rsp)
160 throws IOException {
161 final byte[] raw = content.getBytes(UTF_8);
162 rsp.setContentType(TEXT_PLAIN);
163 rsp.setCharacterEncoding(UTF_8.name());
164 send(raw, req, rsp);
165 }
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187 public static void send(byte[] content, final HttpServletRequest req,
188 final HttpServletResponse rsp) throws IOException {
189 content = sendInit(content, req, rsp);
190 try (OutputStream out = rsp.getOutputStream()) {
191 out.write(content);
192 out.flush();
193 }
194 }
195
196 private static byte[] sendInit(byte[] content,
197 final HttpServletRequest req, final HttpServletResponse rsp)
198 throws IOException {
199 rsp.setHeader(HDR_ETAG, etag(content));
200 if (256 < content.length && acceptsGzipEncoding(req)) {
201 content = compress(content);
202 rsp.setHeader(HDR_CONTENT_ENCODING, ENCODING_GZIP);
203 }
204 rsp.setContentLength(content.length);
205 return content;
206 }
207
208 static boolean acceptsGzipEncoding(HttpServletRequest req) {
209 return acceptsGzipEncoding(req.getHeader(HDR_ACCEPT_ENCODING));
210 }
211
212 static boolean acceptsGzipEncoding(String accepts) {
213 if (accepts == null)
214 return false;
215
216 int b = 0;
217 while (b < accepts.length()) {
218 int comma = accepts.indexOf(',', b);
219 int e = 0 <= comma ? comma : accepts.length();
220 String term = accepts.substring(b, e).trim();
221 if (term.equals(ENCODING_GZIP))
222 return true;
223 b = e + 1;
224 }
225 return false;
226 }
227
228 private static byte[] compress(byte[] raw) throws IOException {
229 final int maxLen = raw.length + 32;
230 final ByteArrayOutputStream out = new ByteArrayOutputStream(maxLen);
231 final GZIPOutputStream gz = new GZIPOutputStream(out);
232 gz.write(raw);
233 gz.finish();
234 gz.flush();
235 return out.toByteArray();
236 }
237
238 private static String etag(byte[] content) {
239 final MessageDigest md = Constants.newMessageDigest();
240 md.update(content);
241 return ObjectId.fromRaw(md.digest()).getName();
242 }
243
244 static String identify(Repository git) {
245 String identifier = git.getIdentifier();
246 if (identifier == null) {
247 return "unknown";
248 }
249 return identifier;
250 }
251
252 private ServletUtils() {
253
254 }
255 }