View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.http.impl.pool;
28  
29  import java.io.IOException;
30  import java.net.InetSocketAddress;
31  import java.net.Socket;
32  import java.security.AccessController;
33  import java.security.PrivilegedActionException;
34  import java.security.PrivilegedExceptionAction;
35  
36  import javax.net.SocketFactory;
37  import javax.net.ssl.SSLSocketFactory;
38  
39  import org.apache.http.HttpClientConnection;
40  import org.apache.http.HttpConnectionFactory;
41  import org.apache.http.HttpHost;
42  import org.apache.http.annotation.Contract;
43  import org.apache.http.annotation.ThreadingBehavior;
44  import org.apache.http.config.ConnectionConfig;
45  import org.apache.http.config.SocketConfig;
46  import org.apache.http.impl.DefaultBHttpClientConnection;
47  import org.apache.http.impl.DefaultBHttpClientConnectionFactory;
48  import org.apache.http.params.CoreConnectionPNames;
49  import org.apache.http.params.HttpParamConfig;
50  import org.apache.http.params.HttpParams;
51  import org.apache.http.pool.ConnFactory;
52  import org.apache.http.util.Args;
53  import org.apache.http.util.Asserts;
54  
55  /**
56   * A very basic {@link ConnFactory} implementation that creates
57   * {@link HttpClientConnection} instances given a {@link HttpHost} instance.
58   *
59   * @see HttpHost
60   * @since 4.2
61   */
62  @SuppressWarnings("deprecation")
63  @Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
64  public class BasicConnFactory implements ConnFactory<HttpHost, HttpClientConnection> {
65  
66      private final SocketFactory plainfactory;
67      private final SSLSocketFactory sslfactory;
68      private final int connectTimeout;
69      private final SocketConfig sconfig;
70      private final HttpConnectionFactory<? extends HttpClientConnection> connFactory;
71  
72      /**
73       * @deprecated (4.3) use
74       *   {@link BasicConnFactory#BasicConnFactory(SocketFactory, SSLSocketFactory, int,
75       *     SocketConfig, ConnectionConfig)}.
76       */
77      @Deprecated
78      public BasicConnFactory(final SSLSocketFactory sslfactory, final HttpParams params) {
79          super();
80          Args.notNull(params, "HTTP params");
81          this.plainfactory = null;
82          this.sslfactory = sslfactory;
83          this.connectTimeout = params.getIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 0);
84          this.sconfig = HttpParamConfig.getSocketConfig(params);
85          this.connFactory = new DefaultBHttpClientConnectionFactory(
86                  HttpParamConfig.getConnectionConfig(params));
87      }
88  
89      /**
90       * @deprecated (4.3) use
91       *   {@link BasicConnFactory#BasicConnFactory(int, SocketConfig, ConnectionConfig)}.
92       */
93      @Deprecated
94      public BasicConnFactory(final HttpParams params) {
95          this(null, params);
96      }
97  
98      /**
99       * @since 4.3
100      */
101     public BasicConnFactory(
102             final SocketFactory plainfactory,
103             final SSLSocketFactory sslfactory,
104             final int connectTimeout,
105             final SocketConfig sconfig,
106             final ConnectionConfig cconfig) {
107         super();
108         this.plainfactory = plainfactory;
109         this.sslfactory = sslfactory;
110         this.connectTimeout = connectTimeout;
111         this.sconfig = sconfig != null ? sconfig : SocketConfig.DEFAULT;
112         this.connFactory = new DefaultBHttpClientConnectionFactory(
113                 cconfig != null ? cconfig : ConnectionConfig.DEFAULT);
114     }
115 
116     /**
117      * @since 4.3
118      */
119     public BasicConnFactory(
120             final int connectTimeout, final SocketConfig sconfig, final ConnectionConfig cconfig) {
121         this(null, null, connectTimeout, sconfig, cconfig);
122     }
123 
124     /**
125      * @since 4.3
126      */
127     public BasicConnFactory(final SocketConfig sconfig, final ConnectionConfig cconfig) {
128         this(null, null, 0, sconfig, cconfig);
129     }
130 
131     /**
132      * @since 4.3
133      */
134     public BasicConnFactory() {
135         this(null, null, 0, SocketConfig.DEFAULT, ConnectionConfig.DEFAULT);
136     }
137 
138     /**
139      * @deprecated (4.3) no longer used.
140      */
141     @Deprecated
142     protected HttpClientConnection create(final Socket socket, final HttpParams params) throws IOException {
143         final int bufsize = params.getIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024);
144         final DefaultBHttpClientConnectiontion.html#DefaultBHttpClientConnection">DefaultBHttpClientConnection conn = new DefaultBHttpClientConnection(bufsize);
145         conn.bind(socket);
146         return conn;
147     }
148 
149     @Override
150     public HttpClientConnection create(final HttpHost host) throws IOException {
151         final String scheme = host.getSchemeName();
152         final Socket socket;
153         if ("http".equalsIgnoreCase(scheme)) {
154             socket = this.plainfactory != null ? this.plainfactory.createSocket() :
155                     new Socket();
156         } else if ("https".equalsIgnoreCase(scheme)) {
157             socket = (this.sslfactory != null ? this.sslfactory :
158                     SSLSocketFactory.getDefault()).createSocket();
159         } else {
160             throw new IOException(scheme + " scheme is not supported");
161         }
162         final String hostname = host.getHostName();
163         int port = host.getPort();
164         if (port == -1) {
165             if (host.getSchemeName().equalsIgnoreCase("http")) {
166                 port = 80;
167             } else if (host.getSchemeName().equalsIgnoreCase("https")) {
168                 port = 443;
169             }
170         }
171         socket.setSoTimeout(this.sconfig.getSoTimeout());
172         if (this.sconfig.getSndBufSize() > 0) {
173             socket.setSendBufferSize(this.sconfig.getSndBufSize());
174         }
175         if (this.sconfig.getRcvBufSize() > 0) {
176             socket.setReceiveBufferSize(this.sconfig.getRcvBufSize());
177         }
178         socket.setTcpNoDelay(this.sconfig.isTcpNoDelay());
179         final int linger = this.sconfig.getSoLinger();
180         if (linger >= 0) {
181             socket.setSoLinger(true, linger);
182         }
183         socket.setKeepAlive(this.sconfig.isSoKeepAlive());
184         // Run this under a doPrivileged to support lib users that run under a SecurityManager this allows granting connect permissions
185         // only to this library
186         final InetSocketAddress address = new InetSocketAddress(hostname, port);
187         try {
188             AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
189                 @Override
190                 public Object run() throws IOException {
191                     socket.connect(address, BasicConnFactory.this.connectTimeout);
192                     return null;
193                 }
194             });
195         } catch (final PrivilegedActionException e) {
196             Asserts.check(e.getCause() instanceof IOException,
197                     "method contract violation only checked exceptions are wrapped: " + e.getCause());
198             // only checked exceptions are wrapped - error and RTExceptions are rethrown by doPrivileged
199             throw (IOException) e.getCause();
200         }
201         return this.connFactory.createConnection(socket);
202     }
203 
204 }