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