1
2
3
4
5
6
7
8
9
10
11
12 package org.eclipse.jgit.util;
13
14 import static java.nio.charset.StandardCharsets.UTF_8;
15
16 import java.io.IOException;
17 import java.io.UnsupportedEncodingException;
18 import java.net.ConnectException;
19 import java.net.Proxy;
20 import java.net.ProxySelector;
21 import java.net.URI;
22 import java.net.URISyntaxException;
23 import java.net.URL;
24 import java.net.URLEncoder;
25 import java.security.KeyManagementException;
26 import java.security.NoSuchAlgorithmException;
27 import java.text.MessageFormat;
28 import java.util.Arrays;
29 import java.util.Collections;
30 import java.util.LinkedHashSet;
31 import java.util.Set;
32
33 import javax.net.ssl.SSLSocket;
34 import javax.net.ssl.TrustManager;
35
36 import org.eclipse.jgit.internal.JGitText;
37 import org.eclipse.jgit.transport.http.HttpConnection;
38 import org.eclipse.jgit.transport.http.NoCheckX509TrustManager;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42
43
44
45 public class HttpSupport {
46 private final static Logger LOG = LoggerFactory
47 .getLogger(HttpSupport.class);
48
49
50 public static final String METHOD_GET = "GET";
51
52
53
54 public static final String METHOD_HEAD = "HEAD";
55
56
57
58 public static final String METHOD_PUT = "PUT";
59
60
61 public static final String METHOD_POST = "POST";
62
63
64 public static final String HDR_CACHE_CONTROL = "Cache-Control";
65
66
67 public static final String HDR_PRAGMA = "Pragma";
68
69
70 public static final String HDR_USER_AGENT = "User-Agent";
71
72
73
74
75
76 public static final String HDR_SERVER = "Server";
77
78
79 public static final String HDR_DATE = "Date";
80
81
82 public static final String HDR_EXPIRES = "Expires";
83
84
85 public static final String HDR_ETAG = "ETag";
86
87
88 public static final String HDR_IF_NONE_MATCH = "If-None-Match";
89
90
91 public static final String HDR_LAST_MODIFIED = "Last-Modified";
92
93
94 public static final String HDR_IF_MODIFIED_SINCE = "If-Modified-Since";
95
96
97 public static final String HDR_ACCEPT = "Accept";
98
99
100 public static final String HDR_CONTENT_TYPE = "Content-Type";
101
102
103 public static final String HDR_CONTENT_LENGTH = "Content-Length";
104
105
106 public static final String HDR_CONTENT_ENCODING = "Content-Encoding";
107
108
109 public static final String HDR_CONTENT_RANGE = "Content-Range";
110
111
112 public static final String HDR_ACCEPT_RANGES = "Accept-Ranges";
113
114
115 public static final String HDR_IF_RANGE = "If-Range";
116
117
118 public static final String HDR_RANGE = "Range";
119
120
121 public static final String HDR_ACCEPT_ENCODING = "Accept-Encoding";
122
123
124
125
126
127 public static final String HDR_LOCATION = "Location";
128
129
130 public static final String ENCODING_GZIP = "gzip";
131
132
133
134
135
136 public static final String ENCODING_X_GZIP = "x-gzip";
137
138
139 public static final String TEXT_PLAIN = "text/plain";
140
141
142 public static final String HDR_AUTHORIZATION = "Authorization";
143
144
145 public static final String HDR_WWW_AUTHENTICATE = "WWW-Authenticate";
146
147
148
149
150
151
152 public static final String HDR_COOKIE = "Cookie";
153
154
155
156
157
158
159 public static final String HDR_SET_COOKIE = "Set-Cookie";
160
161
162
163
164
165
166 public static final String HDR_SET_COOKIE2 = "Set-Cookie2";
167
168 private static Set<String> configuredHttpsProtocols;
169
170
171
172
173
174
175
176
177
178 public static void encode(StringBuilder urlstr, String key) {
179 if (key == null || key.length() == 0)
180 return;
181 try {
182 urlstr.append(URLEncoder.encode(key, UTF_8.name()));
183 } catch (UnsupportedEncodingException e) {
184 throw new RuntimeException(JGitText.get().couldNotURLEncodeToUTF8, e);
185 }
186 }
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203 public static int response(HttpConnection c) throws IOException {
204 try {
205 return c.getResponseCode();
206 } catch (ConnectException ce) {
207 final URL url = c.getURL();
208 final String host = (url == null) ? "<null>" : url.getHost();
209
210
211 if ("Connection timed out: connect".equals(ce.getMessage()))
212 throw new ConnectException(MessageFormat.format(JGitText.get().connectionTimeOut, host));
213 throw new ConnectException(ce.getMessage() + " " + host);
214 }
215 }
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231 public static int response(java.net.HttpURLConnection c)
232 throws IOException {
233 try {
234 return c.getResponseCode();
235 } catch (ConnectException ce) {
236 final URL url = c.getURL();
237 final String host = (url == null) ? "<null>" : url.getHost();
238
239
240 if ("Connection timed out: connect".equals(ce.getMessage()))
241 throw new ConnectException(MessageFormat.format(
242 JGitText.get().connectionTimeOut, host));
243 throw new ConnectException(ce.getMessage() + " " + host);
244 }
245 }
246
247
248
249
250
251
252
253
254
255
256
257
258
259 public static String responseHeader(final HttpConnection c,
260 final String headerName) throws IOException {
261 return c.getHeaderField(headerName);
262 }
263
264
265
266
267
268
269
270
271
272
273
274
275
276 public static Proxy proxyFor(ProxySelector proxySelector, URL u)
277 throws ConnectException {
278 try {
279 URI uri = new URI(u.getProtocol(), null, u.getHost(), u.getPort(),
280 null, null, null);
281 return proxySelector.select(uri).get(0);
282 } catch (URISyntaxException e) {
283 final ConnectException err;
284 err = new ConnectException(MessageFormat.format(JGitText.get().cannotDetermineProxyFor, u));
285 err.initCause(e);
286 throw err;
287 }
288 }
289
290
291
292
293
294
295
296
297
298
299 public static void disableSslVerify(HttpConnection conn)
300 throws IOException {
301 TrustManager[] trustAllCerts = {
302 new NoCheckX509TrustManager() };
303 try {
304 conn.configure(null, trustAllCerts, null);
305 conn.setHostnameVerifier((name, session) -> true);
306 } catch (KeyManagementException | NoSuchAlgorithmException e) {
307 throw new IOException(e.getMessage(), e);
308 }
309 }
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354 public static void configureTLS(SSLSocket socket) {
355
356 Set<String> enabled = new LinkedHashSet<>(
357 Arrays.asList(socket.getEnabledProtocols()));
358 for (String s : socket.getSupportedProtocols()) {
359 if (s.startsWith("TLS")) {
360 enabled.add(s);
361 }
362 }
363
364 Set<String> configured = getConfiguredProtocols();
365 if (!configured.isEmpty()) {
366 enabled.retainAll(configured);
367 }
368 if (!enabled.isEmpty()) {
369 socket.setEnabledProtocols(enabled.toArray(new String[0]));
370 }
371 }
372
373 private static Set<String> getConfiguredProtocols() {
374 Set<String> result = configuredHttpsProtocols;
375 if (result == null) {
376 String configured = getProperty("https.protocols");
377 if (StringUtils.isEmptyOrNull(configured)) {
378 result = Collections.emptySet();
379 } else {
380 result = new LinkedHashSet<>(
381 Arrays.asList(configured.split("\\s*,\\s*")));
382 }
383 configuredHttpsProtocols = result;
384 }
385 return result;
386 }
387
388 private static String getProperty(String property) {
389 try {
390 return SystemReader.getInstance().getProperty(property);
391 } catch (SecurityException e) {
392 LOG.warn(JGitText.get().failedReadHttpsProtocols, e);
393 return null;
394 }
395 }
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413 public static int scanToken(String header, int from) {
414 int length = header.length();
415 int i = from;
416 if (i < 0 || i > length) {
417 throw new IndexOutOfBoundsException();
418 }
419 while (i < length) {
420 char c = header.charAt(i);
421 switch (c) {
422 case '!':
423 case '#':
424 case '$':
425 case '%':
426 case '&':
427 case '\'':
428 case '*':
429 case '+':
430 case '-':
431 case '.':
432 case '^':
433 case '_':
434 case '`':
435 case '|':
436 case '~':
437 case '0':
438 case '1':
439 case '2':
440 case '3':
441 case '4':
442 case '5':
443 case '6':
444 case '7':
445 case '8':
446 case '9':
447 i++;
448 break;
449 default:
450 if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
451 i++;
452 break;
453 }
454 return i;
455 }
456 }
457 return i;
458 }
459
460 private HttpSupport() {
461
462 }
463 }