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