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