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.internal.storage.dfs.DfsRepository;
68 import org.eclipse.jgit.lib.Constants;
69 import org.eclipse.jgit.lib.ObjectId;
70 import org.eclipse.jgit.lib.Repository;
71
72
73
74
75 public final class ServletUtils {
76
77 public static final String ATTRIBUTE_REPOSITORY = "org.eclipse.jgit.Repository";
78
79
80 public static final String ATTRIBUTE_HANDLER = "org.eclipse.jgit.transport.UploadPackOrReceivePack";
81
82
83
84
85
86
87
88
89
90
91
92
93
94 public static Repository getRepository(ServletRequest req) {
95 Repository db = (Repository) req.getAttribute(ATTRIBUTE_REPOSITORY);
96 if (db == null)
97 throw new IllegalStateException(HttpServerText.get().expectedRepositoryAttribute);
98 return db;
99 }
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114 public static InputStream getInputStream(HttpServletRequest req)
115 throws IOException {
116 InputStream in = req.getInputStream();
117 final String enc = req.getHeader(HDR_CONTENT_ENCODING);
118 if (ENCODING_GZIP.equals(enc) || ENCODING_X_GZIP.equals(enc))
119 in = new GZIPInputStream(in);
120 else if (enc != null)
121 throw new IOException(MessageFormat.format(HttpServerText.get().encodingNotSupportedByThisLibrary
122 , HDR_CONTENT_ENCODING, enc));
123 return in;
124 }
125
126
127
128
129
130
131
132 public static void consumeRequestBody(HttpServletRequest req) {
133 if (0 < req.getContentLength() || isChunked(req)) {
134 try {
135 consumeRequestBody(req.getInputStream());
136 } catch (IOException e) {
137
138 }
139 }
140 }
141
142 static boolean isChunked(HttpServletRequest req) {
143 return "chunked".equals(req.getHeader("Transfer-Encoding"));
144 }
145
146
147
148
149
150
151
152 public static void consumeRequestBody(InputStream in) {
153 if (in == null)
154 return;
155 try {
156 while (0 < in.skip(2048) || 0 <= in.read()) {
157
158 }
159 } catch (IOException err) {
160
161 } finally {
162 try {
163 in.close();
164 } catch (IOException err) {
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
192 public static void sendPlainText(final String content,
193 final HttpServletRequest req, final HttpServletResponse rsp)
194 throws IOException {
195 final byte[] raw = content.getBytes(UTF_8);
196 rsp.setContentType(TEXT_PLAIN);
197 rsp.setCharacterEncoding(UTF_8.name());
198 send(raw, req, rsp);
199 }
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221 public static void send(byte[] content, final HttpServletRequest req,
222 final HttpServletResponse rsp) throws IOException {
223 content = sendInit(content, req, rsp);
224 try (OutputStream out = rsp.getOutputStream()) {
225 out.write(content);
226 out.flush();
227 }
228 }
229
230 private static byte[] sendInit(byte[] content,
231 final HttpServletRequest req, final HttpServletResponse rsp)
232 throws IOException {
233 rsp.setHeader(HDR_ETAG, etag(content));
234 if (256 < content.length && acceptsGzipEncoding(req)) {
235 content = compress(content);
236 rsp.setHeader(HDR_CONTENT_ENCODING, ENCODING_GZIP);
237 }
238 rsp.setContentLength(content.length);
239 return content;
240 }
241
242 static boolean acceptsGzipEncoding(HttpServletRequest req) {
243 return acceptsGzipEncoding(req.getHeader(HDR_ACCEPT_ENCODING));
244 }
245
246 static boolean acceptsGzipEncoding(String accepts) {
247 if (accepts == null)
248 return false;
249
250 int b = 0;
251 while (b < accepts.length()) {
252 int comma = accepts.indexOf(',', b);
253 int e = 0 <= comma ? comma : accepts.length();
254 String term = accepts.substring(b, e).trim();
255 if (term.equals(ENCODING_GZIP))
256 return true;
257 b = e + 1;
258 }
259 return false;
260 }
261
262 private static byte[] compress(byte[] raw) throws IOException {
263 final int maxLen = raw.length + 32;
264 final ByteArrayOutputStream out = new ByteArrayOutputStream(maxLen);
265 final GZIPOutputStream gz = new GZIPOutputStream(out);
266 gz.write(raw);
267 gz.finish();
268 gz.flush();
269 return out.toByteArray();
270 }
271
272 private static String etag(byte[] content) {
273 final MessageDigest md = Constants.newMessageDigest();
274 md.update(content);
275 return ObjectId.fromRaw(md.digest()).getName();
276 }
277
278 static String identify(Repository git) {
279 if (git instanceof DfsRepository) {
280 return ((DfsRepository) git).getDescription().getRepositoryName();
281 } else if (git.getDirectory() != null) {
282 return git.getDirectory().getPath();
283 }
284 return "unknown";
285 }
286
287 private ServletUtils() {
288
289 }
290 }