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