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