View Javadoc

1   // ========================================================================
2   // Copyright (c) 2006-2009 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses.
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   * Http Client.
45   * <p/>
46   * HttpClient is the main active component of the client API implementation.
47   * It is the opposite of the Connectors in standard Jetty, in that it listens
48   * for responses rather than requests.   Just like the connectors, there is a
49   * blocking socket version and a non-blocking NIO version (implemented as nested classes
50   * selected by {@link #setConnectorType(int)}).
51   * <p/>
52   * The an instance of {@link HttpExchange} is passed to the {@link #send(HttpExchange)} method
53   * to send a request.  The exchange contains both the headers and content (source) of the request
54   * plus the callbacks to handle responses.   A HttpClient can have many exchanges outstanding
55   * and they may be queued on the {@link HttpDestination} waiting for a {@link HttpConnection},
56   * queued in the {@link HttpConnection} waiting to be transmitted or pipelined on the actual
57   * TCP/IP connection waiting for a response.
58   * <p/>
59   * The {@link HttpDestination} class is an aggregation of {@link HttpConnection}s for the
60   * same host, port and protocol.   A destination may limit the number of connections
61   * open and they provide a pool of open connections that may be reused.   Connections may also
62   * be allocated from a destination, so that multiple request sources are not multiplexed
63   * over the same connection.
64   *
65   * @see HttpExchange
66   * @see HttpDestination
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      * @return True if connects will be in blocking mode.
136      */
137     public boolean isConnectBlocking()
138     {
139         return _connectBlocking;
140     }
141 
142     /* ------------------------------------------------------------------------------- */
143     /**
144      * @param connectBlocking True if connects will be in blocking mode.
145      */
146     public void setConnectBlocking(boolean connectBlocking)
147     {
148         _connectBlocking = connectBlocking;
149     }
150 
151     /* ------------------------------------------------------------ */
152     /**
153      * @see org.eclipse.jetty.util.component.Dumpable#dump()
154      */
155     public String dump()
156     {
157         return AggregateLifeCycle.dump(this);
158     }
159 
160     /* ------------------------------------------------------------ */
161     /**
162      * @see org.eclipse.jetty.util.component.Dumpable#dump(java.lang.Appendable, java.lang.String)
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      * @return the threadpool
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      * @param threadPool the threadPool to set
200      */
201     public void setThreadPool(ThreadPool threadPool)
202     {
203         _threadPool = threadPool;
204     }
205 
206 
207     /* ------------------------------------------------------------ */
208     /**
209      * @param name
210      * @return Attribute associated with client
211      */
212     public Object getAttribute(String name)
213     {
214         return _attributes.getAttribute(name);
215     }
216 
217     /* ------------------------------------------------------------ */
218     /**
219      * @return names of attributes associated with client
220      */
221     public Enumeration getAttributeNames()
222     {
223         return _attributes.getAttributeNames();
224     }
225 
226     /* ------------------------------------------------------------ */
227     /**
228      * @param name
229      */
230     public void removeAttribute(String name)
231     {
232         _attributes.removeAttribute(name);
233     }
234 
235     /* ------------------------------------------------------------ */
236     /**
237      * Set an attribute on the HttpClient.
238      * Attributes are not used by the client, but are provided for
239      * so that users of a shared HttpClient may share other structures.
240      * @param name
241      * @param attribute
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      * Get whether the connector can use direct NIO buffers.
304      */
305     public boolean getUseDirectBuffers()
306     {
307         return _useDirectBuffers;
308     }
309 
310     /* ------------------------------------------------------------ */
311     /** Set a RealmResolver for client Authentication.
312      * If a realmResolver is set, then the HttpDestinations created by
313      * this client will instantiate a {@link SecurityListener} so that
314      * BASIC and DIGEST authentication can be performed.
315      * @param resolver
316      */
317     public void setRealmResolver(RealmResolver resolver)
318     {
319         _realmResolver = resolver;
320     }
321 
322     /* ------------------------------------------------------------ */
323     /**
324      * returns the SecurityRealmResolver reg_realmResolveristered with the HttpClient or null
325      *
326      * @return the SecurityRealmResolver reg_realmResolveristered with the HttpClient or null
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      * Registers a listener that can listen to the stream of execution between the client and the
342      * server and influence events.  Sequential calls to the method wrapper sequentially wrap the preceding
343      * listener in a delegation model.
344      * <p/>
345      * NOTE: the SecurityListener is a special listener which doesn't need to be added via this
346      * mechanic, if you register security realms then it will automatically be added as the top listener of the
347      * delegation stack.
348      *
349      * @param listenerClass
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      * Set to use NIO direct buffers.
370      *
371      * @param direct If True (the default), the connector can use NIO direct
372      *               buffers. Some JVMs have memory management issues (bugs) with
373      *               direct buffers.
374      */
375     public void setUseDirectBuffers(boolean direct)
376     {
377         _useDirectBuffers = direct;
378         setBufferTypes();
379     }
380 
381     /* ------------------------------------------------------------ */
382     /**
383      * Get the type of connector (socket, blocking or select) in use.
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      * if a keystore location has been provided then client will attempt to use it as the keystore,
509      * otherwise we simply ignore certificates and run with a loose ssl context.
510      *
511      * @return the SSL context
512      */
513     protected SSLContext getSSLContext()
514     {
515         return _sslContextFactory.getSslContext();
516     }
517 
518     /* ------------------------------------------------------------ */
519     /**
520      * @return the instance of SslContextFactory associated with the client
521      */
522     public SslContextFactory getSslContextFactory()
523     {
524         return _sslContextFactory;
525     }
526 
527     /* ------------------------------------------------------------ */
528     /**
529      * @return the period in milliseconds a {@link HttpConnection} can be idle for before it is closed.
530      */
531     public long getIdleTimeout()
532     {
533         return _idleTimeout;
534     }
535 
536     /* ------------------------------------------------------------ */
537     /**
538      * @param ms the period in milliseconds a {@link HttpConnection} can be idle for before it is closed.
539      */
540     public void setIdleTimeout(long ms)
541     {
542         _idleTimeout = ms;
543     }
544 
545     /* ------------------------------------------------------------ */
546     /**
547      * @return the period in ms that an exchange will wait for a response from the server.
548      * @deprecated use {@link #getTimeout()} instead.
549      */
550     @Deprecated
551     public int getSoTimeout()
552     {
553         return Long.valueOf(getTimeout()).intValue();
554     }
555 
556     /* ------------------------------------------------------------ */
557     /**
558      * @deprecated use {@link #setTimeout(long)} instead.
559      * @param timeout the period in ms that an exchange will wait for a response from the server.
560      */
561     @Deprecated
562     public void setSoTimeout(int timeout)
563     {
564         setTimeout(timeout);
565     }
566 
567     /* ------------------------------------------------------------ */
568     /**
569      * @return the period in ms that an exchange will wait for a response from the server.
570      */
571     public long getTimeout()
572     {
573         return _timeout;
574     }
575 
576     /* ------------------------------------------------------------ */
577     /**
578      * @param timeout the period in ms that an exchange will wait for a response from the server.
579      */
580     public void setTimeout(long timeout)
581     {
582         _timeout = timeout;
583     }
584 
585     /* ------------------------------------------------------------ */
586     /**
587      * @return the period in ms before timing out an attempt to connect
588      */
589     public int getConnectTimeout()
590     {
591         return _connectTimeout;
592     }
593 
594     /* ------------------------------------------------------------ */
595     /**
596      * @param connectTimeout the period in ms before timing out an attempt to connect
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 }