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 public final class ServletUtils {
73
74 public static final String ATTRIBUTE_REPOSITORY = "org.eclipse.jgit.Repository";
75
76
77 public static final String ATTRIBUTE_HANDLER = "org.eclipse.jgit.transport.UploadPackOrReceivePack";
78
79
80
81
82
83
84
85
86
87
88
89
90
91 public static Repository getRepository(final ServletRequest req) {
92 Repository db = (Repository) req.getAttribute(ATTRIBUTE_REPOSITORY);
93 if (db == null)
94 throw new IllegalStateException(HttpServerText.get().expectedRepositoryAttribute);
95 return db;
96 }
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111 public static InputStream getInputStream(final HttpServletRequest req)
112 throws IOException {
113 InputStream in = req.getInputStream();
114 final String enc = req.getHeader(HDR_CONTENT_ENCODING);
115 if (ENCODING_GZIP.equals(enc) || ENCODING_X_GZIP.equals(enc))
116 in = new GZIPInputStream(in);
117 else if (enc != null)
118 throw new IOException(MessageFormat.format(HttpServerText.get().encodingNotSupportedByThisLibrary
119 , HDR_CONTENT_ENCODING, enc));
120 return in;
121 }
122
123
124
125
126
127
128
129 public static void consumeRequestBody(HttpServletRequest req) {
130 if (0 < req.getContentLength() || isChunked(req)) {
131 try {
132 consumeRequestBody(req.getInputStream());
133 } catch (IOException e) {
134
135 }
136 }
137 }
138
139 static boolean isChunked(HttpServletRequest req) {
140 return "chunked".equals(req.getHeader("Transfer-Encoding"));
141 }
142
143
144
145
146
147
148
149 public static void consumeRequestBody(InputStream in) {
150 if (in == null)
151 return;
152 try {
153 while (0 < in.skip(2048) || 0 <= in.read()) {
154
155 }
156 } catch (IOException err) {
157
158 } finally {
159 try {
160 in.close();
161 } catch (IOException err) {
162
163 }
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 public static void sendPlainText(final String content,
190 final HttpServletRequest req, final HttpServletResponse rsp)
191 throws IOException {
192 final byte[] raw = content.getBytes(Constants.CHARACTER_ENCODING);
193 rsp.setContentType(TEXT_PLAIN);
194 rsp.setCharacterEncoding(Constants.CHARACTER_ENCODING);
195 send(raw, req, rsp);
196 }
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218 public static void send(byte[] content, final HttpServletRequest req,
219 final HttpServletResponse rsp) throws IOException {
220 content = sendInit(content, req, rsp);
221 final OutputStream out = rsp.getOutputStream();
222 try {
223 out.write(content);
224 out.flush();
225 } finally {
226 out.close();
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(final 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(final 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(final 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 }