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