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 public static String urlEncode(String url, boolean keepPathSlash) {
202 String encoded;
203 try {
204 encoded = URLEncoder.encode(url, UTF_8.name());
205 } catch (UnsupportedEncodingException e) {
206 throw new RuntimeException(JGitText.get().couldNotURLEncodeToUTF8,
207 e);
208 }
209 if (keepPathSlash) {
210 encoded = encoded.replace("%2F", "/");
211 }
212 return encoded;
213 }
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230 public static int response(HttpConnection c) throws IOException {
231 try {
232 return c.getResponseCode();
233 } catch (ConnectException ce) {
234 final URL url = c.getURL();
235 final String host = (url == null) ? "<null>" : url.getHost();
236
237
238 if ("Connection timed out: connect".equals(ce.getMessage()))
239 throw new ConnectException(MessageFormat.format(JGitText.get().connectionTimeOut, host));
240 throw new ConnectException(ce.getMessage() + " " + host);
241 }
242 }
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258 public static int response(java.net.HttpURLConnection c)
259 throws IOException {
260 try {
261 return c.getResponseCode();
262 } catch (ConnectException ce) {
263 final URL url = c.getURL();
264 final String host = (url == null) ? "<null>" : url.getHost();
265
266
267 if ("Connection timed out: connect".equals(ce.getMessage()))
268 throw new ConnectException(MessageFormat.format(
269 JGitText.get().connectionTimeOut, host));
270 throw new ConnectException(ce.getMessage() + " " + host);
271 }
272 }
273
274
275
276
277
278
279
280
281
282
283
284
285
286 public static String responseHeader(final HttpConnection c,
287 final String headerName) throws IOException {
288 return c.getHeaderField(headerName);
289 }
290
291
292
293
294
295
296
297
298
299
300
301
302
303 public static Proxy proxyFor(ProxySelector proxySelector, URL u)
304 throws ConnectException {
305 try {
306 URI uri = new URI(u.getProtocol(), null, u.getHost(), u.getPort(),
307 null, null, null);
308 return proxySelector.select(uri).get(0);
309 } catch (URISyntaxException e) {
310 final ConnectException err;
311 err = new ConnectException(MessageFormat.format(JGitText.get().cannotDetermineProxyFor, u));
312 err.initCause(e);
313 throw err;
314 }
315 }
316
317
318
319
320
321
322
323
324
325
326 public static void disableSslVerify(HttpConnection conn)
327 throws IOException {
328 TrustManager[] trustAllCerts = {
329 new NoCheckX509TrustManager() };
330 try {
331 conn.configure(null, trustAllCerts, null);
332 conn.setHostnameVerifier((name, session) -> true);
333 } catch (KeyManagementException | NoSuchAlgorithmException e) {
334 throw new IOException(e.getMessage(), e);
335 }
336 }
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381 public static void configureTLS(SSLSocket socket) {
382
383 Set<String> enabled = new LinkedHashSet<>(
384 Arrays.asList(socket.getEnabledProtocols()));
385 for (String s : socket.getSupportedProtocols()) {
386 if (s.startsWith("TLS")) {
387 enabled.add(s);
388 }
389 }
390
391 Set<String> configured = getConfiguredProtocols();
392 if (!configured.isEmpty()) {
393 enabled.retainAll(configured);
394 }
395 if (!enabled.isEmpty()) {
396 socket.setEnabledProtocols(enabled.toArray(new String[0]));
397 }
398 }
399
400 private static Set<String> getConfiguredProtocols() {
401 Set<String> result = configuredHttpsProtocols;
402 if (result == null) {
403 String configured = getProperty("https.protocols");
404 if (StringUtils.isEmptyOrNull(configured)) {
405 result = Collections.emptySet();
406 } else {
407 result = new LinkedHashSet<>(
408 Arrays.asList(configured.split("\\s*,\\s*")));
409 }
410 configuredHttpsProtocols = result;
411 }
412 return result;
413 }
414
415 private static String getProperty(String property) {
416 try {
417 return SystemReader.getInstance().getProperty(property);
418 } catch (SecurityException e) {
419 LOG.warn(JGitText.get().failedReadHttpsProtocols, e);
420 return null;
421 }
422 }
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440 public static int scanToken(String header, int from) {
441 int length = header.length();
442 int i = from;
443 if (i < 0 || i > length) {
444 throw new IndexOutOfBoundsException();
445 }
446 while (i < length) {
447 char c = header.charAt(i);
448 switch (c) {
449 case '!':
450 case '#':
451 case '$':
452 case '%':
453 case '&':
454 case '\'':
455 case '*':
456 case '+':
457 case '-':
458 case '.':
459 case '^':
460 case '_':
461 case '`':
462 case '|':
463 case '~':
464 case '0':
465 case '1':
466 case '2':
467 case '3':
468 case '4':
469 case '5':
470 case '6':
471 case '7':
472 case '8':
473 case '9':
474 i++;
475 break;
476 default:
477 if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
478 i++;
479 break;
480 }
481 return i;
482 }
483 }
484 return i;
485 }
486
487 private HttpSupport() {
488
489 }
490 }