1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.client;
15
16 import java.io.IOException;
17 import java.io.InputStream;
18 import java.net.UnknownHostException;
19 import java.util.Enumeration;
20 import java.util.LinkedList;
21 import java.util.Map;
22 import java.util.Set;
23 import java.util.concurrent.ConcurrentHashMap;
24 import java.util.concurrent.ConcurrentMap;
25 import javax.net.ssl.SSLContext;
26
27 import org.eclipse.jetty.client.security.Authentication;
28 import org.eclipse.jetty.client.security.RealmResolver;
29 import org.eclipse.jetty.client.security.SecurityListener;
30 import org.eclipse.jetty.http.HttpBuffers;
31 import org.eclipse.jetty.http.HttpSchemes;
32 import org.eclipse.jetty.http.ssl.SslContextFactory;
33 import org.eclipse.jetty.io.Buffers.Type;
34 import org.eclipse.jetty.util.Attributes;
35 import org.eclipse.jetty.util.AttributesMap;
36 import org.eclipse.jetty.util.TypeUtil;
37 import org.eclipse.jetty.util.component.AggregateLifeCycle;
38 import org.eclipse.jetty.util.component.Dumpable;
39 import org.eclipse.jetty.util.component.LifeCycle;
40 import org.eclipse.jetty.util.log.Log;
41 import org.eclipse.jetty.util.thread.QueuedThreadPool;
42 import org.eclipse.jetty.util.thread.ThreadPool;
43 import org.eclipse.jetty.util.thread.Timeout;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 public class HttpClient extends HttpBuffers implements Attributes, Dumpable
71 {
72 public static final int CONNECTOR_SOCKET = 0;
73 public static final int CONNECTOR_SELECT_CHANNEL = 2;
74
75 private int _connectorType = CONNECTOR_SELECT_CHANNEL;
76 private boolean _useDirectBuffers = true;
77 private boolean _connectBlocking = true;
78 private int _maxConnectionsPerAddress = Integer.MAX_VALUE;
79 private int _maxQueueSizePerAddress = Integer.MAX_VALUE;
80 private ConcurrentMap<Address, HttpDestination> _destinations = new ConcurrentHashMap<Address, HttpDestination>();
81 ThreadPool _threadPool;
82 Connector _connector;
83 private long _idleTimeout = 20000;
84 private long _timeout = 320000;
85 private int _connectTimeout = 75000;
86 private Timeout _timeoutQ = new Timeout();
87 private Timeout _idleTimeoutQ = new Timeout();
88 private Address _proxy;
89 private Authentication _proxyAuthentication;
90 private Set<String> _noProxy;
91 private int _maxRetries = 3;
92 private int _maxRedirects = 20;
93 private LinkedList<String> _registeredListeners;
94
95 private SslContextFactory _sslContextFactory;
96
97 private RealmResolver _realmResolver;
98
99 private AttributesMap _attributes=new AttributesMap();
100
101
102
103 private void setBufferTypes()
104 {
105 if (_connectorType==CONNECTOR_SOCKET)
106 {
107 setRequestBufferType(Type.BYTE_ARRAY);
108 setRequestHeaderType(Type.BYTE_ARRAY);
109 setResponseBufferType(Type.BYTE_ARRAY);
110 setResponseHeaderType(Type.BYTE_ARRAY);
111 }
112 else
113 {
114 setRequestBufferType(Type.DIRECT);
115 setRequestHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT);
116 setResponseBufferType(Type.DIRECT);
117 setResponseHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT);
118 }
119 }
120
121
122 public HttpClient()
123 {
124 this(new SslContextFactory());
125 setBufferTypes();
126 }
127
128
129 public HttpClient(SslContextFactory sslContextFactory)
130 {
131 _sslContextFactory = sslContextFactory;
132 setBufferTypes();
133 }
134
135
136
137
138
139 public boolean isConnectBlocking()
140 {
141 return _connectBlocking;
142 }
143
144
145
146
147
148 public void setConnectBlocking(boolean connectBlocking)
149 {
150 _connectBlocking = connectBlocking;
151 }
152
153
154
155
156
157 public String dump()
158 {
159 return AggregateLifeCycle.dump(this);
160 }
161
162
163
164
165
166 public void dump(Appendable out, String indent) throws IOException
167 {
168 out.append(String.valueOf(this)).append("\n");
169 AggregateLifeCycle.dump(out,indent,_destinations.values());
170 }
171
172
173 public void send(HttpExchange exchange) throws IOException
174 {
175 boolean ssl = HttpSchemes.HTTPS_BUFFER.equalsIgnoreCase(exchange.getScheme());
176 exchange.setStatus(HttpExchange.STATUS_WAITING_FOR_CONNECTION);
177 HttpDestination destination = getDestination(exchange.getAddress(), ssl);
178 destination.send(exchange);
179 }
180
181
182
183
184
185 public ThreadPool getThreadPool()
186 {
187 return _threadPool;
188 }
189
190
191
192
193
194 public void setThreadPool(ThreadPool threadPool)
195 {
196 _threadPool = threadPool;
197 }
198
199
200
201
202
203
204
205 public Object getAttribute(String name)
206 {
207 return _attributes.getAttribute(name);
208 }
209
210
211
212
213
214 public Enumeration getAttributeNames()
215 {
216 return _attributes.getAttributeNames();
217 }
218
219
220
221
222
223 public void removeAttribute(String name)
224 {
225 _attributes.removeAttribute(name);
226 }
227
228
229
230
231
232
233
234
235
236 public void setAttribute(String name, Object attribute)
237 {
238 _attributes.setAttribute(name,attribute);
239 }
240
241
242 public void clearAttributes()
243 {
244 _attributes.clearAttributes();
245 }
246
247
248 public HttpDestination getDestination(Address remote, boolean ssl) throws IOException
249 {
250 if (remote == null)
251 throw new UnknownHostException("Remote socket address cannot be null.");
252
253 HttpDestination destination = _destinations.get(remote);
254 if (destination == null)
255 {
256 destination = new HttpDestination(this, remote, ssl);
257 if (_proxy != null && (_noProxy == null || !_noProxy.contains(remote.getHost())))
258 {
259 destination.setProxy(_proxy);
260 if (_proxyAuthentication != null)
261 destination.setProxyAuthentication(_proxyAuthentication);
262 }
263 HttpDestination other =_destinations.putIfAbsent(remote, destination);
264 if (other!=null)
265 destination=other;
266 }
267 return destination;
268 }
269
270
271 public void schedule(Timeout.Task task)
272 {
273 _timeoutQ.schedule(task);
274 }
275
276
277 public void schedule(Timeout.Task task, long timeout)
278 {
279 _timeoutQ.schedule(task, timeout - _timeoutQ.getDuration());
280 }
281
282
283 public void scheduleIdle(Timeout.Task task)
284 {
285 _idleTimeoutQ.schedule(task);
286 }
287
288
289 public void cancel(Timeout.Task task)
290 {
291 task.cancel();
292 }
293
294
295
296
297
298 public boolean getUseDirectBuffers()
299 {
300 return _useDirectBuffers;
301 }
302
303
304
305
306
307
308
309
310 public void setRealmResolver(RealmResolver resolver)
311 {
312 _realmResolver = resolver;
313 }
314
315
316
317
318
319
320
321 public RealmResolver getRealmResolver()
322 {
323 return _realmResolver;
324 }
325
326
327 public boolean hasRealms()
328 {
329 return _realmResolver == null ? false : true;
330 }
331
332
333
334
335
336
337
338
339
340
341
342
343
344 public void registerListener(String listenerClass)
345 {
346 if (_registeredListeners == null)
347 {
348 _registeredListeners = new LinkedList<String>();
349 }
350 _registeredListeners.add(listenerClass);
351 }
352
353
354 public LinkedList<String> getRegisteredListeners()
355 {
356 return _registeredListeners;
357 }
358
359
360
361
362
363
364
365
366
367
368 public void setUseDirectBuffers(boolean direct)
369 {
370 _useDirectBuffers = direct;
371 setBufferTypes();
372 }
373
374
375
376
377
378 public int getConnectorType()
379 {
380 return _connectorType;
381 }
382
383
384 public void setConnectorType(int connectorType)
385 {
386 this._connectorType = connectorType;
387 setBufferTypes();
388 }
389
390
391 public int getMaxConnectionsPerAddress()
392 {
393 return _maxConnectionsPerAddress;
394 }
395
396
397 public void setMaxConnectionsPerAddress(int maxConnectionsPerAddress)
398 {
399 _maxConnectionsPerAddress = maxConnectionsPerAddress;
400 }
401
402 public int getMaxQueueSizePerAddress()
403 {
404 return _maxQueueSizePerAddress;
405 }
406
407 public void setMaxQueueSizePerAddress(int maxQueueSizePerAddress)
408 {
409 this._maxQueueSizePerAddress = maxQueueSizePerAddress;
410 }
411
412
413 @Override
414 protected void doStart() throws Exception
415 {
416 setBufferTypes();
417 super.doStart();
418
419 _timeoutQ.setDuration(_timeout);
420 _timeoutQ.setNow();
421 _idleTimeoutQ.setDuration(_idleTimeout);
422 _idleTimeoutQ.setNow();
423
424 if (_threadPool == null)
425 {
426 QueuedThreadPool pool = new QueuedThreadPool();
427 pool.setMaxThreads(16);
428 pool.setDaemon(true);
429 pool.setName("HttpClient");
430 _threadPool = pool;
431 }
432
433 if (_threadPool instanceof LifeCycle)
434 {
435 ((LifeCycle)_threadPool).start();
436 }
437
438 _sslContextFactory.start();
439
440 if (_connectorType == CONNECTOR_SELECT_CHANNEL)
441 {
442
443 _connector = new SelectConnector(this);
444 }
445 else
446 {
447 _connector = new SocketConnector(this);
448 }
449 _connector.start();
450
451 _threadPool.dispatch(new Runnable()
452 {
453 public void run()
454 {
455 while (isRunning())
456 {
457 _timeoutQ.tick(System.currentTimeMillis());
458 _idleTimeoutQ.tick(_timeoutQ.getNow());
459 try
460 {
461 Thread.sleep(200);
462 }
463 catch (InterruptedException e)
464 {
465 }
466 }
467 }
468 });
469 }
470
471
472 long getNow()
473 {
474 return _timeoutQ.getNow();
475 }
476
477
478 @Override
479 protected void doStop() throws Exception
480 {
481 _connector.stop();
482 _connector = null;
483 _sslContextFactory.stop();
484
485 if (_threadPool instanceof LifeCycle)
486 {
487 ((LifeCycle)_threadPool).stop();
488 }
489 for (HttpDestination destination : _destinations.values())
490 {
491 destination.close();
492 }
493
494 _timeoutQ.cancelAll();
495 _idleTimeoutQ.cancelAll();
496 super.doStop();
497 }
498
499
500 interface Connector extends LifeCycle
501 {
502 public void startConnection(HttpDestination destination) throws IOException;
503 }
504
505
506
507
508
509
510
511
512 protected SSLContext getSSLContext()
513 {
514 return _sslContextFactory.getSslContext();
515 }
516
517
518
519
520
521 public SslContextFactory getSslContextFactory()
522 {
523 return _sslContextFactory;
524 }
525
526
527
528
529
530 public long getIdleTimeout()
531 {
532 return _idleTimeout;
533 }
534
535
536
537
538
539 public void setIdleTimeout(long ms)
540 {
541 _idleTimeout = ms;
542 }
543
544
545
546
547
548
549 @Deprecated
550 public int getSoTimeout()
551 {
552 return Long.valueOf(getTimeout()).intValue();
553 }
554
555
556
557
558
559
560 @Deprecated
561 public void setSoTimeout(int timeout)
562 {
563 setTimeout(timeout);
564 }
565
566
567
568
569
570 public long getTimeout()
571 {
572 return _timeout;
573 }
574
575
576
577
578
579 public void setTimeout(long timeout)
580 {
581 _timeout = timeout;
582 }
583
584
585
586
587
588 public int getConnectTimeout()
589 {
590 return _connectTimeout;
591 }
592
593
594
595
596
597 public void setConnectTimeout(int connectTimeout)
598 {
599 this._connectTimeout = connectTimeout;
600 }
601
602
603 public Address getProxy()
604 {
605 return _proxy;
606 }
607
608
609 public void setProxy(Address proxy)
610 {
611 this._proxy = proxy;
612 }
613
614
615 public Authentication getProxyAuthentication()
616 {
617 return _proxyAuthentication;
618 }
619
620
621 public void setProxyAuthentication(Authentication authentication)
622 {
623 _proxyAuthentication = authentication;
624 }
625
626
627 public boolean isProxied()
628 {
629 return this._proxy != null;
630 }
631
632
633 public Set<String> getNoProxy()
634 {
635 return _noProxy;
636 }
637
638
639 public void setNoProxy(Set<String> noProxyAddresses)
640 {
641 _noProxy = noProxyAddresses;
642 }
643
644
645 public int maxRetries()
646 {
647 return _maxRetries;
648 }
649
650
651 public void setMaxRetries(int retries)
652 {
653 _maxRetries = retries;
654 }
655
656
657 public int maxRedirects()
658 {
659 return _maxRedirects;
660 }
661
662
663 public void setMaxRedirects(int redirects)
664 {
665 _maxRedirects = redirects;
666 }
667
668
669 @Deprecated
670 public String getTrustStoreLocation()
671 {
672 return _sslContextFactory.getTrustStore();
673 }
674
675
676 @Deprecated
677 public void setTrustStoreLocation(String trustStoreLocation)
678 {
679 _sslContextFactory.setTrustStore(trustStoreLocation);
680 }
681
682
683 @Deprecated
684 public InputStream getTrustStoreInputStream()
685 {
686 return _sslContextFactory.getTrustStoreInputStream();
687 }
688
689
690 @Deprecated
691 public void setTrustStoreInputStream(InputStream trustStoreInputStream)
692 {
693 _sslContextFactory.setTrustStoreInputStream(trustStoreInputStream);
694 }
695
696
697 @Deprecated
698 public String getKeyStoreLocation()
699 {
700 return _sslContextFactory.getKeyStore();
701 }
702
703
704 @Deprecated
705 public void setKeyStoreLocation(String keyStoreLocation)
706 {
707 _sslContextFactory.setKeyStore(keyStoreLocation);
708 }
709
710 @Deprecated
711 public InputStream getKeyStoreInputStream()
712 {
713 return _sslContextFactory.getKeyStoreInputStream();
714 }
715
716 @Deprecated
717 public void setKeyStoreInputStream(InputStream keyStoreInputStream)
718 {
719 _sslContextFactory.setKeyStoreInputStream(keyStoreInputStream);
720 }
721
722
723 @Deprecated
724 public void setKeyStorePassword(String keyStorePassword)
725 {
726 _sslContextFactory.setKeyStorePassword(keyStorePassword);
727 }
728
729
730 @Deprecated
731 public void setKeyManagerPassword(String keyManagerPassword)
732 {
733 _sslContextFactory.setKeyManagerPassword(keyManagerPassword);
734 }
735
736
737 @Deprecated
738 public void setTrustStorePassword(String trustStorePassword)
739 {
740 _sslContextFactory.setTrustStorePassword(trustStorePassword);
741 }
742
743
744 @Deprecated
745 public String getKeyStoreType()
746 {
747 return _sslContextFactory.getKeyStoreType();
748 }
749
750
751 @Deprecated
752 public void setKeyStoreType(String keyStoreType)
753 {
754 _sslContextFactory.setKeyStoreType(keyStoreType);
755 }
756
757
758 @Deprecated
759 public String getTrustStoreType()
760 {
761 return _sslContextFactory.getTrustStoreType();
762 }
763
764
765 @Deprecated
766 public void setTrustStoreType(String trustStoreType)
767 {
768 _sslContextFactory.setTrustStoreType(trustStoreType);
769 }
770
771
772 @Deprecated
773 public String getKeyManagerAlgorithm()
774 {
775 return _sslContextFactory.getSslKeyManagerFactoryAlgorithm();
776 }
777
778
779 @Deprecated
780 public void setKeyManagerAlgorithm(String keyManagerAlgorithm)
781 {
782 _sslContextFactory.setSslKeyManagerFactoryAlgorithm(keyManagerAlgorithm);
783 }
784
785
786 @Deprecated
787 public String getTrustManagerAlgorithm()
788 {
789 return _sslContextFactory.getTrustManagerFactoryAlgorithm();
790 }
791
792
793 @Deprecated
794 public void setTrustManagerAlgorithm(String trustManagerAlgorithm)
795 {
796 _sslContextFactory.setTrustManagerFactoryAlgorithm(trustManagerAlgorithm);
797 }
798
799
800 @Deprecated
801 public String getProtocol()
802 {
803 return _sslContextFactory.getProtocol();
804 }
805
806
807 @Deprecated
808 public void setProtocol(String protocol)
809 {
810 _sslContextFactory.setProtocol(protocol);
811 }
812
813
814 @Deprecated
815 public String getProvider()
816 {
817 return _sslContextFactory.getProvider();
818 }
819
820
821 @Deprecated
822 public void setProvider(String provider)
823 {
824 setProvider(provider);
825 }
826
827
828 @Deprecated
829 public String getSecureRandomAlgorithm()
830 {
831 return _sslContextFactory.getSecureRandomAlgorithm();
832 }
833
834
835 @Deprecated
836 public void setSecureRandomAlgorithm(String secureRandomAlgorithm)
837 {
838 _sslContextFactory.setSecureRandomAlgorithm(secureRandomAlgorithm);
839 }
840 }