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