From 8de26bac03997f86230d3e0d3a08178588eff9f8 Mon Sep 17 00:00:00 2001 From: Oleg Kalnichevski Date: Wed, 7 Apr 2010 17:28:15 +0000 Subject: [PATCH] HTTPCLIENT-898: Refactored socket factory API (new socket factory interfaces are better suited for multihome hosts) git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@931624 13f79535-47bb-0310-9956-ffa450edef68 --- .../http/conn/ClientConnectionOperator.java | 4 +- .../conn/MultihomePlainSocketFactory.java | 5 + .../http/conn/scheme/HostNameResolver.java | 3 + .../scheme/LayeredSchemeSocketFactory.java | 66 ++++++ .../LayeredSchemeSocketFactoryAdaptor.java | 52 ++++ .../conn/scheme/LayeredSocketFactory.java | 3 + .../scheme/LayeredSocketFactoryAdaptor.java | 50 ++++ .../http/conn/scheme/PlainSocketFactory.java | 86 ++++--- .../org/apache/http/conn/scheme/Scheme.java | 124 ++++++---- .../http/conn/scheme/SchemeSocketFactory.java | 110 +++++++++ .../scheme/SchemeSocketFactoryAdaptor.java | 93 ++++++++ .../http/conn/scheme/SocketFactory.java | 3 + .../conn/scheme/SocketFactoryAdaptor.java | 95 ++++++++ .../http/conn/ssl/SSLSocketFactory.java | 223 +++++++++++------- .../http/impl/client/DefaultHttpClient.java | 4 +- .../http/impl/client/RedirectLocations.java | 2 +- .../conn/DefaultClientConnectionOperator.java | 32 ++- .../tsccm/ThreadSafeClientConnManager.java | 2 +- .../apache/http/conn/TestConnectionReuse.java | 18 +- .../java/org/apache/http/conn/TestScheme.java | 68 ++---- .../apache/http/conn/scheme/TestScheme.java | 2 +- .../http/conn/ssl/TestSSLSocketFactory.java | 5 +- .../http/impl/client/TestContentCodings.java | 2 +- .../TestDefaultClientRequestDirector.java | 12 +- .../impl/client/TestRequestRetryHandler.java | 6 +- .../impl/conn/TestProxySelRoutePlanner.java | 7 +- .../http/impl/conn/TestTSCCMNoServer.java | 4 +- .../http/impl/conn/TestTSCCMWithServer.java | 41 ++-- .../impl/conn/tsccm/TestSpuriousWakeup.java | 6 +- .../http/localserver/ServerTestBase.java | 13 +- .../mockup/SecureSocketFactoryMockup.java | 13 +- .../http/mockup/SocketFactoryMockup.java | 25 +- src/docbkx/connmgmt.xml | 45 ++-- 33 files changed, 907 insertions(+), 317 deletions(-) create mode 100644 httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSchemeSocketFactory.java create mode 100644 httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSchemeSocketFactoryAdaptor.java create mode 100644 httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSocketFactoryAdaptor.java create mode 100644 httpclient/src/main/java/org/apache/http/conn/scheme/SchemeSocketFactory.java create mode 100644 httpclient/src/main/java/org/apache/http/conn/scheme/SchemeSocketFactoryAdaptor.java create mode 100644 httpclient/src/main/java/org/apache/http/conn/scheme/SocketFactoryAdaptor.java diff --git a/httpclient/src/main/java/org/apache/http/conn/ClientConnectionOperator.java b/httpclient/src/main/java/org/apache/http/conn/ClientConnectionOperator.java index f4cee1852..650aeefaf 100644 --- a/httpclient/src/main/java/org/apache/http/conn/ClientConnectionOperator.java +++ b/httpclient/src/main/java/org/apache/http/conn/ClientConnectionOperator.java @@ -32,7 +32,7 @@ import java.net.InetAddress; import java.net.Socket; import org.apache.http.HttpHost; -import org.apache.http.conn.scheme.SocketFactory; +import org.apache.http.conn.scheme.SchemeSocketFactory; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; @@ -40,7 +40,7 @@ import org.apache.http.protocol.HttpContext; * ClientConnectionOperator represents a strategy for creating * {@link OperatedClientConnection} instances and updating the underlying * {@link Socket} of those objects. Implementations will most likely make use - * of {@link SocketFactory}s to create {@link Socket} instances. + * of {@link SchemeSocketFactory}s to create {@link Socket} instances. *

