Configuration API changes: deprecated SchemeSocketFactory and SchemeLayeredSocketFactory in favor of ConnectionSocketFactory and LayeredConnectionSocketFactory interfaces (new API no longer relies on HttpParams)

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1414674 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2012-11-28 13:35:46 +00:00
parent 697556b9b0
commit 4dc5821acb
9 changed files with 400 additions and 109 deletions

View File

@ -28,7 +28,9 @@
package org.apache.http.conn; package org.apache.http.conn;
import java.io.InterruptedIOException; import java.io.InterruptedIOException;
import java.net.InetSocketAddress;
import org.apache.http.HttpHost;
import org.apache.http.annotation.Immutable; import org.apache.http.annotation.Immutable;
/** /**
@ -59,4 +61,18 @@ public class ConnectTimeoutException extends InterruptedIOException {
super(message); super(message);
} }
/**
* Creates a ConnectTimeoutException with the specified detail message.
*
* @param message The exception detail message
*
* @since 4.3
*/
public ConnectTimeoutException(final HttpHost host, final InetSocketAddress remoteAddress) {
super("Connect to " +
(host != null ? host.toHostString() : " remote host") +
(remoteAddress != null ? " (" + remoteAddress.getAddress() + ")" : "")
+ " timed out");
}
} }

View File

@ -35,8 +35,11 @@ import org.apache.http.HttpHost;
* Extended {@link InetSocketAddress} implementation that also provides access to the original * Extended {@link InetSocketAddress} implementation that also provides access to the original
* {@link HttpHost} used to resolve the address. * {@link HttpHost} used to resolve the address.
* *
* @since 4.2 * @since 4.2 no longer used.
*
* @deprecated (4.3)
*/ */
@Deprecated
public class HttpInetSocketAddress extends InetSocketAddress { public class HttpInetSocketAddress extends InetSocketAddress {
private static final long serialVersionUID = -6650701828361907957L; private static final long serialVersionUID = -6650701828361907957L;

View File

@ -43,18 +43,13 @@ import org.apache.http.params.HttpParams;
/** /**
* The default class for creating plain (unencrypted) sockets. * The default class for creating plain (unencrypted) sockets.
* <p>
* The following parameters can be used to customize the behavior of this
* class:
* <ul>
* <li>{@link org.apache.http.params.CoreConnectionPNames#CONNECTION_TIMEOUT}</li>
* <li>{@link org.apache.http.params.CoreConnectionPNames#SO_REUSEADDR}</li>
* </ul>
* *
* @since 4.0 * @since 4.0
*
* @deprecated (4.3) use {@link org.apache.http.conn.socket.PlainSocketFactory}
*/ */
@SuppressWarnings("deprecation")
@Immutable @Immutable
@Deprecated
public class PlainSocketFactory implements SocketFactory, SchemeSocketFactory { public class PlainSocketFactory implements SocketFactory, SchemeSocketFactory {
private final HostNameResolver nameResolver; private final HostNameResolver nameResolver;

View File

@ -37,7 +37,10 @@ import org.apache.http.params.HttpParams;
* Extended {@link SchemeSocketFactory} interface for layered sockets such as SSL/TLS. * Extended {@link SchemeSocketFactory} interface for layered sockets such as SSL/TLS.
* *
* @since 4.2 * @since 4.2
*
* @deprecated (4.3) use {@link LayeredConnectionSocketFactory}
*/ */
@Deprecated
public interface SchemeLayeredSocketFactory extends SchemeSocketFactory { public interface SchemeLayeredSocketFactory extends SchemeSocketFactory {
/** /**

View File

@ -35,6 +35,7 @@ import java.net.UnknownHostException;
import org.apache.http.HttpHost; import org.apache.http.HttpHost;
import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.HttpInetSocketAddress; import org.apache.http.conn.HttpInetSocketAddress;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.params.HttpParams; import org.apache.http.params.HttpParams;
/** /**
@ -42,7 +43,10 @@ import org.apache.http.params.HttpParams;
* for establishing a socket connection. * for establishing a socket connection.
* *
* @since 4.1 * @since 4.1
*
* @deprecated (4.3) use {@link ConnectionSocketFactory}
*/ */
@Deprecated
public interface SchemeSocketFactory { public interface SchemeSocketFactory {
/** /**

View File

@ -0,0 +1,87 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.conn.socket;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import org.apache.http.HttpHost;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.protocol.HttpContext;
/**
* A factory for creating and connecting sockets.
*
* @since 4.3
*/
public interface ConnectionSocketFactory {
/**
* Creates new, unconnected socket. The socket should subsequently be passed to
* {@link #connectSocket(Socket, SocketConfig, HttpHost, InetSocketAddress, InetSocketAddress,
* HttpContext))}.
*
* @return a new socket
*
* @throws IOException if an I/O error occurs while creating the socket
*/
Socket createSocket(HttpContext context) throws IOException;
/**
* Connects a socket to the target host with the given resolved remote address.
*
* @param connectTimeout connect timeout.
* @param sock the socket to connect, as obtained from {@link #createSocket(HttpContext)}.
* <code>null</code> indicates that a new socket should be created and connected.
* @param config Socket configuration. If <code>null</cpde> {@link SocketConfig#DEFAULT}
* will be used.
* @param host target host as specified by the caller (end user).
* @param remoteAddress the resolved remote address to connect to.
* @param localAddress the local address to bind the socket to, or <code>null</code> for any.
* @param context the actual HTTP context.
*
* @return the connected socket. The returned object may be different
* from the <code>sock</code> argument if this factory supports
* a layered protocol.
*
* @throws IOException if an I/O error occurs
* @throws ConnectTimeoutException if the socket cannot be connected
* within the time limit defined in the <code>params</code>
*/
Socket connectSocket(
int connectTimeout,
Socket sock,
SocketConfig config,
HttpHost host,
InetSocketAddress remoteAddress,
InetSocketAddress localAddress,
HttpContext context) throws IOException, ConnectTimeoutException;
}

View File

@ -0,0 +1,63 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.conn.socket;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import org.apache.http.protocol.HttpContext;
/**
* Extended {@link ConnectionSocketFactory} interface for layered sockets such as SSL/TLS.
*
* @since 4.3
*/
public interface LayeredConnectionSocketFactory extends ConnectionSocketFactory {
/**
* Returns a socket connected to the given host that is layered over an
* existing socket. Used primarily for creating secure sockets through
* proxies.
*
* @param socket the existing socket
* @param target the name of the target host.
* @param port the port to connect to on the target host.
* @param context the actual HTTP context.
*
* @return Socket a new socket
*
* @throws IOException if an I/O error occurs while creating the socket
*/
Socket createLayeredSocket(
Socket socket,
String target,
int port,
HttpContext context) throws IOException, UnknownHostException;
}

View File

@ -0,0 +1,91 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.conn.socket;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
import org.apache.http.HttpHost;
import org.apache.http.annotation.Immutable;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.protocol.HttpContext;
/**
* The default class for creating plain (unencrypted) sockets.
*
* @since 4.3
*/
@Immutable
public class PlainSocketFactory implements ConnectionSocketFactory {
public static final PlainSocketFactory INSTANCE = new PlainSocketFactory();
public static PlainSocketFactory getSocketFactory() {
return INSTANCE;
}
public PlainSocketFactory() {
super();
}
public Socket createSocket(final HttpContext context) throws IOException {
return new Socket();
}
public Socket connectSocket(
final int connectTimeout,
final Socket socket,
final SocketConfig config,
final HttpHost host,
final InetSocketAddress remoteAddress,
final InetSocketAddress localAddress,
final HttpContext context) throws IOException, ConnectTimeoutException {
Socket sock = socket != null ? socket : createSocket(context);
SocketConfig sconf = config != null ? config : SocketConfig.DEFAULT;
if (localAddress != null) {
sock.setReuseAddress(sconf.isSoReuseAddress());
sock.bind(localAddress);
}
try {
sock.setSoTimeout(sconf.getSoTimeout());
sock.connect(remoteAddress, connectTimeout);
} catch (SocketTimeoutException ex) {
throw new ConnectTimeoutException(host, remoteAddress);
}
sock.setTcpNoDelay(sconf.isTcpNoDelay());
int linger = sconf.getSoLinger();
if (linger >= 0) {
sock.setSoLinger(linger > 0, linger);
}
return sock;
}
}

View File

@ -30,14 +30,19 @@ package org.apache.http.conn.ssl;
import org.apache.http.HttpHost; import org.apache.http.HttpHost;
import org.apache.http.annotation.ThreadSafe; import org.apache.http.annotation.ThreadSafe;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.HttpInetSocketAddress; import org.apache.http.conn.HttpInetSocketAddress;
import org.apache.http.conn.scheme.HostNameResolver; import org.apache.http.conn.scheme.HostNameResolver;
import org.apache.http.conn.scheme.LayeredSchemeSocketFactory; import org.apache.http.conn.scheme.LayeredSchemeSocketFactory;
import org.apache.http.conn.scheme.LayeredSocketFactory; import org.apache.http.conn.scheme.LayeredSocketFactory;
import org.apache.http.conn.scheme.SchemeLayeredSocketFactory; import org.apache.http.conn.scheme.SchemeLayeredSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainSocketFactory;
import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParamConfig;
import org.apache.http.params.HttpParams; import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.KeyManagerFactory;
@ -53,7 +58,6 @@ import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.security.KeyManagementException; import java.security.KeyManagementException;
import java.security.KeyStore; import java.security.KeyStore;
@ -84,14 +88,6 @@ import java.security.cert.CertificateException;
* {@link TrustStrategy}. This interface is primarily intended for allowing self-signed * {@link TrustStrategy}. This interface is primarily intended for allowing self-signed
* certificates to be accepted as trusted without having to add them to the trust-store file. * certificates to be accepted as trusted without having to add them to the trust-store file.
* <p> * <p>
* The following parameters can be used to customize the behavior of this
* class:
* <ul>
* <li>{@link org.apache.http.params.CoreConnectionPNames#CONNECTION_TIMEOUT}</li>
* <li>{@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}</li>
* <li>{@link org.apache.http.params.CoreConnectionPNames#SO_REUSEADDR}</li>
* </ul>
* <p>
* SSLSocketFactory will enable client authentication when supplied with * SSLSocketFactory will enable client authentication when supplied with
* a {@link KeyStore key-store} file containing a private key/public certificate * a {@link KeyStore key-store} file containing a private key/public certificate
* pair. The client secure socket will use the private key to authenticate * pair. The client secure socket will use the private key to authenticate
@ -147,7 +143,7 @@ import java.security.cert.CertificateException;
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@ThreadSafe @ThreadSafe
public class SSLSocketFactory implements SchemeLayeredSocketFactory, public class SSLSocketFactory implements LayeredConnectionSocketFactory, SchemeLayeredSocketFactory,
LayeredSchemeSocketFactory, LayeredSocketFactory { LayeredSchemeSocketFactory, LayeredSocketFactory {
public static final String TLS = "TLS"; public static final String TLS = "TLS";
@ -242,7 +238,7 @@ public class SSLSocketFactory implements SchemeLayeredSocketFactory,
sslcontext.init(keymanagers, trustmanagers, random); sslcontext.init(keymanagers, trustmanagers, random);
return sslcontext; return sslcontext;
} }
private static SSLContext createSystemSSLContext( private static SSLContext createSystemSSLContext(
String algorithm, String algorithm,
final SecureRandom random) throws IOException, NoSuchAlgorithmException, NoSuchProviderException, final SecureRandom random) throws IOException, NoSuchAlgorithmException, NoSuchProviderException,
@ -370,7 +366,8 @@ public class SSLSocketFactory implements SchemeLayeredSocketFactory,
} }
/** /**
* @deprecated Use {@link #SSLSocketFactory(String, KeyStore, String, KeyStore, SecureRandom, X509HostnameVerifier)} * @deprecated (4.1) Use {@link #SSLSocketFactory(String, KeyStore, String, KeyStore,
* SecureRandom, X509HostnameVerifier)}
*/ */
@Deprecated @Deprecated
public SSLSocketFactory( public SSLSocketFactory(
@ -464,7 +461,7 @@ public class SSLSocketFactory implements SchemeLayeredSocketFactory,
} }
/** /**
* @deprecated Use {@link #SSLSocketFactory(SSLContext)} * @deprecated (4.1) Use {@link #SSLSocketFactory(SSLContext)}
*/ */
@Deprecated @Deprecated
public SSLSocketFactory( public SSLSocketFactory(
@ -493,7 +490,7 @@ public class SSLSocketFactory implements SchemeLayeredSocketFactory,
* @since 4.2 * @since 4.2
*/ */
public SSLSocketFactory( public SSLSocketFactory(
final javax.net.ssl.SSLSocketFactory socketfactory, final javax.net.ssl.SSLSocketFactory socketfactory,
final X509HostnameVerifier hostnameVerifier) { final X509HostnameVerifier hostnameVerifier) {
if (socketfactory == null) { if (socketfactory == null) {
throw new IllegalArgumentException("SSL socket factory may not be null"); throw new IllegalArgumentException("SSL socket factory may not be null");
@ -507,23 +504,29 @@ public class SSLSocketFactory implements SchemeLayeredSocketFactory,
* @param params Optional parameters. Parameters passed to this method will have no effect. * @param params Optional parameters. Parameters passed to this method will have no effect.
* This method will create a unconnected instance of {@link Socket} class. * This method will create a unconnected instance of {@link Socket} class.
* @since 4.1 * @since 4.1
*
* @deprecated (4.3) use {@link #createSocket(HttpContext)}
*/ */
@Deprecated
public Socket createSocket(final HttpParams params) throws IOException { public Socket createSocket(final HttpParams params) throws IOException {
SSLSocket sock = (SSLSocket) this.socketfactory.createSocket(); return createSocket((HttpContext) null);
prepareSocket(sock);
return sock;
} }
/**
* @deprecated (4.1) use {@link #createSocket(HttpParams)}
*/
@Deprecated @Deprecated
public Socket createSocket() throws IOException { public Socket createSocket() throws IOException {
SSLSocket sock = (SSLSocket) this.socketfactory.createSocket(); return createSocket((HttpContext) null);
prepareSocket(sock);
return sock;
} }
/** /**
* @since 4.1 * @since 4.1
*
* @deprecated (4.3) use {@link #connectSocket(Socket, SocketConfig, HttpHost,
* InetSocketAddress, InetSocketAddress, HttpContext)}
*/ */
@Deprecated
public Socket connectSocket( public Socket connectSocket(
final Socket socket, final Socket socket,
final InetSocketAddress remoteAddress, final InetSocketAddress remoteAddress,
@ -535,52 +538,17 @@ public class SSLSocketFactory implements SchemeLayeredSocketFactory,
if (params == null) { if (params == null) {
throw new IllegalArgumentException("HTTP parameters may not be null"); throw new IllegalArgumentException("HTTP parameters may not be null");
} }
Socket sock = socket != null ? socket : this.socketfactory.createSocket(); HttpHost host;
if (localAddress != null) {
sock.setReuseAddress(HttpConnectionParams.getSoReuseaddr(params));
sock.bind(localAddress);
}
int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
int soTimeout = HttpConnectionParams.getSoTimeout(params);
try {
sock.setSoTimeout(soTimeout);
sock.connect(remoteAddress, connTimeout);
} catch (SocketTimeoutException ex) {
throw new ConnectTimeoutException("Connect to " + remoteAddress + " timed out");
}
String hostname;
if (remoteAddress instanceof HttpInetSocketAddress) { if (remoteAddress instanceof HttpInetSocketAddress) {
hostname = ((HttpInetSocketAddress) remoteAddress).getHttpHost().getHostName(); host = ((HttpInetSocketAddress) remoteAddress).getHttpHost();
} else { } else {
hostname = remoteAddress.getHostName(); host = new HttpHost(remoteAddress.getHostName(), remoteAddress.getPort(), "https");
} }
int connectTimeout = HttpConnectionParams.getConnectionTimeout(params);
SSLSocket sslsock; SocketConfig config = HttpParamConfig.getSocketConfig(params);
// Setup SSL layering if necessary return connectSocket(connectTimeout, socket, config, host, remoteAddress, localAddress, null);
if (sock instanceof SSLSocket) {
sslsock = (SSLSocket) sock;
} else {
int port = remoteAddress.getPort();
sslsock = (SSLSocket) this.socketfactory.createSocket(sock, hostname, port, true);
prepareSocket(sslsock);
}
if (this.hostnameVerifier != null) {
try {
this.hostnameVerifier.verify(hostname, sslsock);
// verifyHostName() didn't blowup - good!
} catch (IOException iox) {
// close the socket before re-throwing the exception
try { sslsock.close(); } catch (Exception x) { /*ignore*/ }
throw iox;
}
}
return sslsock;
} }
/** /**
* Checks whether a socket connection is secure. * Checks whether a socket connection is secure.
* This factory creates TLS/SSL socket connections * This factory creates TLS/SSL socket connections
@ -594,7 +562,10 @@ public class SSLSocketFactory implements SchemeLayeredSocketFactory,
* @return <code>true</code> * @return <code>true</code>
* *
* @throws IllegalArgumentException if the argument is invalid * @throws IllegalArgumentException if the argument is invalid
*
* @deprecated (4.3) no longer used.
*/ */
@Deprecated
public boolean isSecure(final Socket sock) throws IllegalArgumentException { public boolean isSecure(final Socket sock) throws IllegalArgumentException {
if (sock == null) { if (sock == null) {
throw new IllegalArgumentException("Socket may not be null"); throw new IllegalArgumentException("Socket may not be null");
@ -612,48 +583,33 @@ public class SSLSocketFactory implements SchemeLayeredSocketFactory,
/** /**
* @since 4.2 * @since 4.2
*
* @deprecated (4.3) use {@link #createLayeredSocket(Socket, String, int, HttpContext)}
*/ */
@Deprecated
public Socket createLayeredSocket( public Socket createLayeredSocket(
final Socket socket, final Socket socket,
final String host, final String host,
final int port, final int port,
final HttpParams params) throws IOException, UnknownHostException { final HttpParams params) throws IOException, UnknownHostException {
SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket( return createLayeredSocket(socket, host, port, (HttpContext) null);
socket,
host,
port,
true);
prepareSocket(sslSocket);
if (this.hostnameVerifier != null) {
this.hostnameVerifier.verify(host, sslSocket);
}
// verifyHostName() didn't blowup - good!
return sslSocket;
} }
/** /**
* @deprecated use {@link #createLayeredSocket(Socket, String, int, HttpParams)} * @deprecated (4.1) use {@link #createLayeredSocket(Socket, String, int, HttpParams)}
*/ */
@Deprecated @Deprecated
public Socket createLayeredSocket( public Socket createLayeredSocket(
final Socket socket, final Socket socket,
final String host, final String host,
final int port, final int port,
final boolean autoClose) throws IOException, UnknownHostException { final boolean autoClose) throws IOException, UnknownHostException {
SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket( return createLayeredSocket(socket, host, port, (HttpContext) null);
socket,
host,
port,
autoClose
);
prepareSocket(sslSocket);
if (this.hostnameVerifier != null) {
this.hostnameVerifier.verify(host, sslSocket);
}
// verifyHostName() didn't blowup - good!
return sslSocket;
} }
/**
* @deprecated (4.1) use constructor.
*/
@Deprecated @Deprecated
public void setHostnameVerifier(X509HostnameVerifier hostnameVerifier) { public void setHostnameVerifier(X509HostnameVerifier hostnameVerifier) {
if ( hostnameVerifier == null ) { if ( hostnameVerifier == null ) {
@ -667,34 +623,36 @@ public class SSLSocketFactory implements SchemeLayeredSocketFactory,
} }
/** /**
* @deprecated Use {@link #connectSocket(Socket, InetSocketAddress, InetSocketAddress, HttpParams)} * @deprecated (4.1) Use {@link #connectSocket(Socket, InetSocketAddress, InetSocketAddress,
* HttpParams)}
*/ */
@Deprecated @Deprecated
public Socket connectSocket( public Socket connectSocket(
final Socket socket, final Socket socket,
final String host, int port, final String host, int port,
final InetAddress localAddress, int localPort, final InetAddress local, int localPort,
final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
InetSocketAddress local = null; InetAddress remote;
if (localAddress != null || localPort > 0) { if (this.nameResolver != null) {
remote = this.nameResolver.resolve(host);
} else {
remote = InetAddress.getByName(host);
}
InetSocketAddress localAddress = null;
if (local != null || localPort > 0) {
// we need to bind explicitly // we need to bind explicitly
if (localPort < 0) { if (localPort < 0) {
localPort = 0; // indicates "any" localPort = 0; // indicates "any"
} }
local = new InetSocketAddress(localAddress, localPort); localAddress = new InetSocketAddress(local, localPort);
} }
InetAddress remoteAddress; InetSocketAddress remoteAddress = new HttpInetSocketAddress(
if (this.nameResolver != null) { new HttpHost(host, port), remote, port);
remoteAddress = this.nameResolver.resolve(host); return connectSocket(socket, remoteAddress, localAddress, params);
} else {
remoteAddress = InetAddress.getByName(host);
}
InetSocketAddress remote = new HttpInetSocketAddress(new HttpHost(host, port), remoteAddress, port);
return connectSocket(socket, remote, local, params);
} }
/** /**
* @deprecated Use {@link #createLayeredSocket(Socket, String, int, boolean)} * @deprecated (4.1) Use {@link #createLayeredSocket(Socket, String, int, boolean)}
*/ */
@Deprecated @Deprecated
public Socket createSocket( public Socket createSocket(
@ -715,4 +673,75 @@ public class SSLSocketFactory implements SchemeLayeredSocketFactory,
*/ */
protected void prepareSocket(final SSLSocket socket) throws IOException { protected void prepareSocket(final SSLSocket socket) throws IOException {
} }
/**
* {@inheritDoc}
*
* @since 4.3
*/
public Socket createSocket(final HttpContext context) throws IOException {
SSLSocket sock = (SSLSocket) this.socketfactory.createSocket();
prepareSocket(sock);
return sock;
}
/**
* {@inheritDoc}
*
* @since 4.3
*/
public Socket connectSocket(
final int connectTimeout,
final Socket socket,
final SocketConfig config,
final HttpHost host,
final InetSocketAddress remoteAddress,
final InetSocketAddress localAddress,
final HttpContext context) throws IOException, ConnectTimeoutException {
if (host == null) {
throw new IllegalArgumentException("HTTP host may not be null");
}
if (remoteAddress == null) {
throw new IllegalArgumentException("Remote address may not be null");
}
Socket sock = socket != null ? socket : createSocket(context);
PlainSocketFactory.INSTANCE.connectSocket(
connectTimeout, socket, config, host, remoteAddress, localAddress, context);
// Setup SSL layering if necessary
if (sock instanceof SSLSocket) {
verifyHostname((SSLSocket) sock, host.getHostName());
} else {
sock = createLayeredSocket(sock, host.getHostName(), remoteAddress.getPort(), context);
}
return sock;
}
public Socket createLayeredSocket(
final Socket socket,
final String target,
int port,
final HttpContext context) throws IOException, UnknownHostException {
SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket(
socket,
target,
port,
true);
prepareSocket(sslSocket);
verifyHostname(sslSocket, target);
return sslSocket;
}
private void verifyHostname(final SSLSocket sslsock, final String hostname) throws IOException {
if (this.hostnameVerifier != null) {
try {
this.hostnameVerifier.verify(hostname, sslsock);
// verifyHostName() didn't blowup - good!
} catch (IOException iox) {
// close the socket before re-throwing the exception
try { sslsock.close(); } catch (Exception x) { /*ignore*/ }
throw iox;
}
}
}
} }