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 org.eclipse.jgit.util.HttpSupport.ENCODING_GZIP;
47 import static org.eclipse.jgit.util.HttpSupport.ENCODING_X_GZIP;
48 import static org.eclipse.jgit.util.HttpSupport.HDR_ACCEPT_ENCODING;
49 import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_ENCODING;
50 import static org.eclipse.jgit.util.HttpSupport.HDR_ETAG;
51 import static org.eclipse.jgit.util.HttpSupport.TEXT_PLAIN;
52
53 import java.io.ByteArrayOutputStream;
54 import java.io.IOException;
55 import java.io.InputStream;
56 import java.io.OutputStream;
57 import java.security.MessageDigest;
58 import java.text.MessageFormat;
59 import java.util.zip.GZIPInputStream;
60 import java.util.zip.GZIPOutputStream;
61
62 import javax.servlet.ServletRequest;
63 import javax.servlet.http.HttpServletRequest;
64 import javax.servlet.http.HttpServletResponse;
65
66 import org.eclipse.jgit.internal.storage.dfs.DfsRepository;
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(final 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(final 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(Constants.CHARACTER_ENCODING);
195 rsp.setContentType(TEXT_PLAIN);
196 rsp.setCharacterEncoding(Constants.CHARACTER_ENCODING);
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 final OutputStream out = rsp.getOutputStream();
224 try {
225 out.write(content);
226 out.flush();
227 } finally {
228 out.close();
229 }
230 }
231
232 private static byte[] sendInit(byte[] content,
233 final HttpServletRequest req, final HttpServletResponse rsp)
234 throws IOException {
235 rsp.setHeader(HDR_ETAG, etag(content));
236 if (256 < content.length && acceptsGzipEncoding(req)) {
237 content = compress(content);
238 rsp.setHeader(HDR_CONTENT_ENCODING, ENCODING_GZIP);
239 }
240 rsp.setContentLength(content.length);
241 return content;
242 }
243
244 static boolean acceptsGzipEncoding(final HttpServletRequest req) {
245 return acceptsGzipEncoding(req.getHeader(HDR_ACCEPT_ENCODING));
246 }
247
248 static boolean acceptsGzipEncoding(String accepts) {
249 if (accepts == null)
250 return false;
251
252 int b = 0;
253 while (b < accepts.length()) {
254 int comma = accepts.indexOf(',', b);
255 int e = 0 <= comma ? comma : accepts.length();
256 String term = accepts.substring(b, e).trim();
257 if (term.equals(ENCODING_GZIP))
258 return true;
259 b = e + 1;
260 }
261 return false;
262 }
263
264 private static byte[] compress(final byte[] raw) throws IOException {
265 final int maxLen = raw.length + 32;
266 final ByteArrayOutputStream out = new ByteArrayOutputStream(maxLen);
267 final GZIPOutputStream gz = new GZIPOutputStream(out);
268 gz.write(raw);
269 gz.finish();
270 gz.flush();
271 return out.toByteArray();
272 }
273
274 private static String etag(final byte[] content) {
275 final MessageDigest md = Constants.newMessageDigest();
276 md.update(content);
277 return ObjectId.fromRaw(md.digest()).getName();
278 }
279
280 static String identify(Repository git) {
281 if (git instanceof DfsRepository) {
282 return ((DfsRepository) git).getDescription().getRepositoryName();
283 } else if (git.getDirectory() != null) {
284 return git.getDirectory().getPath();
285 }
286 return "unknown";
287 }
288
289 private ServletUtils() {
290
291 }
292 }