* The methods in this interface allow the creation of plain and layered * sockets. Creating a tunnelled connection through a proxy, however, diff --git a/httpclient/src/main/java/org/apache/http/conn/MultihomePlainSocketFactory.java b/httpclient/src/main/java/org/apache/http/conn/MultihomePlainSocketFactory.java index bedd80458..d82aa734f 100644 --- a/httpclient/src/main/java/org/apache/http/conn/MultihomePlainSocketFactory.java +++ b/httpclient/src/main/java/org/apache/http/conn/MultihomePlainSocketFactory.java @@ -39,6 +39,7 @@ import java.util.Arrays; import org.apache.http.annotation.Immutable; +import org.apache.http.conn.scheme.SchemeSocketFactory; import org.apache.http.conn.scheme.SocketFactory; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; @@ -51,7 +52,11 @@ import org.apache.http.params.HttpParams; * {@link #createSocket()} method. * * @since 4.0 + * + * @deprecated Do not use. For multihome support socket factories must implement + * {@link SchemeSocketFactory} interface. */ +@Deprecated @Immutable public final class MultihomePlainSocketFactory implements SocketFactory { diff --git a/httpclient/src/main/java/org/apache/http/conn/scheme/HostNameResolver.java b/httpclient/src/main/java/org/apache/http/conn/scheme/HostNameResolver.java index 2e7a5bd55..908fe221e 100644 --- a/httpclient/src/main/java/org/apache/http/conn/scheme/HostNameResolver.java +++ b/httpclient/src/main/java/org/apache/http/conn/scheme/HostNameResolver.java @@ -34,7 +34,10 @@ import java.net.InetAddress; * Hostname to IP address resolver. * * @since 4.0 + * + * @deprecated Do not use */ +@Deprecated public interface HostNameResolver { /** diff --git a/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSchemeSocketFactory.java b/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSchemeSocketFactory.java new file mode 100644 index 000000000..867b36dc6 --- /dev/null +++ b/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSchemeSocketFactory.java @@ -0,0 +1,66 @@ +/* + * ==================================================================== + * 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 + * . + * + */ + +package org.apache.http.conn.scheme; + +import java.io.IOException; +import java.net.Socket; +import java.net.UnknownHostException; + +/** + * A {@link SocketFactory SocketFactory} for layered sockets (SSL/TLS). + * See there for things to consider when implementing a socket factory. + * + * @since 4.1 + */ +public interface LayeredSchemeSocketFactory extends SchemeSocketFactory { + + /** + * 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 autoClose a flag for closing the underling socket when the created + * socket is closed + * + * @return Socket a new socket + * + * @throws IOException if an I/O error occurs while creating the socket + * @throws UnknownHostException if the IP address of the host cannot be + * determined + */ + Socket createLayeredSocket( + Socket socket, + String target, + int port, + boolean autoClose + ) throws IOException, UnknownHostException; + +} diff --git a/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSchemeSocketFactoryAdaptor.java b/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSchemeSocketFactoryAdaptor.java new file mode 100644 index 000000000..f5cfdafc8 --- /dev/null +++ b/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSchemeSocketFactoryAdaptor.java @@ -0,0 +1,52 @@ +/* + * ==================================================================== + * 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 + * . + * + */ + +package org.apache.http.conn.scheme; + +import java.io.IOException; +import java.net.Socket; +import java.net.UnknownHostException; + +@Deprecated +class LayeredSchemeSocketFactoryAdaptor extends SchemeSocketFactoryAdaptor + implements LayeredSchemeSocketFactory { + + private final LayeredSocketFactory factory; + + LayeredSchemeSocketFactoryAdaptor(final LayeredSocketFactory factory) { + super(factory); + this.factory = factory; + } + + public Socket createLayeredSocket( + final Socket socket, + final String target, int port, + boolean autoClose) throws IOException, UnknownHostException { + return this.factory.createSocket(socket, target, port, autoClose); + } + +} diff --git a/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSocketFactory.java b/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSocketFactory.java index 5be9640a2..f26030689 100644 --- a/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSocketFactory.java +++ b/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSocketFactory.java @@ -36,7 +36,10 @@ import java.net.UnknownHostException; * See there for things to consider when implementing a socket factory. * * @since 4.0 + * + * @deprecated use {@link SchemeSocketFactory} */ +@Deprecated public interface LayeredSocketFactory extends SocketFactory { /** diff --git a/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSocketFactoryAdaptor.java b/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSocketFactoryAdaptor.java new file mode 100644 index 000000000..9e3101fde --- /dev/null +++ b/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSocketFactoryAdaptor.java @@ -0,0 +1,50 @@ +/* + * ==================================================================== + * 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 + * . + * + */ + +package org.apache.http.conn.scheme; + +import java.io.IOException; +import java.net.Socket; +import java.net.UnknownHostException; + +@Deprecated +class LayeredSocketFactoryAdaptor extends SocketFactoryAdaptor implements LayeredSocketFactory { + + private final LayeredSchemeSocketFactory factory; + + LayeredSocketFactoryAdaptor(final LayeredSchemeSocketFactory factory) { + super(factory); + this.factory = factory; + } + + public Socket createSocket( + final Socket socket, + final String host, int port, boolean autoClose) throws IOException, UnknownHostException { + return this.factory.createLayeredSocket(socket, host, port, autoClose); + } + +} diff --git a/httpclient/src/main/java/org/apache/http/conn/scheme/PlainSocketFactory.java b/httpclient/src/main/java/org/apache/http/conn/scheme/PlainSocketFactory.java index 0ffda1ccf..99b1bba15 100644 --- a/httpclient/src/main/java/org/apache/http/conn/scheme/PlainSocketFactory.java +++ b/httpclient/src/main/java/org/apache/http/conn/scheme/PlainSocketFactory.java @@ -32,6 +32,7 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketTimeoutException; +import java.net.UnknownHostException; import org.apache.http.annotation.Immutable; @@ -50,14 +51,14 @@ import org.apache.http.params.HttpParams; * * @since 4.0 */ +@SuppressWarnings("deprecation") @Immutable -public final class PlainSocketFactory implements SocketFactory { +public final class PlainSocketFactory implements SocketFactory, SchemeSocketFactory { /** * The default factory. */ - private static final - PlainSocketFactory DEFAULT_FACTORY = new PlainSocketFactory(); + private static final PlainSocketFactory DEFAULT_FACTORY = new PlainSocketFactory(); private final HostNameResolver nameResolver; @@ -71,58 +72,48 @@ public final class PlainSocketFactory implements SocketFactory { return DEFAULT_FACTORY; } + @Deprecated public PlainSocketFactory(final HostNameResolver nameResolver) { super(); this.nameResolver = nameResolver; } - public PlainSocketFactory() { - this(null); + super(); + this.nameResolver = null; } public Socket createSocket() { return new Socket(); } - public Socket connectSocket(Socket sock, String host, int port, - InetAddress localAddress, int localPort, - HttpParams params) - throws IOException { - - if (host == null) { - throw new IllegalArgumentException("Target host may not be null."); + /** + * @since 4.1 + */ + public Socket connectSocket( + final Socket socket, + final InetSocketAddress remoteAddress, + final InetSocketAddress localAddress, + final HttpParams params) throws IOException, ConnectTimeoutException { + if (remoteAddress == null) { + throw new IllegalArgumentException("Remote address may not be null"); } if (params == null) { - throw new IllegalArgumentException("Parameters may not be null."); + throw new IllegalArgumentException("HTTP parameters may not be null"); } - - if (sock == null) + Socket sock = socket; + if (sock == null) { sock = createSocket(); - - if ((localAddress != null) || (localPort > 0)) { - - // we need to bind explicitly - if (localPort < 0) - localPort = 0; // indicates "any" - - InetSocketAddress isa = - new InetSocketAddress(localAddress, localPort); - sock.bind(isa); } - + if (localAddress != null) { + sock.bind(localAddress); + } int timeout = HttpConnectionParams.getConnectionTimeout(params); - - InetSocketAddress remoteAddress; - if (this.nameResolver != null) { - remoteAddress = new InetSocketAddress(this.nameResolver.resolve(host), port); - } else { - remoteAddress = new InetSocketAddress(host, port); - } try { sock.connect(remoteAddress, timeout); } catch (SocketTimeoutException ex) { - throw new ConnectTimeoutException("Connect to " + remoteAddress + " timed out"); + throw new ConnectTimeoutException("Connect to " + remoteAddress.getHostName() + "/" + + remoteAddress.getAddress() + " timed out"); } return sock; } @@ -152,4 +143,31 @@ public final class PlainSocketFactory implements SocketFactory { return false; } + /** + * @deprecated Use {@link #connectSocket(Socket, InetSocketAddress, InetSocketAddress, HttpParams)} + */ + @Deprecated + public Socket connectSocket( + final Socket socket, + final String host, int port, + final InetAddress localAddress, int localPort, + final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { + InetSocketAddress local = null; + if (localAddress != null || localPort > 0) { + // we need to bind explicitly + if (localPort < 0) { + localPort = 0; // indicates "any" + } + local = new InetSocketAddress(localAddress, localPort); + } + InetAddress remoteAddress; + if (this.nameResolver != null) { + remoteAddress = this.nameResolver.resolve(host); + } else { + remoteAddress = InetAddress.getByName(host); + } + InetSocketAddress remote = new InetSocketAddress(remoteAddress, port); + return connectSocket(socket, remote, local, params); + } + } diff --git a/httpclient/src/main/java/org/apache/http/conn/scheme/Scheme.java b/httpclient/src/main/java/org/apache/http/conn/scheme/Scheme.java index 21bfe46ab..f4e4786b2 100644 --- a/httpclient/src/main/java/org/apache/http/conn/scheme/Scheme.java +++ b/httpclient/src/main/java/org/apache/http/conn/scheme/Scheme.java @@ -33,21 +33,16 @@ import org.apache.http.annotation.Immutable; import org.apache.http.util.LangUtils; /** - * Encapsulates specifics of a protocol scheme such as "http" or "https". - * Schemes are identified by lowercase names. - * Supported schemes are typically collected in a - * {@link SchemeRegistry SchemeRegistry}. - * + * Encapsulates specifics of a protocol scheme such as "http" or "https". Schemes are identified + * by lowercase names. Supported schemes are typically collected in a {@link SchemeRegistry + * SchemeRegistry}. *

- * For example, to configure support for "https://" URLs, - * you could write code like the following: - *

+ * For example, to configure support for "https://" URLs, you could write code like the following: *
- * Scheme https = new Scheme("https", new MySecureSocketFactory(), 443);
+ * Scheme https = new Scheme("https", 443, new MySecureSocketFactory());
  * SchemeRegistry.DEFAULT.register(https);
  * 
* - * * @since 4.0 */ @Immutable @@ -57,7 +52,7 @@ public final class Scheme { private final String name; /** The socket factory for this scheme */ - private final SocketFactory socketFactory; + private final SchemeSocketFactory socketFactory; /** The default port for this scheme */ private final int defaultPort; @@ -65,7 +60,6 @@ public final class Scheme { /** Indicates whether this scheme allows for layered connections */ private final boolean layered; - /** A string representation, for {@link #toString toString}. */ private String stringRep; /* @@ -74,6 +68,34 @@ public final class Scheme { * need to synchronize, and it does not affect immutability. */ + /** + * Creates a new scheme. + * Whether the created scheme allows for layered connections + * depends on the class of factory. + * + * @param name the scheme name, for example "http". + * The name will be converted to lowercase. + * @param port the default port for this scheme + * @param factory the factory for creating sockets for communication + * with this scheme + * + * @since 4.1 + */ + public Scheme(final String name, final int port, final SchemeSocketFactory factory) { + if (name == null) { + throw new IllegalArgumentException("Scheme name may not be null"); + } + if ((port <= 0) || (port > 0xffff)) { + throw new IllegalArgumentException("Port is invalid: " + port); + } + if (factory == null) { + throw new IllegalArgumentException("Socket factory may not be null"); + } + this.name = name.toLowerCase(Locale.ENGLISH); + this.socketFactory = factory; + this.defaultPort = port; + this.layered = factory instanceof LayeredSchemeSocketFactory; + } /** * Creates a new scheme. @@ -85,7 +107,10 @@ public final class Scheme { * @param factory the factory for creating sockets for communication * with this scheme * @param port the default port for this scheme + * + * @deprecated Use {@link #Scheme(String, int, SchemeSocketFactory)} */ + @Deprecated public Scheme(final String name, final SocketFactory factory, final int port) { @@ -104,12 +129,17 @@ public final class Scheme { } this.name = name.toLowerCase(Locale.ENGLISH); - this.socketFactory = factory; + if (factory instanceof LayeredSocketFactory) { + this.socketFactory = new LayeredSchemeSocketFactoryAdaptor( + (LayeredSocketFactory) factory); + this.layered = true; + } else { + this.socketFactory = new SchemeSocketFactoryAdaptor(factory); + this.layered = false; + } this.defaultPort = port; - this.layered = (factory instanceof LayeredSocketFactory); } - /** * Obtains the default port. * @@ -126,11 +156,35 @@ public final class Scheme { * {@link LayeredSocketFactory LayeredSocketFactory}. * * @return the socket factory for this scheme + * + * @deprecated Use {@link #getSchemeSocketFactory()} */ + @Deprecated public final SocketFactory getSocketFactory() { - return socketFactory; + if (this.socketFactory instanceof SchemeSocketFactoryAdaptor) { + return ((SchemeSocketFactoryAdaptor) this.socketFactory).getFactory(); + } else { + if (this.layered) { + return new LayeredSocketFactoryAdaptor( + (LayeredSchemeSocketFactory) this.socketFactory); + } else { + return new SocketFactoryAdaptor(this.socketFactory); + } + } } + /** + * Obtains the socket factory. + * If this scheme is {@link #isLayered layered}, the factory implements + * {@link LayeredSocketFactory LayeredSchemeSocketFactory}. + * + * @return the socket factory for this scheme + * + * @since 4.1 + */ + public final SchemeSocketFactory getSchemeSocketFactory() { + return this.socketFactory; + } /** * Obtains the scheme name. @@ -141,7 +195,6 @@ public final class Scheme { return name; } - /** * Indicates whether this scheme allows for layered connections. * @@ -152,7 +205,6 @@ public final class Scheme { return layered; } - /** * Resolves the correct port for this scheme. * Returns the given port if it is valid, the default port otherwise. @@ -166,7 +218,6 @@ public final class Scheme { return port <= 0 ? defaultPort : port; } - /** * Return a string representation of this object. * @@ -184,34 +235,21 @@ public final class Scheme { return stringRep; } - - /** - * Compares this scheme to an object. - * - * @param obj the object to compare with - * - * @return true iff the argument is equal to this scheme - */ @Override public final boolean equals(Object obj) { if (obj == null) return false; if (this == obj) return true; - if (!(obj instanceof Scheme)) return false; + if (obj instanceof Scheme) { + Scheme that = (Scheme) obj; + return this.name.equals(that.name) + && this.defaultPort == that.defaultPort + && this.layered == that.layered + && this.socketFactory.equals(that.socketFactory); + } else { + return false; + } + } - Scheme s = (Scheme) obj; - return (name.equals(s.name) && - defaultPort == s.defaultPort && - layered == s.layered && - socketFactory.equals(s.socketFactory) - ); - } // equals - - - /** - * Obtains a hash code for this scheme. - * - * @return the hash code - */ @Override public int hashCode() { int hash = LangUtils.HASH_SEED; @@ -222,4 +260,4 @@ public final class Scheme { return hash; } -} // class Scheme +} diff --git a/httpclient/src/main/java/org/apache/http/conn/scheme/SchemeSocketFactory.java b/httpclient/src/main/java/org/apache/http/conn/scheme/SchemeSocketFactory.java new file mode 100644 index 000000000..cc30e6571 --- /dev/null +++ b/httpclient/src/main/java/org/apache/http/conn/scheme/SchemeSocketFactory.java @@ -0,0 +1,110 @@ +/* + * ==================================================================== + * 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 + * . + * + */ + +package org.apache.http.conn.scheme; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.UnknownHostException; + +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.params.HttpParams; + +/** + * A factory for creating, initializing and connecting sockets. The factory encapsulates the logic + * for establishing a socket connection. + * + * @since 4.1 + */ +public interface SchemeSocketFactory { + + /** + * Creates a new, unconnected socket. The socket should subsequently be passed to + * {@link #connectSocket(Socket, InetSocketAddress, InetSocketAddress, HttpParams)}. + * + * @return a new socket + * + * @throws IOException if an I/O error occurs while creating the socket + */ + Socket createSocket() throws IOException; + + /** + * Connects a socket to the target host with the given remote address. + * + * @param sock the socket to connect, as obtained from + * {@link #createSocket() createSocket}. + * null indicates that a new socket + * should be created and connected. + * @param remoteAddress the remote address to connect to + * @param localAddress the local address to bind the socket to, or + * null for any + * @param params additional {@link HttpParams parameters} for connecting + * + * @return the connected socket. The returned object may be different + * from the sock argument if this factory supports + * a layered protocol. + * + * @throws IOException if an I/O error occurs + * @throws UnknownHostException if the IP address of the target host + * can not be determined + * @throws ConnectTimeoutException if the socket cannot be connected + * within the time limit defined in the params + */ + Socket connectSocket( + Socket sock, + InetSocketAddress remoteAddress, + InetSocketAddress localAddress, + HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException; + + /** + * Checks whether a socket provides a secure connection. The socket must be + * {@link #connectSocket(Socket, InetSocketAddress, InetSocketAddress, HttpParams) connected} + * by this factory. The factory will not perform I/O operations in this method. + *

+ * As a rule of thumb, plain sockets are not secure and TLS/SSL sockets are secure. However, + * there may be application specific deviations. For example, a plain socket to a host in the + * same intranet ("trusted zone") could be considered secure. On the other hand, a TLS/SSL + * socket could be considered insecure based on the cipher suite chosen for the connection. + * + * @param sock the connected socket to check + * + * @return true if the connection of the socket + * should be considered secure, or + * false if it should not + * + * @throws IllegalArgumentException + * if the argument is invalid, for example because it is + * not a connected socket or was created by a different + * socket factory. + * Note that socket factories are not required to + * check these conditions, they may simply return a default + * value when called with an invalid socket argument. + */ + boolean isSecure(Socket sock) throws IllegalArgumentException; + +} diff --git a/httpclient/src/main/java/org/apache/http/conn/scheme/SchemeSocketFactoryAdaptor.java b/httpclient/src/main/java/org/apache/http/conn/scheme/SchemeSocketFactoryAdaptor.java new file mode 100644 index 000000000..8b02e4e0c --- /dev/null +++ b/httpclient/src/main/java/org/apache/http/conn/scheme/SchemeSocketFactoryAdaptor.java @@ -0,0 +1,93 @@ +/* + * ==================================================================== + * 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 + * . + * + */ + +package org.apache.http.conn.scheme; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.UnknownHostException; + +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.params.HttpParams; + +@Deprecated +class SchemeSocketFactoryAdaptor implements SchemeSocketFactory { + + private final SocketFactory factory; + + SchemeSocketFactoryAdaptor(final SocketFactory factory) { + super(); + this.factory = factory; + } + + public Socket connectSocket( + final Socket sock, + final InetSocketAddress remoteAddress, + final InetSocketAddress localAddress, + final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { + String host = remoteAddress.getHostName(); + int port = remoteAddress.getPort(); + InetAddress local = null; + int localPort = 0; + if (localAddress != null) { + local = localAddress.getAddress(); + localPort = localAddress.getPort(); + } + return this.factory.connectSocket(sock, host, port, local, localPort, params); + } + + public Socket createSocket() throws IOException { + return this.factory.createSocket(); + } + + public boolean isSecure(final Socket sock) throws IllegalArgumentException { + return this.factory.isSecure(sock); + } + + public SocketFactory getFactory() { + return this.factory; + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) return false; + if (this == obj) return true; + if (obj instanceof SchemeSocketFactoryAdaptor) { + return this.factory.equals(((SchemeSocketFactoryAdaptor)obj).factory); + } else { + return this.factory.equals(obj); + } + } + + @Override + public int hashCode() { + return this.factory.hashCode(); + } + +} diff --git a/httpclient/src/main/java/org/apache/http/conn/scheme/SocketFactory.java b/httpclient/src/main/java/org/apache/http/conn/scheme/SocketFactory.java index 6ae099430..162ae4789 100644 --- a/httpclient/src/main/java/org/apache/http/conn/scheme/SocketFactory.java +++ b/httpclient/src/main/java/org/apache/http/conn/scheme/SocketFactory.java @@ -40,7 +40,10 @@ import org.apache.http.params.HttpParams; * The factory encapsulates the logic for establishing a socket connection. * * @since 4.0 + * + * @deprecated use {@link SchemeSocketFactory} */ +@Deprecated public interface SocketFactory { /** diff --git a/httpclient/src/main/java/org/apache/http/conn/scheme/SocketFactoryAdaptor.java b/httpclient/src/main/java/org/apache/http/conn/scheme/SocketFactoryAdaptor.java new file mode 100644 index 000000000..1d922214e --- /dev/null +++ b/httpclient/src/main/java/org/apache/http/conn/scheme/SocketFactoryAdaptor.java @@ -0,0 +1,95 @@ +/* + * ==================================================================== + * 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 + * . + * + */ + +package org.apache.http.conn.scheme; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.UnknownHostException; + +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.params.HttpParams; + +@Deprecated +class SocketFactoryAdaptor implements SocketFactory { + + private final SchemeSocketFactory factory; + + SocketFactoryAdaptor(final SchemeSocketFactory factory) { + super(); + this.factory = factory; + } + + public Socket createSocket() throws IOException { + return this.factory.createSocket(); + } + + public Socket connectSocket( + final Socket socket, + final String host, int port, + final InetAddress localAddress, int localPort, + final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { + InetSocketAddress local = null; + if (localAddress != null || localPort > 0) { + // we need to bind explicitly + if (localPort < 0) { + localPort = 0; // indicates "any" + } + local = new InetSocketAddress(localAddress, localPort); + } + InetAddress remoteAddress = InetAddress.getByName(host); + InetSocketAddress remote = new InetSocketAddress(remoteAddress, port); + return this.factory.connectSocket(socket, remote, local, params); + } + + public boolean isSecure(final Socket socket) throws IllegalArgumentException { + return this.factory.isSecure(socket); + } + + public SchemeSocketFactory getFactory() { + return this.factory; + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) return false; + if (this == obj) return true; + if (obj instanceof SocketFactoryAdaptor) { + return this.factory.equals(((SocketFactoryAdaptor)obj).factory); + } else { + return this.factory.equals(obj); + } + } + + @Override + public int hashCode() { + return this.factory.hashCode(); + } + +} diff --git a/httpclient/src/main/java/org/apache/http/conn/ssl/SSLSocketFactory.java b/httpclient/src/main/java/org/apache/http/conn/ssl/SSLSocketFactory.java index a8733afdd..420272830 100644 --- a/httpclient/src/main/java/org/apache/http/conn/ssl/SSLSocketFactory.java +++ b/httpclient/src/main/java/org/apache/http/conn/ssl/SSLSocketFactory.java @@ -27,10 +27,11 @@ package org.apache.http.conn.ssl; -import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.annotation.ThreadSafe; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.scheme.HostNameResolver; +import org.apache.http.conn.scheme.LayeredSchemeSocketFactory; import org.apache.http.conn.scheme.LayeredSocketFactory; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; @@ -144,8 +145,9 @@ import java.security.UnrecoverableKeyException; * * @since 4.0 */ -@NotThreadSafe // [gs]etHostNameVerifier -public class SSLSocketFactory implements LayeredSocketFactory { +@SuppressWarnings("deprecation") +@ThreadSafe +public class SSLSocketFactory implements LayeredSchemeSocketFactory, LayeredSocketFactory { public static final String TLS = "TLS"; public static final String SSL = "SSL"; @@ -178,10 +180,13 @@ public class SSLSocketFactory implements LayeredSocketFactory { private final SSLContext sslcontext; private final javax.net.ssl.SSLSocketFactory socketfactory; private final HostNameResolver nameResolver; - - // volatile is needed to guarantee thread-safety of the setter/getter methods under all usage scenarios - private volatile X509HostnameVerifier hostnameVerifier = BROWSER_COMPATIBLE_HOSTNAME_VERIFIER; + // TODO: make final + private volatile X509HostnameVerifier hostnameVerifier; + /** + * @deprecated Use {@link #SSLSocketFactory(String, KeyStore, String, KeyStore, SecureRandom, X509HostnameVerifier)} + */ + @Deprecated public SSLSocketFactory( String algorithm, final KeyStore keystore, @@ -206,42 +211,87 @@ public class SSLSocketFactory implements LayeredSocketFactory { this.sslcontext = SSLContext.getInstance(algorithm); this.sslcontext.init(keymanagers, trustmanagers, random); this.socketfactory = this.sslcontext.getSocketFactory(); + this.hostnameVerifier = BROWSER_COMPATIBLE_HOSTNAME_VERIFIER; this.nameResolver = nameResolver; } + /** + * @since 4.1 + */ + public SSLSocketFactory( + String algorithm, + final KeyStore keystore, + final String keystorePassword, + final KeyStore truststore, + final SecureRandom random, + final X509HostnameVerifier hostnameVerifier) + throws NoSuchAlgorithmException, KeyManagementException, + KeyStoreException, UnrecoverableKeyException { + super(); + if (algorithm == null) { + algorithm = TLS; + } + KeyManager[] keymanagers = null; + if (keystore != null) { + keymanagers = createKeyManagers(keystore, keystorePassword); + } + TrustManager[] trustmanagers = null; + if (truststore != null) { + trustmanagers = createTrustManagers(truststore); + } + this.sslcontext = SSLContext.getInstance(algorithm); + this.sslcontext.init(keymanagers, trustmanagers, random); + this.socketfactory = this.sslcontext.getSocketFactory(); + this.hostnameVerifier = hostnameVerifier; + this.nameResolver = null; + } + public SSLSocketFactory( final KeyStore keystore, final String keystorePassword, final KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { - this(TLS, keystore, keystorePassword, truststore, null, null); + this(TLS, keystore, keystorePassword, truststore, null, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); } public SSLSocketFactory(final KeyStore keystore, final String keystorePassword) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { - this(TLS, keystore, keystorePassword, null, null, null); + this(TLS, keystore, keystorePassword, null, null, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); } public SSLSocketFactory(final KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { - this(TLS, null, null, truststore, null, null); + this(TLS, null, null, truststore, null, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); } - public SSLSocketFactory( - final SSLContext sslContext, - final HostNameResolver nameResolver) - { + /** + * @deprecated Use {@link #SSLSocketFactory(SSLContext)} + */ + @Deprecated + public SSLSocketFactory(final SSLContext sslContext, final HostNameResolver nameResolver) { + super(); this.sslcontext = sslContext; this.socketfactory = this.sslcontext.getSocketFactory(); + this.hostnameVerifier = BROWSER_COMPATIBLE_HOSTNAME_VERIFIER; this.nameResolver = nameResolver; } - public SSLSocketFactory(final SSLContext sslContext) - { - this(sslContext, null); + /** + * @since 4.1 + */ + public SSLSocketFactory(final SSLContext sslContext, final X509HostnameVerifier hostnameVerifier) { + super(); + this.sslcontext = sslContext; + this.socketfactory = this.sslcontext.getSocketFactory(); + this.hostnameVerifier = hostnameVerifier; + this.nameResolver = null; + } + + public SSLSocketFactory(final SSLContext sslContext) { + this(sslContext, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); } /** @@ -278,72 +328,51 @@ public class SSLSocketFactory implements LayeredSocketFactory { return tmfactory.getTrustManagers(); } - - // non-javadoc, see interface org.apache.http.conn.SocketFactory @SuppressWarnings("cast") - public Socket createSocket() - throws IOException { - + public Socket createSocket() throws IOException { // the cast makes sure that the factory is working as expected return (SSLSocket) this.socketfactory.createSocket(); } - - // non-javadoc, see interface org.apache.http.conn.SocketFactory + /** + * @since 4.1 + */ public Socket connectSocket( - final Socket sock, - final String host, - final int port, - final InetAddress localAddress, - int localPort, - final HttpParams params - ) throws IOException { - - if (host == null) { - throw new IllegalArgumentException("Target host may not be null."); + final Socket sock, + final InetSocketAddress remoteAddress, + final InetSocketAddress localAddress, + final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { + if (remoteAddress == null) { + throw new IllegalArgumentException("Remote address may not be null"); } if (params == null) { - throw new IllegalArgumentException("Parameters may not be null."); + throw new IllegalArgumentException("HTTP parameters may not be null"); } - - SSLSocket sslsock = (SSLSocket) - ((sock != null) ? sock : createSocket()); - - if ((localAddress != null) || (localPort > 0)) { - - // we need to bind explicitly - if (localPort < 0) - localPort = 0; // indicates "any" - - InetSocketAddress isa = - new InetSocketAddress(localAddress, localPort); - sslsock.bind(isa); + SSLSocket sslsock = (SSLSocket) (sock != null ? sock : createSocket()); + if (localAddress != null) { + sslsock.bind(localAddress); } int connTimeout = HttpConnectionParams.getConnectionTimeout(params); int soTimeout = HttpConnectionParams.getSoTimeout(params); - InetSocketAddress remoteAddress; - if (this.nameResolver != null) { - remoteAddress = new InetSocketAddress(this.nameResolver.resolve(host), port); - } else { - remoteAddress = new InetSocketAddress(host, port); - } try { sslsock.connect(remoteAddress, connTimeout); } catch (SocketTimeoutException ex) { - throw new ConnectTimeoutException("Connect to " + remoteAddress + " timed out"); + throw new ConnectTimeoutException("Connect to " + remoteAddress.getHostName() + "/" + + remoteAddress.getAddress() + " timed out"); } sslsock.setSoTimeout(soTimeout); - try { - hostnameVerifier.verify(host, 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; + if (this.hostnameVerifier != null) { + try { + this.hostnameVerifier.verify(remoteAddress.getHostName(), 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; } @@ -362,45 +391,43 @@ public class SSLSocketFactory implements LayeredSocketFactory { * * @throws IllegalArgumentException if the argument is invalid */ - public boolean isSecure(Socket sock) - throws IllegalArgumentException { - + public boolean isSecure(final Socket sock) throws IllegalArgumentException { if (sock == null) { - throw new IllegalArgumentException("Socket may not be null."); + throw new IllegalArgumentException("Socket may not be null"); } // This instanceof check is in line with createSocket() above. if (!(sock instanceof SSLSocket)) { - throw new IllegalArgumentException - ("Socket not created by this factory."); + throw new IllegalArgumentException("Socket not created by this factory"); } // This check is performed last since it calls the argument object. if (sock.isClosed()) { - throw new IllegalArgumentException("Socket is closed."); + throw new IllegalArgumentException("Socket is closed"); } - return true; + } - } // isSecure - - - // non-javadoc, see interface LayeredSocketFactory - public Socket createSocket( + /** + * @since 4.1 + */ + public Socket createLayeredSocket( final Socket socket, final String host, final int port, - final boolean autoClose - ) throws IOException, UnknownHostException { + final boolean autoClose) throws IOException, UnknownHostException { SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket( socket, host, port, autoClose ); - hostnameVerifier.verify(host, sslSocket); + if (this.hostnameVerifier != null) { + this.hostnameVerifier.verify(host, sslSocket); + } // verifyHostName() didn't blowup - good! return sslSocket; } + @Deprecated public void setHostnameVerifier(X509HostnameVerifier hostnameVerifier) { if ( hostnameVerifier == null ) { throw new IllegalArgumentException("Hostname verifier may not be null"); @@ -409,7 +436,45 @@ public class SSLSocketFactory implements LayeredSocketFactory { } public X509HostnameVerifier getHostnameVerifier() { - return hostnameVerifier; + return this.hostnameVerifier; + } + + /** + * @deprecated Use {@link #connectSocket(Socket, InetSocketAddress, InetSocketAddress, HttpParams)} + */ + @Deprecated + public Socket connectSocket( + final Socket socket, + final String host, int port, + final InetAddress localAddress, int localPort, + final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { + InetSocketAddress local = null; + if (localAddress != null || localPort > 0) { + // we need to bind explicitly + if (localPort < 0) { + localPort = 0; // indicates "any" + } + local = new InetSocketAddress(localAddress, localPort); + } + InetAddress remoteAddress; + if (this.nameResolver != null) { + remoteAddress = this.nameResolver.resolve(host); + } else { + remoteAddress = InetAddress.getByName(host); + } + InetSocketAddress remote = new InetSocketAddress(remoteAddress, port); + return connectSocket(socket, remote, local, params); + } + + /** + * @deprecated Use {@link #createLayeredSocket(Socket, String, int, boolean)} + */ + @Deprecated + public Socket createSocket( + final Socket socket, + final String host, int port, + boolean autoClose) throws IOException, UnknownHostException { + return createLayeredSocket(socket, host, port, autoClose); } } diff --git a/httpclient/src/main/java/org/apache/http/impl/client/DefaultHttpClient.java b/httpclient/src/main/java/org/apache/http/impl/client/DefaultHttpClient.java index 6ec6b75ca..c667c6d61 100644 --- a/httpclient/src/main/java/org/apache/http/impl/client/DefaultHttpClient.java +++ b/httpclient/src/main/java/org/apache/http/impl/client/DefaultHttpClient.java @@ -221,9 +221,9 @@ public class DefaultHttpClient extends AbstractHttpClient { protected ClientConnectionManager createClientConnectionManager() { SchemeRegistry registry = new SchemeRegistry(); registry.register( - new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); registry.register( - new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); + new Scheme("https", 443, SSLSocketFactory.getSocketFactory())); ClientConnectionManager connManager = null; HttpParams params = getParams(); diff --git a/httpclient/src/main/java/org/apache/http/impl/client/RedirectLocations.java b/httpclient/src/main/java/org/apache/http/impl/client/RedirectLocations.java index 0a80d1301..94f54a1b4 100644 --- a/httpclient/src/main/java/org/apache/http/impl/client/RedirectLocations.java +++ b/httpclient/src/main/java/org/apache/http/impl/client/RedirectLocations.java @@ -86,7 +86,7 @@ public class RedirectLocations { } /** - * Returns all redirect {@Link URI}s in the order they were added to the collection. + * Returns all redirect {@link URI}s in the order they were added to the collection. * * @return list of all URIs * diff --git a/httpclient/src/main/java/org/apache/http/impl/conn/DefaultClientConnectionOperator.java b/httpclient/src/main/java/org/apache/http/impl/conn/DefaultClientConnectionOperator.java index 3c034ea9d..7286ecbb0 100644 --- a/httpclient/src/main/java/org/apache/http/impl/conn/DefaultClientConnectionOperator.java +++ b/httpclient/src/main/java/org/apache/http/impl/conn/DefaultClientConnectionOperator.java @@ -29,6 +29,7 @@ package org.apache.http.impl.conn; import java.io.IOException; import java.net.ConnectException; +import java.net.InetSocketAddress; import java.net.Socket; import java.net.InetAddress; @@ -42,14 +43,14 @@ import org.apache.http.protocol.HttpContext; import org.apache.http.conn.HttpHostConnectException; import org.apache.http.conn.OperatedClientConnection; import org.apache.http.conn.ClientConnectionOperator; -import org.apache.http.conn.scheme.LayeredSocketFactory; +import org.apache.http.conn.scheme.LayeredSchemeSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.conn.scheme.SocketFactory; +import org.apache.http.conn.scheme.SchemeSocketFactory; /** * Default implementation of a {@link ClientConnectionOperator}. It uses - * a {@link SchemeRegistry} to look up {@link SocketFactory} objects. + * a {@link SchemeRegistry} to look up {@link SchemeSocketFactory} objects. *

* The following parameters can be used to customize the behavior of this * class: @@ -113,16 +114,21 @@ public class DefaultClientConnectionOperator implements ClientConnectionOperator ("Connection must not be open."); } - final Scheme schm = schemeRegistry.getScheme(target.getSchemeName()); - final SocketFactory sf = schm.getSocketFactory(); + Scheme schm = schemeRegistry.getScheme(target.getSchemeName()); + SchemeSocketFactory sf = schm.getSchemeSocketFactory(); Socket sock = sf.createSocket(); conn.opening(sock, target); + InetAddress address = InetAddress.getByName(target.getHostName()); + int port = schm.resolvePort(target.getPort()); + InetSocketAddress remoteAddress = new InetSocketAddress(address, port); + InetSocketAddress localAddress = null; + if (local != null) { + localAddress = new InetSocketAddress(local, 0); + } try { - Socket connsock = sf.connectSocket(sock, target.getHostName(), - schm.resolvePort(target.getPort()), - local, 0, params); + Socket connsock = sf.connectSocket(sock, remoteAddress, localAddress, params); if (sock != connsock) { sock = connsock; conn.opening(sock, target); @@ -159,17 +165,17 @@ public class DefaultClientConnectionOperator implements ClientConnectionOperator } final Scheme schm = schemeRegistry.getScheme(target.getSchemeName()); - if (!(schm.getSocketFactory() instanceof LayeredSocketFactory)) { + if (!(schm.getSchemeSocketFactory() instanceof LayeredSchemeSocketFactory)) { throw new IllegalArgumentException ("Target scheme (" + schm.getName() + ") must have layered socket factory."); } - final LayeredSocketFactory lsf = (LayeredSocketFactory) schm.getSocketFactory(); - final Socket sock; + LayeredSchemeSocketFactory lsf = (LayeredSchemeSocketFactory) schm.getSchemeSocketFactory(); + Socket sock; try { - sock = lsf.createSocket - (conn.getSocket(), target.getHostName(), target.getPort(), true); + sock = lsf.createLayeredSocket( + conn.getSocket(), target.getHostName(), target.getPort(), true); } catch (ConnectException ex) { throw new HttpHostConnectException(target, ex); } diff --git a/httpclient/src/main/java/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java b/httpclient/src/main/java/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java index c6861e7b0..b42537962 100644 --- a/httpclient/src/main/java/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java +++ b/httpclient/src/main/java/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java @@ -135,7 +135,7 @@ public class ThreadSafeClientConnManager implements ClientConnectionManager { * * @return the connection pool to use * - * @deprecated use {@link #createConnectionPool(ConnPerRouteBean)} + * @deprecated use {@link #createConnectionPool()} */ @Deprecated protected AbstractConnPool createConnectionPool(final HttpParams params) { diff --git a/httpclient/src/test/java/org/apache/http/conn/TestConnectionReuse.java b/httpclient/src/test/java/org/apache/http/conn/TestConnectionReuse.java index 43b98f0ea..5944862a2 100644 --- a/httpclient/src/test/java/org/apache/http/conn/TestConnectionReuse.java +++ b/httpclient/src/test/java/org/apache/http/conn/TestConnectionReuse.java @@ -47,7 +47,7 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.conn.scheme.SocketFactory; +import org.apache.http.conn.scheme.SchemeSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.localserver.LocalTestServer; @@ -110,8 +110,8 @@ public class TestConnectionReuse extends TestCase { HttpConnectionParams.setStaleCheckingEnabled(params, false); SchemeRegistry supportedSchemes = new SchemeRegistry(); - SocketFactory sf = PlainSocketFactory.getSocketFactory(); - supportedSchemes.register(new Scheme("http", sf, 80)); + SchemeSocketFactory sf = PlainSocketFactory.getSocketFactory(); + supportedSchemes.register(new Scheme("http", 80, sf)); ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(supportedSchemes); mgr.setMaxTotalConnections(5); @@ -180,8 +180,8 @@ public class TestConnectionReuse extends TestCase { HttpConnectionParams.setStaleCheckingEnabled(params, false); SchemeRegistry supportedSchemes = new SchemeRegistry(); - SocketFactory sf = PlainSocketFactory.getSocketFactory(); - supportedSchemes.register(new Scheme("http", sf, 80)); + SchemeSocketFactory sf = PlainSocketFactory.getSocketFactory(); + supportedSchemes.register(new Scheme("http", 80, sf)); ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(supportedSchemes); mgr.setMaxTotalConnections(5); @@ -240,8 +240,8 @@ public class TestConnectionReuse extends TestCase { HttpConnectionParams.setStaleCheckingEnabled(params, false); SchemeRegistry supportedSchemes = new SchemeRegistry(); - SocketFactory sf = PlainSocketFactory.getSocketFactory(); - supportedSchemes.register(new Scheme("http", sf, 80)); + SchemeSocketFactory sf = PlainSocketFactory.getSocketFactory(); + supportedSchemes.register(new Scheme("http", 80, sf)); ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(supportedSchemes); mgr.setMaxTotalConnections(5); @@ -301,8 +301,8 @@ public class TestConnectionReuse extends TestCase { HttpConnectionParams.setStaleCheckingEnabled(params, false); SchemeRegistry supportedSchemes = new SchemeRegistry(); - SocketFactory sf = PlainSocketFactory.getSocketFactory(); - supportedSchemes.register(new Scheme("http", sf, 80)); + SchemeSocketFactory sf = PlainSocketFactory.getSocketFactory(); + supportedSchemes.register(new Scheme("http", 80, sf)); ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(supportedSchemes); mgr.setMaxTotalConnections(1); diff --git a/httpclient/src/test/java/org/apache/http/conn/TestScheme.java b/httpclient/src/test/java/org/apache/http/conn/TestScheme.java index ebf557a57..05f8b7336 100644 --- a/httpclient/src/test/java/org/apache/http/conn/TestScheme.java +++ b/httpclient/src/test/java/org/apache/http/conn/TestScheme.java @@ -61,48 +61,41 @@ public class TestScheme extends TestCase { } public void testConstructor() { - Scheme http = new Scheme - ("http", PlainSocketFactory.getSocketFactory(), 80); + Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory()); assertEquals("http", http.getName()); assertEquals(80, http.getDefaultPort()); - assertSame(PlainSocketFactory.getSocketFactory(), - http.getSocketFactory()); + assertSame(PlainSocketFactory.getSocketFactory(), http.getSchemeSocketFactory()); assertFalse(http.isLayered()); - Scheme https = new Scheme - ("https", SecureSocketFactoryMockup.INSTANCE, 443); - // ("https", SSLSocketFactory.getSocketFactory(), 443); + Scheme https = new Scheme("https", 443, SecureSocketFactoryMockup.INSTANCE); assertEquals("https", https.getName()); assertEquals(443, https.getDefaultPort()); - assertSame(//SSLSocketFactory.getSocketFactory() - SecureSocketFactoryMockup.INSTANCE, - https.getSocketFactory()); + assertSame(SecureSocketFactoryMockup.INSTANCE, https.getSchemeSocketFactory()); assertTrue(https.isLayered()); - Scheme hTtP = new Scheme - ("hTtP", PlainSocketFactory.getSocketFactory(), 80); + Scheme hTtP = new Scheme("hTtP", 80, PlainSocketFactory.getSocketFactory()); assertEquals("http", hTtP.getName()); // the rest is no different from above try { - new Scheme(null, PlainSocketFactory.getSocketFactory(), 80); + new Scheme(null, 80, PlainSocketFactory.getSocketFactory()); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { // expected } try { - new Scheme("http", null, 80); + new Scheme("http", 80, null); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { // expected } try { - new Scheme("http", PlainSocketFactory.getSocketFactory(), -1); + new Scheme("http", -1, PlainSocketFactory.getSocketFactory()); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { // expected } try { - new Scheme("http", PlainSocketFactory.getSocketFactory(), 70000); + new Scheme("http", 70000, PlainSocketFactory.getSocketFactory()); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { // expected @@ -112,13 +105,9 @@ public class TestScheme extends TestCase { public void testRegisterUnregister() { SchemeRegistry schmreg = new SchemeRegistry(); - Scheme http = new Scheme - ("http", PlainSocketFactory.getSocketFactory(), 80); - Scheme https = new Scheme - ("https", SecureSocketFactoryMockup.INSTANCE, 443); - // ("https", SSLSocketFactory.getSocketFactory(), 443); - Scheme myhttp = new Scheme - ("http", PlainSocketFactory.getSocketFactory(), 80); + Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory()); + Scheme https = new Scheme("https", 443, SecureSocketFactoryMockup.INSTANCE); + Scheme myhttp = new Scheme("http", 80, PlainSocketFactory.getSocketFactory()); HttpHost host = new HttpHost("www.test.invalid", -1, "http"); HttpHost hosts = new HttpHost("www.test.invalid", -1, "https"); @@ -151,11 +140,8 @@ public class TestScheme extends TestCase { assertNotNull(names); assertTrue(names.isEmpty()); - Scheme http = new Scheme - ("http", PlainSocketFactory.getSocketFactory(), 80); - Scheme https = new Scheme - ("https", SecureSocketFactoryMockup.INSTANCE, 443); - // ("https", SSLSocketFactory.getSocketFactory(), 443); + Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory()); + Scheme https = new Scheme("https", 443, SecureSocketFactoryMockup.INSTANCE); schmreg.register(http); schmreg.register(https); @@ -227,34 +213,25 @@ public class TestScheme extends TestCase { } public void testResolvePort() { - Scheme http = new Scheme - ("http", PlainSocketFactory.getSocketFactory(), 80); + Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory()); assertEquals(8080, http.resolvePort(8080)); assertEquals(80, http.resolvePort(-1)); } public void testHashCode() { - Scheme http = new Scheme - ("http", PlainSocketFactory.getSocketFactory(), 80); - Scheme myhttp = new Scheme - ("http", PlainSocketFactory.getSocketFactory(), 80); - Scheme https = new Scheme - ("https", SecureSocketFactoryMockup.INSTANCE, 443); - // ("https", SSLSocketFactory.getSocketFactory(), 443); + Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory()); + Scheme myhttp = new Scheme("http", 80, PlainSocketFactory.getSocketFactory()); + Scheme https = new Scheme("https", 443, SecureSocketFactoryMockup.INSTANCE); assertTrue(http.hashCode() != https.hashCode()); // not guaranteed assertTrue(http.hashCode() == myhttp.hashCode()); } public void testEquals() { - Scheme http = new Scheme - ("http", PlainSocketFactory.getSocketFactory(), 80); - Scheme myhttp = new Scheme - ("http", PlainSocketFactory.getSocketFactory(), 80); - Scheme https = new Scheme - ("https", SecureSocketFactoryMockup.INSTANCE, 443); - // ("https", SSLSocketFactory.getSocketFactory(), 443); + Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory()); + Scheme myhttp = new Scheme("http", 80, PlainSocketFactory.getSocketFactory()); + Scheme https = new Scheme("https", 443, SecureSocketFactoryMockup.INSTANCE); assertFalse(http.equals(https)); assertFalse(http.equals(null)); @@ -265,8 +242,7 @@ public class TestScheme extends TestCase { } public void testToString() { - Scheme http = new Scheme - ("http", PlainSocketFactory.getSocketFactory(), 80); + Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory()); // test it twice, the result is cached assertEquals("http:80", http.toString()); assertEquals("http:80", http.toString()); diff --git a/httpclient/src/test/java/org/apache/http/conn/scheme/TestScheme.java b/httpclient/src/test/java/org/apache/http/conn/scheme/TestScheme.java index 8ec8200ab..b8759bdf1 100644 --- a/httpclient/src/test/java/org/apache/http/conn/scheme/TestScheme.java +++ b/httpclient/src/test/java/org/apache/http/conn/scheme/TestScheme.java @@ -50,7 +50,7 @@ public class TestScheme extends TestCase { } public void testPortResolution() { - Scheme http = new Scheme("http", PlainSocketFactory.getSocketFactory(), 80); + Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory()); assertEquals(80, http.resolvePort(0)); assertEquals(80, http.resolvePort(-1)); assertEquals(8080, http.resolvePort(8080)); diff --git a/httpclient/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.java b/httpclient/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.java index 929e533b9..8c08c7d50 100644 --- a/httpclient/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.java +++ b/httpclient/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.java @@ -168,10 +168,9 @@ public class TestSSLSocketFactory extends TestCase { TestX509HostnameVerifier hostnameVerifier = new TestX509HostnameVerifier(); - SSLSocketFactory socketFactory = new SSLSocketFactory(sslcontext); - socketFactory.setHostnameVerifier(hostnameVerifier); + SSLSocketFactory socketFactory = new SSLSocketFactory(sslcontext, hostnameVerifier); - Scheme https = new Scheme("https", socketFactory, 443); + Scheme https = new Scheme("https", 443, socketFactory); DefaultHttpClient httpclient = new DefaultHttpClient(); httpclient.getConnectionManager().getSchemeRegistry().register(https); diff --git a/httpclient/src/test/java/org/apache/http/impl/client/TestContentCodings.java b/httpclient/src/test/java/org/apache/http/impl/client/TestContentCodings.java index 9ca1b0279..34c38edeb 100644 --- a/httpclient/src/test/java/org/apache/http/impl/client/TestContentCodings.java +++ b/httpclient/src/test/java/org/apache/http/impl/client/TestContentCodings.java @@ -185,7 +185,7 @@ public class TestContentCodings extends ServerTestBase { int clients = 100; SchemeRegistry schemeRegistry = new SchemeRegistry(); - schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(schemeRegistry); cm.setMaxTotalConnections(clients); diff --git a/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultClientRequestDirector.java b/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultClientRequestDirector.java index b879eaee8..5a28c5699 100644 --- a/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultClientRequestDirector.java +++ b/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultClientRequestDirector.java @@ -150,7 +150,7 @@ public class TestDefaultClientRequestDirector extends BasicServerTestBase { CountDownLatch releaseLatch = new CountDownLatch(1); SchemeRegistry registry = new SchemeRegistry(); - registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + registry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); SingleClientConnManager conMan = new SingleClientConnManager(registry); final AtomicReference throwableRef = new AtomicReference(); @@ -190,7 +190,7 @@ public class TestDefaultClientRequestDirector extends BasicServerTestBase { this.localServer.register("*", new BasicService()); SchemeRegistry registry = new SchemeRegistry(); - registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + registry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); SingleClientConnManager conMan = new SingleClientConnManager(registry); final AtomicReference throwableRef = new AtomicReference(); @@ -236,7 +236,7 @@ public class TestDefaultClientRequestDirector extends BasicServerTestBase { this.localServer.register("*", new BasicRedirectService(port)); SchemeRegistry registry = new SchemeRegistry(); - registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + registry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); CountDownLatch connLatch = new CountDownLatch(1); CountDownLatch awaitLatch = new CountDownLatch(1); @@ -295,7 +295,7 @@ public class TestDefaultClientRequestDirector extends BasicServerTestBase { this.localServer.register("*", new ThrowingService()); SchemeRegistry registry = new SchemeRegistry(); - registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + registry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); ConnMan3 conMan = new ConnMan3(registry); DefaultHttpClient client = new DefaultHttpClient(conMan, new BasicHttpParams()); @@ -474,7 +474,7 @@ public class TestDefaultClientRequestDirector extends BasicServerTestBase { public SchemeRegistry getSchemeRegistry() { SchemeRegistry registry = new SchemeRegistry(); - registry.register(new Scheme("http", new SocketFactoryMockup(null), 80)); + registry.register(new Scheme("http", 80, new SocketFactoryMockup(null))); return registry; } @@ -549,7 +549,7 @@ public class TestDefaultClientRequestDirector extends BasicServerTestBase { public SchemeRegistry getSchemeRegistry() { SchemeRegistry registry = new SchemeRegistry(); - registry.register(new Scheme("http", new SocketFactoryMockup(null), 80)); + registry.register(new Scheme("http", 80, new SocketFactoryMockup(null))); return registry; } diff --git a/httpclient/src/test/java/org/apache/http/impl/client/TestRequestRetryHandler.java b/httpclient/src/test/java/org/apache/http/impl/client/TestRequestRetryHandler.java index fff1df80f..5e59934e7 100644 --- a/httpclient/src/test/java/org/apache/http/impl/client/TestRequestRetryHandler.java +++ b/httpclient/src/test/java/org/apache/http/impl/client/TestRequestRetryHandler.java @@ -48,7 +48,7 @@ public class TestRequestRetryHandler extends TestCase { throws Exception { SchemeRegistry schemeRegistry = new SchemeRegistry(); - schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); ClientConnectionManager connManager = new ThreadSafeClientConnManager(schemeRegistry); assertOnRetry(connManager); @@ -58,14 +58,14 @@ public class TestRequestRetryHandler extends TestCase { throws Exception { SchemeRegistry schemeRegistry = new SchemeRegistry(); - schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); ClientConnectionManager connManager = new SingleClientConnManager(schemeRegistry); assertOnRetry(connManager); } protected void assertOnRetry(ClientConnectionManager connManager) throws Exception { SchemeRegistry schemeRegistry = new SchemeRegistry(); - schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); DefaultHttpClient client = new DefaultHttpClient(connManager); TestHttpRequestRetryHandler testRetryHandler = new TestHttpRequestRetryHandler(); diff --git a/httpclient/src/test/java/org/apache/http/impl/conn/TestProxySelRoutePlanner.java b/httpclient/src/test/java/org/apache/http/impl/conn/TestProxySelRoutePlanner.java index 4d7f463ac..060a0c583 100644 --- a/httpclient/src/test/java/org/apache/http/impl/conn/TestProxySelRoutePlanner.java +++ b/httpclient/src/test/java/org/apache/http/impl/conn/TestProxySelRoutePlanner.java @@ -27,7 +27,6 @@ package org.apache.http.impl.conn; - import java.net.Proxy; import java.net.InetAddress; import java.net.InetSocketAddress; @@ -48,12 +47,9 @@ import org.apache.http.conn.routing.HttpRoutePlanner; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.conn.scheme.SocketFactory; import org.apache.http.mockup.ProxySelectorMockup; - - /** * Tests for ProxySelectorRoutePlanner. */ @@ -81,8 +77,7 @@ public class TestProxySelRoutePlanner extends TestCase { public SchemeRegistry createSchemeRegistry() { SchemeRegistry schreg = new SchemeRegistry(); - SocketFactory sf = PlainSocketFactory.getSocketFactory(); - schreg.register(new Scheme("http", sf, 80)); + schreg.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); return schreg; } diff --git a/httpclient/src/test/java/org/apache/http/impl/conn/TestTSCCMNoServer.java b/httpclient/src/test/java/org/apache/http/impl/conn/TestTSCCMNoServer.java index dcb4d3add..528cdee2e 100644 --- a/httpclient/src/test/java/org/apache/http/impl/conn/TestTSCCMNoServer.java +++ b/httpclient/src/test/java/org/apache/http/impl/conn/TestTSCCMNoServer.java @@ -43,7 +43,6 @@ import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.conn.scheme.SocketFactory; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpParams; @@ -122,8 +121,7 @@ public class TestTSCCMNoServer extends TestCase { public SchemeRegistry createSchemeRegistry() { SchemeRegistry schreg = new SchemeRegistry(); - SocketFactory sf = PlainSocketFactory.getSocketFactory(); - schreg.register(new Scheme("http", sf, 80)); + schreg.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); return schreg; } diff --git a/httpclient/src/test/java/org/apache/http/impl/conn/TestTSCCMWithServer.java b/httpclient/src/test/java/org/apache/http/impl/conn/TestTSCCMWithServer.java index f6e66a970..2c1396ae6 100644 --- a/httpclient/src/test/java/org/apache/http/impl/conn/TestTSCCMWithServer.java +++ b/httpclient/src/test/java/org/apache/http/impl/conn/TestTSCCMWithServer.java @@ -30,6 +30,7 @@ package org.apache.http.impl.conn; import java.io.IOException; import java.lang.ref.WeakReference; import java.net.InetAddress; +import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketException; import java.net.UnknownHostException; @@ -56,7 +57,7 @@ import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.conn.scheme.SocketFactory; +import org.apache.http.conn.scheme.SchemeSocketFactory; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.localserver.ServerTestBase; import org.apache.http.message.BasicHttpRequest; @@ -505,8 +506,9 @@ public class TestTSCCMWithServer extends ServerTestBase { public void testAbortDuringConnecting() throws Exception { final CountDownLatch connectLatch = new CountDownLatch(1); - final StallingSocketFactory stallingSocketFactory = new StallingSocketFactory(connectLatch, WaitPolicy.BEFORE_CONNECT, PlainSocketFactory.getSocketFactory()); - Scheme scheme = new Scheme("http", stallingSocketFactory, 80); + final StallingSocketFactory stallingSocketFactory = new StallingSocketFactory( + connectLatch, WaitPolicy.BEFORE_CONNECT, PlainSocketFactory.getSocketFactory()); + Scheme scheme = new Scheme("http", 80, stallingSocketFactory); SchemeRegistry registry = new SchemeRegistry(); registry.register(scheme); @@ -555,8 +557,9 @@ public class TestTSCCMWithServer extends ServerTestBase { public void testAbortBeforeSocketCreate() throws Exception { final CountDownLatch connectLatch = new CountDownLatch(1); - final StallingSocketFactory stallingSocketFactory = new StallingSocketFactory(connectLatch, WaitPolicy.BEFORE_CREATE, PlainSocketFactory.getSocketFactory()); - Scheme scheme = new Scheme("http", stallingSocketFactory, 80); + final StallingSocketFactory stallingSocketFactory = new StallingSocketFactory( + connectLatch, WaitPolicy.BEFORE_CREATE, PlainSocketFactory.getSocketFactory()); + Scheme scheme = new Scheme("http", 80, stallingSocketFactory); SchemeRegistry registry = new SchemeRegistry(); registry.register(scheme); @@ -607,8 +610,9 @@ public class TestTSCCMWithServer extends ServerTestBase { public void testAbortAfterSocketConnect() throws Exception { final CountDownLatch connectLatch = new CountDownLatch(1); - final StallingSocketFactory stallingSocketFactory = new StallingSocketFactory(connectLatch, WaitPolicy.AFTER_CONNECT, PlainSocketFactory.getSocketFactory()); - Scheme scheme = new Scheme("http", stallingSocketFactory, 80); + final StallingSocketFactory stallingSocketFactory = new StallingSocketFactory( + connectLatch, WaitPolicy.AFTER_CONNECT, PlainSocketFactory.getSocketFactory()); + Scheme scheme = new Scheme("http", 80, stallingSocketFactory); SchemeRegistry registry = new SchemeRegistry(); registry.register(scheme); @@ -780,24 +784,27 @@ public class TestTSCCMWithServer extends ServerTestBase { } } - private static class StallingSocketFactory extends LatchSupport implements SocketFactory { - private final SocketFactory delegate; + private static class StallingSocketFactory extends LatchSupport implements SchemeSocketFactory { + + private final SchemeSocketFactory delegate; - public StallingSocketFactory(CountDownLatch continueLatch, - WaitPolicy waitPolicy, SocketFactory delegate) { + public StallingSocketFactory( + final CountDownLatch continueLatch, + final WaitPolicy waitPolicy, + final SchemeSocketFactory delegate) { super(continueLatch, waitPolicy); this.delegate = delegate; } - public Socket connectSocket(Socket sock, String host, int port, - InetAddress localAddress, int localPort, HttpParams params) - throws IOException, UnknownHostException, - ConnectTimeoutException { + public Socket connectSocket( + final Socket sock, + final InetSocketAddress remoteAddress, + final InetSocketAddress localAddress, + final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { if(waitPolicy == WaitPolicy.BEFORE_CONNECT) latch(); - Socket socket = delegate.connectSocket(sock, host, port, localAddress, - localPort, params); + Socket socket = delegate.connectSocket(sock, remoteAddress, localAddress, params); if(waitPolicy == WaitPolicy.AFTER_CONNECT) latch(); diff --git a/httpclient/src/test/java/org/apache/http/impl/conn/tsccm/TestSpuriousWakeup.java b/httpclient/src/test/java/org/apache/http/impl/conn/tsccm/TestSpuriousWakeup.java index 2c8fd07c5..eef46df67 100644 --- a/httpclient/src/test/java/org/apache/http/impl/conn/tsccm/TestSpuriousWakeup.java +++ b/httpclient/src/test/java/org/apache/http/impl/conn/tsccm/TestSpuriousWakeup.java @@ -42,7 +42,7 @@ import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.conn.scheme.SocketFactory; +import org.apache.http.conn.scheme.SchemeSocketFactory; import org.apache.http.conn.params.ConnPerRoute; import org.apache.http.impl.conn.GetConnThread; @@ -130,8 +130,8 @@ public class TestSpuriousWakeup extends TestCase { public void testSpuriousWakeup() throws Exception { SchemeRegistry schreg = new SchemeRegistry(); - SocketFactory sf = PlainSocketFactory.getSocketFactory(); - schreg.register(new Scheme("http", sf, 80)); + SchemeSocketFactory sf = PlainSocketFactory.getSocketFactory(); + schreg.register(new Scheme("http", 80, sf)); XTSCCM mgr = new XTSCCM(schreg); try { diff --git a/httpclient/src/test/java/org/apache/http/localserver/ServerTestBase.java b/httpclient/src/test/java/org/apache/http/localserver/ServerTestBase.java index 1bdd497ac..0f89b9fb9 100644 --- a/httpclient/src/test/java/org/apache/http/localserver/ServerTestBase.java +++ b/httpclient/src/test/java/org/apache/http/localserver/ServerTestBase.java @@ -27,6 +27,8 @@ package org.apache.http.localserver; +import java.net.InetAddress; +import java.net.InetSocketAddress; import java.net.Socket; import org.apache.http.HttpHost; @@ -34,7 +36,7 @@ import org.apache.http.HttpVersion; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.conn.scheme.SocketFactory; +import org.apache.http.conn.scheme.SchemeSocketFactory; import org.apache.http.impl.DefaultHttpClientConnection; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; @@ -116,8 +118,8 @@ public abstract class ServerTestBase extends BasicServerTestBase { if (supportedSchemes == null) { supportedSchemes = new SchemeRegistry(); - SocketFactory sf = PlainSocketFactory.getSocketFactory(); - supportedSchemes.register(new Scheme("http", sf, 80)); + SchemeSocketFactory sf = PlainSocketFactory.getSocketFactory(); + supportedSchemes.register(new Scheme("http", 80, sf)); } if (httpProcessor == null) { @@ -179,8 +181,9 @@ public abstract class ServerTestBase extends BasicServerTestBase { int port = schm.resolvePort(target.getPort()); DefaultHttpClientConnection conn = new DefaultHttpClientConnection(); - Socket sock = schm.getSocketFactory().connectSocket - (null, target.getHostName(), port, null, 0, params); + InetSocketAddress address = new InetSocketAddress( + InetAddress.getByName(target.getHostName()), port); + Socket sock = schm.getSchemeSocketFactory().connectSocket(null, address, null, params); conn.bind(sock, params); return conn; diff --git a/httpclient/src/test/java/org/apache/http/mockup/SecureSocketFactoryMockup.java b/httpclient/src/test/java/org/apache/http/mockup/SecureSocketFactoryMockup.java index f54ee7ea1..55dcc5dc3 100644 --- a/httpclient/src/test/java/org/apache/http/mockup/SecureSocketFactoryMockup.java +++ b/httpclient/src/test/java/org/apache/http/mockup/SecureSocketFactoryMockup.java @@ -29,18 +29,16 @@ package org.apache.http.mockup; import java.net.Socket; -import org.apache.http.conn.scheme.LayeredSocketFactory; +import org.apache.http.conn.scheme.LayeredSchemeSocketFactory; /** * {@link LayeredSocketFactory} mockup implementation. */ -public class SecureSocketFactoryMockup extends SocketFactoryMockup - implements LayeredSocketFactory { +public class SecureSocketFactoryMockup extends SocketFactoryMockup + implements LayeredSchemeSocketFactory { /* A default instance of this mockup. */ - public final static LayeredSocketFactory INSTANCE = - new SecureSocketFactoryMockup("INSTANCE"); - + public final static LayeredSchemeSocketFactory INSTANCE = new SecureSocketFactoryMockup("INSTANCE"); public SecureSocketFactoryMockup(String name) { super(name); @@ -54,8 +52,9 @@ public class SecureSocketFactoryMockup extends SocketFactoryMockup } - public Socket createSocket(Socket socket, String host, int port, + public Socket createLayeredSocket(Socket socket, String host, int port, boolean autoClose) { throw new UnsupportedOperationException("I'm a mockup!"); } + } diff --git a/httpclient/src/test/java/org/apache/http/mockup/SocketFactoryMockup.java b/httpclient/src/test/java/org/apache/http/mockup/SocketFactoryMockup.java index a72803f9d..f0238b1cb 100644 --- a/httpclient/src/test/java/org/apache/http/mockup/SocketFactoryMockup.java +++ b/httpclient/src/test/java/org/apache/http/mockup/SocketFactoryMockup.java @@ -27,27 +27,26 @@ package org.apache.http.mockup; +import java.io.IOException; +import java.net.InetSocketAddress; import java.net.Socket; -import java.net.InetAddress; +import java.net.UnknownHostException; -import org.apache.http.conn.scheme.SocketFactory; +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.conn.scheme.SchemeSocketFactory; import org.apache.http.params.HttpParams; - - /** * {@link SocketFactory} mockup implementation. */ -public class SocketFactoryMockup implements SocketFactory { +public class SocketFactoryMockup implements SchemeSocketFactory { /* A default instance of this mockup. */ - public final static SocketFactory INSTANCE = - new SocketFactoryMockup("INSTANCE"); + public final static SchemeSocketFactory INSTANCE = new SocketFactoryMockup("INSTANCE"); /** The name of this mockup socket factory. */ protected final String mockup_name; - public SocketFactoryMockup(String name) { mockup_name = (name != null) ? name : String.valueOf(hashCode()); } @@ -59,14 +58,15 @@ public class SocketFactoryMockup implements SocketFactory { return "SocketFactoryMockup." + mockup_name; } - public Socket createSocket() { throw new UnsupportedOperationException("I'm a mockup!"); } - public Socket connectSocket(Socket sock, String host, int port, - InetAddress localAddress, int localPort, - HttpParams params) { + public Socket connectSocket( + Socket sock, + InetSocketAddress remoteAddress, + InetSocketAddress localAddress, + HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { throw new UnsupportedOperationException("I'm a mockup!"); } @@ -74,4 +74,5 @@ public class SocketFactoryMockup implements SocketFactory { // no way that the argument is from *this* factory... throw new IllegalArgumentException("I'm a mockup!"); } + } diff --git a/src/docbkx/connmgmt.xml b/src/docbkx/connmgmt.xml index c8e85b5b9..34262a049 100644 --- a/src/docbkx/connmgmt.xml +++ b/src/docbkx/connmgmt.xml @@ -236,7 +236,7 @@ Socket factories HTTP connections make use of a java.net.Socket object internally to handle transmission of data across the wire. They, however, rely on - SocketFactory interface to create, initialize and + SchemeSocketFactory interface to create, initialize and connect sockets. This enables the users of HttpClient to provide application specific socket initialization code at runtime. PlainSocketFactory is the default factory for creating and initializing plain (unencrypted) sockets. @@ -248,17 +248,19 @@ Socket socket = sf.createSocket(); HttpParams params = new BasicHttpParams(); params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 1000L); -sf.connectSocket(socket, "locahost", 8080, null, -1, params); +InetSocketAddress address = new InetSocketAddress("locahost", 8080); +sf.connectSocket(socket, address, null, params); ]]>

Secure socket layering - LayeredSocketFactory is an extension of - SocketFactory interface. Layered socket factories - are capable of creating sockets that are layered over an existing plain socket. + LayeredSchemeSocketFactory is an extension of + SchemeSocketFactory interface. Layered socket + factories are capable of creating sockets layered over an existing plain socket. Socket layering is used primarily for creating secure sockets through proxies. - HttpClient ships with SSLSocketFactory that implements SSL/TLS layering. Please note - HttpClient does not use any custom encryption functionality. It is fully reliant on - standard Java Cryptography (JCE) and Secure Sockets (JSEE) extensions. + HttpClient ships with SSLSocketFactory that implements + SSL/TLS layering. Please note HttpClient does not use any custom encryption + functionality. It is fully reliant on standard Java Cryptography (JCE) and Secure + Sockets (JSEE) extensions.
SSL/TLS customization @@ -300,7 +302,8 @@ socket.setEnabledCipherSuites(new String[] { "SSL_RSA_WITH_RC4_128_MD5" }); HttpParams params = new BasicHttpParams(); params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 1000L); -sf.connectSocket(socket, "locahost", 443, null, -1, params); +InetSocketAddress address = new InetSocketAddress("locahost", 443); +sf.connectSocket(socket, address, null, params); ]]> Customization of SSLSocketFactory implies a certain degree of familiarity with the concepts of the SSL/TLS protocol, a detailed explanation of which is out of scope @@ -357,8 +360,9 @@ sf.connectSocket(socket, "locahost", 443, null, -1, params); implementation. One can specify a different hostname verifier implementation if desired
@@ -371,11 +375,12 @@ sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER); a set of Schemes HttpClient can choose from when trying to establish a connection by a request URI: ClientConnectionOperator interface represents a strategy for creating OperatedClientConnection instances and updating the underlying socket of those objects. Implementations will - most likely make use SocketFactorys to create + most likely make use SchemeSocketFactorys to create java.net.Socket instances. The ClientConnectionOperator interface enables the users of HttpClient to provide a custom strategy for connection operators as well as @@ -475,7 +480,7 @@ httpclient.setRoutePlanner(new HttpRoutePlanner() { unintentionally. This is an example of acquiring a connection from a connection manager: