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 package org.eclipse.jgit.transport.http.apache;
44
45 import static org.eclipse.jgit.util.HttpSupport.METHOD_GET;
46 import static org.eclipse.jgit.util.HttpSupport.METHOD_HEAD;
47 import static org.eclipse.jgit.util.HttpSupport.METHOD_POST;
48 import static org.eclipse.jgit.util.HttpSupport.METHOD_PUT;
49
50 import java.io.IOException;
51 import java.io.InputStream;
52 import java.io.OutputStream;
53 import java.net.InetSocketAddress;
54 import java.net.MalformedURLException;
55 import java.net.ProtocolException;
56 import java.net.Proxy;
57 import java.net.URL;
58 import java.security.KeyManagementException;
59 import java.security.NoSuchAlgorithmException;
60 import java.security.SecureRandom;
61 import java.util.HashMap;
62 import java.util.LinkedList;
63 import java.util.List;
64 import java.util.Map;
65
66 import javax.net.ssl.HostnameVerifier;
67 import javax.net.ssl.KeyManager;
68 import javax.net.ssl.SSLContext;
69 import javax.net.ssl.TrustManager;
70
71 import org.apache.http.Header;
72 import org.apache.http.HeaderElement;
73 import org.apache.http.HttpEntity;
74 import org.apache.http.HttpEntityEnclosingRequest;
75 import org.apache.http.HttpHost;
76 import org.apache.http.HttpResponse;
77 import org.apache.http.client.ClientProtocolException;
78 import org.apache.http.client.HttpClient;
79 import org.apache.http.client.config.RequestConfig;
80 import org.apache.http.client.methods.HttpGet;
81 import org.apache.http.client.methods.HttpHead;
82 import org.apache.http.client.methods.HttpPost;
83 import org.apache.http.client.methods.HttpPut;
84 import org.apache.http.client.methods.HttpUriRequest;
85 import org.apache.http.config.Registry;
86 import org.apache.http.config.RegistryBuilder;
87 import org.apache.http.conn.socket.ConnectionSocketFactory;
88 import org.apache.http.conn.socket.PlainConnectionSocketFactory;
89 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
90 import org.apache.http.impl.client.HttpClientBuilder;
91 import org.apache.http.impl.client.HttpClients;
92 import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
93 import org.eclipse.jgit.transport.http.HttpConnection;
94 import org.eclipse.jgit.transport.http.apache.internal.HttpApacheText;
95 import org.eclipse.jgit.util.TemporaryBuffer;
96 import org.eclipse.jgit.util.TemporaryBuffer.LocalFile;
97
98
99
100
101
102
103
104 public class HttpClientConnection implements HttpConnection {
105 HttpClient client;
106
107 URL url;
108
109 HttpUriRequest req;
110
111 HttpResponse resp = null;
112
113 String method = "GET";
114
115 private TemporaryBufferEntity entity;
116
117 private boolean isUsingProxy = false;
118
119 private Proxy proxy;
120
121 private Integer timeout = null;
122
123 private Integer readTimeout;
124
125 private Boolean followRedirects;
126
127 private HostnameVerifier hostnameverifier;
128
129 SSLContext ctx;
130
131 private HttpClient getClient() {
132 if (client == null) {
133 HttpClientBuilder clientBuilder = HttpClients.custom();
134 RequestConfig.Builder configBuilder = RequestConfig.custom();
135 if (proxy != null && !Proxy.NO_PROXY.equals(proxy)) {
136 isUsingProxy = true;
137 InetSocketAddress adr = (InetSocketAddress) proxy.address();
138 clientBuilder.setProxy(
139 new HttpHost(adr.getHostName(), adr.getPort()));
140 }
141 if (timeout != null) {
142 configBuilder.setConnectTimeout(timeout.intValue());
143 }
144 if (readTimeout != null) {
145 configBuilder.setSocketTimeout(readTimeout.intValue());
146 }
147 if (followRedirects != null) {
148 configBuilder
149 .setRedirectsEnabled(followRedirects.booleanValue());
150 }
151 if (hostnameverifier != null) {
152 SSLConnectionSocketFactory sslConnectionFactory = new SSLConnectionSocketFactory(
153 getSSLContext(), hostnameverifier);
154 clientBuilder.setSSLSocketFactory(sslConnectionFactory);
155 Registry<ConnectionSocketFactory> registry = RegistryBuilder
156 .<ConnectionSocketFactory> create()
157 .register("https", sslConnectionFactory)
158 .register("http", PlainConnectionSocketFactory.INSTANCE)
159 .build();
160 clientBuilder.setConnectionManager(
161 new BasicHttpClientConnectionManager(registry));
162 }
163 clientBuilder.setDefaultRequestConfig(configBuilder.build());
164 client = clientBuilder.build();
165 }
166
167 return client;
168 }
169
170 private SSLContext getSSLContext() {
171 if (ctx == null) {
172 try {
173 ctx = SSLContext.getInstance("TLS");
174 } catch (NoSuchAlgorithmException e) {
175 throw new IllegalStateException(
176 HttpApacheText.get().unexpectedSSLContextException, e);
177 }
178 }
179 return ctx;
180 }
181
182
183
184
185
186
187 public void setBuffer(TemporaryBuffer buffer) {
188 this.entity = new TemporaryBufferEntity(buffer);
189 }
190
191
192
193
194
195
196
197 public HttpClientConnection(String urlStr) throws MalformedURLException {
198 this(urlStr, null);
199 }
200
201
202
203
204
205
206
207
208 public HttpClientConnection(String urlStr, Proxy proxy)
209 throws MalformedURLException {
210 this(urlStr, proxy, null);
211 }
212
213
214
215
216
217
218
219
220
221 public HttpClientConnection(String urlStr, Proxy proxy, HttpClient cl)
222 throws MalformedURLException {
223 this.client = cl;
224 this.url = new URL(urlStr);
225 this.proxy = proxy;
226 }
227
228
229 @Override
230 public int getResponseCode() throws IOException {
231 execute();
232 return resp.getStatusLine().getStatusCode();
233 }
234
235
236 @Override
237 public URL getURL() {
238 return url;
239 }
240
241
242 @Override
243 public String getResponseMessage() throws IOException {
244 execute();
245 return resp.getStatusLine().getReasonPhrase();
246 }
247
248 private void execute() throws IOException, ClientProtocolException {
249 if (resp != null) {
250 return;
251 }
252
253 if (entity == null) {
254 resp = getClient().execute(req);
255 return;
256 }
257
258 try {
259 if (req instanceof HttpEntityEnclosingRequest) {
260 HttpEntityEnclosingRequest eReq = (HttpEntityEnclosingRequest) req;
261 eReq.setEntity(entity);
262 }
263 resp = getClient().execute(req);
264 } finally {
265 entity.close();
266 entity = null;
267 }
268 }
269
270
271 @Override
272 public Map<String, List<String>> getHeaderFields() {
273 Map<String, List<String>> ret = new HashMap<>();
274 for (Header hdr : resp.getAllHeaders()) {
275 List<String> list = new LinkedList<>();
276 for (HeaderElement hdrElem : hdr.getElements())
277 list.add(hdrElem.toString());
278 ret.put(hdr.getName(), list);
279 }
280 return ret;
281 }
282
283
284 @Override
285 public void setRequestProperty(String name, String value) {
286 req.addHeader(name, value);
287 }
288
289
290 @Override
291 public void setRequestMethod(String method) throws ProtocolException {
292 this.method = method;
293 if (METHOD_GET.equalsIgnoreCase(method)) {
294 req = new HttpGet(url.toString());
295 } else if (METHOD_HEAD.equalsIgnoreCase(method)) {
296 req = new HttpHead(url.toString());
297 } else if (METHOD_PUT.equalsIgnoreCase(method)) {
298 req = new HttpPut(url.toString());
299 } else if (METHOD_POST.equalsIgnoreCase(method)) {
300 req = new HttpPost(url.toString());
301 } else {
302 this.method = null;
303 throw new UnsupportedOperationException();
304 }
305 }
306
307
308 @Override
309 public void setUseCaches(boolean usecaches) {
310
311 }
312
313
314 @Override
315 public void setConnectTimeout(int timeout) {
316 this.timeout = Integer.valueOf(timeout);
317 }
318
319
320 @Override
321 public void setReadTimeout(int readTimeout) {
322 this.readTimeout = Integer.valueOf(readTimeout);
323 }
324
325
326 @Override
327 public String getContentType() {
328 HttpEntity responseEntity = resp.getEntity();
329 if (responseEntity != null) {
330 Header contentType = responseEntity.getContentType();
331 if (contentType != null)
332 return contentType.getValue();
333 }
334 return null;
335 }
336
337
338 @Override
339 public InputStream getInputStream() throws IOException {
340 return resp.getEntity().getContent();
341 }
342
343
344
345 @Override
346 public String getHeaderField(String name) {
347 Header header = resp.getFirstHeader(name);
348 return (header == null) ? null : header.getValue();
349 }
350
351
352 @Override
353 public int getContentLength() {
354 Header contentLength = resp.getFirstHeader("content-length");
355 if (contentLength == null) {
356 return -1;
357 }
358
359 try {
360 int l = Integer.parseInt(contentLength.getValue());
361 return l < 0 ? -1 : l;
362 } catch (NumberFormatException e) {
363 return -1;
364 }
365 }
366
367
368 @Override
369 public void setInstanceFollowRedirects(boolean followRedirects) {
370 this.followRedirects = Boolean.valueOf(followRedirects);
371 }
372
373
374 @Override
375 public void setDoOutput(boolean dooutput) {
376
377 }
378
379
380 @Override
381 public void setFixedLengthStreamingMode(int contentLength) {
382 if (entity != null)
383 throw new IllegalArgumentException();
384 entity = new TemporaryBufferEntity(new LocalFile(null));
385 entity.setContentLength(contentLength);
386 }
387
388
389 @Override
390 public OutputStream getOutputStream() throws IOException {
391 if (entity == null)
392 entity = new TemporaryBufferEntity(new LocalFile(null));
393 return entity.getBuffer();
394 }
395
396
397 @Override
398 public void setChunkedStreamingMode(int chunklen) {
399 if (entity == null)
400 entity = new TemporaryBufferEntity(new LocalFile(null));
401 entity.setChunked(true);
402 }
403
404
405 @Override
406 public String getRequestMethod() {
407 return method;
408 }
409
410
411 @Override
412 public boolean usingProxy() {
413 return isUsingProxy;
414 }
415
416
417 @Override
418 public void connect() throws IOException {
419 execute();
420 }
421
422
423 @Override
424 public void setHostnameVerifier(HostnameVerifier hostnameverifier) {
425 this.hostnameverifier = hostnameverifier;
426 }
427
428
429 @Override
430 public void configure(KeyManager[] km, TrustManager[] tm,
431 SecureRandom random) throws KeyManagementException {
432 getSSLContext().init(km, tm, random);
433 }
434 }