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
This commit is contained in:
Oleg Kalnichevski 2010-04-07 17:28:15 +00:00
parent 9b7b9c9ce1
commit 8de26bac03
33 changed files with 907 additions and 317 deletions

View File

@ -32,7 +32,7 @@ import java.net.InetAddress;
import java.net.Socket; import java.net.Socket;
import org.apache.http.HttpHost; 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.params.HttpParams;
import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpContext;
@ -40,7 +40,7 @@ import org.apache.http.protocol.HttpContext;
* ClientConnectionOperator represents a strategy for creating * ClientConnectionOperator represents a strategy for creating
* {@link OperatedClientConnection} instances and updating the underlying * {@link OperatedClientConnection} instances and updating the underlying
* {@link Socket} of those objects. Implementations will most likely make use * {@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.
* <p> * <p>
* The methods in this interface allow the creation of plain and layered * The methods in this interface allow the creation of plain and layered
* sockets. Creating a tunnelled connection through a proxy, however, * sockets. Creating a tunnelled connection through a proxy, however,

View File

@ -39,6 +39,7 @@ import java.util.Arrays;
import org.apache.http.annotation.Immutable; import org.apache.http.annotation.Immutable;
import org.apache.http.conn.scheme.SchemeSocketFactory;
import org.apache.http.conn.scheme.SocketFactory; import org.apache.http.conn.scheme.SocketFactory;
import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams; import org.apache.http.params.HttpParams;
@ -51,7 +52,11 @@ import org.apache.http.params.HttpParams;
* {@link #createSocket()} method. * {@link #createSocket()} method.
* *
* @since 4.0 * @since 4.0
*
* @deprecated Do not use. For multihome support socket factories must implement
* {@link SchemeSocketFactory} interface.
*/ */
@Deprecated
@Immutable @Immutable
public final class MultihomePlainSocketFactory implements SocketFactory { public final class MultihomePlainSocketFactory implements SocketFactory {

View File

@ -34,7 +34,10 @@ import java.net.InetAddress;
* Hostname to IP address resolver. * Hostname to IP address resolver.
* *
* @since 4.0 * @since 4.0
*
* @deprecated Do not use
*/ */
@Deprecated
public interface HostNameResolver { public interface HostNameResolver {
/** /**

View File

@ -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
* <http://www.apache.org/>.
*
*/
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;
}

View File

@ -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
* <http://www.apache.org/>.
*
*/
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);
}
}

View File

@ -36,7 +36,10 @@ import java.net.UnknownHostException;
* See there for things to consider when implementing a socket factory. * See there for things to consider when implementing a socket factory.
* *
* @since 4.0 * @since 4.0
*
* @deprecated use {@link SchemeSocketFactory}
*/ */
@Deprecated
public interface LayeredSocketFactory extends SocketFactory { public interface LayeredSocketFactory extends SocketFactory {
/** /**

View File

@ -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
* <http://www.apache.org/>.
*
*/
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);
}
}

View File

@ -32,6 +32,7 @@ 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.SocketTimeoutException;
import java.net.UnknownHostException;
import org.apache.http.annotation.Immutable; import org.apache.http.annotation.Immutable;
@ -50,14 +51,14 @@ import org.apache.http.params.HttpParams;
* *
* @since 4.0 * @since 4.0
*/ */
@SuppressWarnings("deprecation")
@Immutable @Immutable
public final class PlainSocketFactory implements SocketFactory { public final class PlainSocketFactory implements SocketFactory, SchemeSocketFactory {
/** /**
* The default factory. * The default factory.
*/ */
private static final private static final PlainSocketFactory DEFAULT_FACTORY = new PlainSocketFactory();
PlainSocketFactory DEFAULT_FACTORY = new PlainSocketFactory();
private final HostNameResolver nameResolver; private final HostNameResolver nameResolver;
@ -71,58 +72,48 @@ public final class PlainSocketFactory implements SocketFactory {
return DEFAULT_FACTORY; return DEFAULT_FACTORY;
} }
@Deprecated
public PlainSocketFactory(final HostNameResolver nameResolver) { public PlainSocketFactory(final HostNameResolver nameResolver) {
super(); super();
this.nameResolver = nameResolver; this.nameResolver = nameResolver;
} }
public PlainSocketFactory() { public PlainSocketFactory() {
this(null); super();
this.nameResolver = null;
} }
public Socket createSocket() { public Socket createSocket() {
return new Socket(); return new Socket();
} }
public Socket connectSocket(Socket sock, String host, int port, /**
InetAddress localAddress, int localPort, * @since 4.1
HttpParams params) */
throws IOException { public Socket connectSocket(
final Socket socket,
if (host == null) { final InetSocketAddress remoteAddress,
throw new IllegalArgumentException("Target host may not be null."); final InetSocketAddress localAddress,
final HttpParams params) throws IOException, ConnectTimeoutException {
if (remoteAddress == null) {
throw new IllegalArgumentException("Remote address may not be null");
} }
if (params == null) { if (params == null) {
throw new IllegalArgumentException("Parameters may not be null."); throw new IllegalArgumentException("HTTP parameters may not be null");
} }
Socket sock = socket;
if (sock == null) if (sock == null) {
sock = createSocket(); 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); 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 { try {
sock.connect(remoteAddress, timeout); sock.connect(remoteAddress, timeout);
} catch (SocketTimeoutException ex) { } catch (SocketTimeoutException ex) {
throw new ConnectTimeoutException("Connect to " + remoteAddress + " timed out"); throw new ConnectTimeoutException("Connect to " + remoteAddress.getHostName() + "/"
+ remoteAddress.getAddress() + " timed out");
} }
return sock; return sock;
} }
@ -152,4 +143,31 @@ public final class PlainSocketFactory implements SocketFactory {
return false; 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);
}
} }

View File

@ -33,21 +33,16 @@ import org.apache.http.annotation.Immutable;
import org.apache.http.util.LangUtils; import org.apache.http.util.LangUtils;
/** /**
* Encapsulates specifics of a protocol scheme such as "http" or "https". * Encapsulates specifics of a protocol scheme such as "http" or "https". Schemes are identified
* Schemes are identified by lowercase names. * by lowercase names. Supported schemes are typically collected in a {@link SchemeRegistry
* Supported schemes are typically collected in a * SchemeRegistry}.
* {@link SchemeRegistry SchemeRegistry}.
*
* <p> * <p>
* For example, to configure support for "https://" URLs, * For example, to configure support for "https://" URLs, you could write code like the following:
* you could write code like the following:
* </p>
* <pre> * <pre>
* Scheme https = new Scheme("https", new MySecureSocketFactory(), 443); * Scheme https = new Scheme("https", 443, new MySecureSocketFactory());
* SchemeRegistry.DEFAULT.register(https); * SchemeRegistry.DEFAULT.register(https);
* </pre> * </pre>
* *
*
* @since 4.0 * @since 4.0
*/ */
@Immutable @Immutable
@ -57,7 +52,7 @@ public final class Scheme {
private final String name; private final String name;
/** The socket factory for this scheme */ /** The socket factory for this scheme */
private final SocketFactory socketFactory; private final SchemeSocketFactory socketFactory;
/** The default port for this scheme */ /** The default port for this scheme */
private final int defaultPort; private final int defaultPort;
@ -65,7 +60,6 @@ public final class Scheme {
/** Indicates whether this scheme allows for layered connections */ /** Indicates whether this scheme allows for layered connections */
private final boolean layered; private final boolean layered;
/** A string representation, for {@link #toString toString}. */ /** A string representation, for {@link #toString toString}. */
private String stringRep; private String stringRep;
/* /*
@ -74,6 +68,34 @@ public final class Scheme {
* need to synchronize, and it does not affect immutability. * 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 <code>factory</code>.
*
* @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. * Creates a new scheme.
@ -85,7 +107,10 @@ public final class Scheme {
* @param factory the factory for creating sockets for communication * @param factory the factory for creating sockets for communication
* with this scheme * with this scheme
* @param port the default port for this scheme * @param port the default port for this scheme
*
* @deprecated Use {@link #Scheme(String, int, SchemeSocketFactory)}
*/ */
@Deprecated
public Scheme(final String name, public Scheme(final String name,
final SocketFactory factory, final SocketFactory factory,
final int port) { final int port) {
@ -104,12 +129,17 @@ public final class Scheme {
} }
this.name = name.toLowerCase(Locale.ENGLISH); 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.defaultPort = port;
this.layered = (factory instanceof LayeredSocketFactory);
} }
/** /**
* Obtains the default port. * Obtains the default port.
* *
@ -126,11 +156,35 @@ public final class Scheme {
* {@link LayeredSocketFactory LayeredSocketFactory}. * {@link LayeredSocketFactory LayeredSocketFactory}.
* *
* @return the socket factory for this scheme * @return the socket factory for this scheme
*
* @deprecated Use {@link #getSchemeSocketFactory()}
*/ */
@Deprecated
public final SocketFactory getSocketFactory() { 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. * Obtains the scheme name.
@ -141,7 +195,6 @@ public final class Scheme {
return name; return name;
} }
/** /**
* Indicates whether this scheme allows for layered connections. * Indicates whether this scheme allows for layered connections.
* *
@ -152,7 +205,6 @@ public final class Scheme {
return layered; return layered;
} }
/** /**
* Resolves the correct port for this scheme. * Resolves the correct port for this scheme.
* Returns the given port if it is valid, the default port otherwise. * 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 port <= 0 ? defaultPort : port;
} }
/** /**
* Return a string representation of this object. * Return a string representation of this object.
* *
@ -184,34 +235,21 @@ public final class Scheme {
return stringRep; return stringRep;
} }
/**
* Compares this scheme to an object.
*
* @param obj the object to compare with
*
* @return <code>true</code> iff the argument is equal to this scheme
*/
@Override @Override
public final boolean equals(Object obj) { public final boolean equals(Object obj) {
if (obj == null) return false; if (obj == null) return false;
if (this == obj) return true; 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 @Override
public int hashCode() { public int hashCode() {
int hash = LangUtils.HASH_SEED; int hash = LangUtils.HASH_SEED;
@ -222,4 +260,4 @@ public final class Scheme {
return hash; return hash;
} }
} // class Scheme }

View File

@ -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
* <http://www.apache.org/>.
*
*/
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}.
* <code>null</code> 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
* <code>null</code> for any
* @param params additional {@link HttpParams parameters} for connecting
*
* @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 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 <code>params</code>
*/
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 <i>not</i> perform I/O operations in this method.
* <p>
* 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 <code>true</code> if the connection of the socket
* should be considered secure, or
* <code>false</code> 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 <i>not</i> 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;
}

View File

@ -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
* <http://www.apache.org/>.
*
*/
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();
}
}

View File

@ -40,7 +40,10 @@ import org.apache.http.params.HttpParams;
* The factory encapsulates the logic for establishing a socket connection. * The factory encapsulates the logic for establishing a socket connection.
* *
* @since 4.0 * @since 4.0
*
* @deprecated use {@link SchemeSocketFactory}
*/ */
@Deprecated
public interface SocketFactory { public interface SocketFactory {
/** /**

View File

@ -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
* <http://www.apache.org/>.
*
*/
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();
}
}

View File

@ -27,10 +27,11 @@
package org.apache.http.conn.ssl; 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.ConnectTimeoutException;
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.LayeredSocketFactory; import org.apache.http.conn.scheme.LayeredSocketFactory;
import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams; import org.apache.http.params.HttpParams;
@ -144,8 +145,9 @@ import java.security.UnrecoverableKeyException;
* *
* @since 4.0 * @since 4.0
*/ */
@NotThreadSafe // [gs]etHostNameVerifier @SuppressWarnings("deprecation")
public class SSLSocketFactory implements LayeredSocketFactory { @ThreadSafe
public class SSLSocketFactory implements LayeredSchemeSocketFactory, LayeredSocketFactory {
public static final String TLS = "TLS"; public static final String TLS = "TLS";
public static final String SSL = "SSL"; public static final String SSL = "SSL";
@ -178,10 +180,13 @@ public class SSLSocketFactory implements LayeredSocketFactory {
private final SSLContext sslcontext; private final SSLContext sslcontext;
private final javax.net.ssl.SSLSocketFactory socketfactory; private final javax.net.ssl.SSLSocketFactory socketfactory;
private final HostNameResolver nameResolver; private final HostNameResolver nameResolver;
// TODO: make final
// volatile is needed to guarantee thread-safety of the setter/getter methods under all usage scenarios private volatile X509HostnameVerifier hostnameVerifier;
private volatile X509HostnameVerifier hostnameVerifier = BROWSER_COMPATIBLE_HOSTNAME_VERIFIER;
/**
* @deprecated Use {@link #SSLSocketFactory(String, KeyStore, String, KeyStore, SecureRandom, X509HostnameVerifier)}
*/
@Deprecated
public SSLSocketFactory( public SSLSocketFactory(
String algorithm, String algorithm,
final KeyStore keystore, final KeyStore keystore,
@ -206,42 +211,87 @@ public class SSLSocketFactory implements LayeredSocketFactory {
this.sslcontext = SSLContext.getInstance(algorithm); this.sslcontext = SSLContext.getInstance(algorithm);
this.sslcontext.init(keymanagers, trustmanagers, random); this.sslcontext.init(keymanagers, trustmanagers, random);
this.socketfactory = this.sslcontext.getSocketFactory(); this.socketfactory = this.sslcontext.getSocketFactory();
this.hostnameVerifier = BROWSER_COMPATIBLE_HOSTNAME_VERIFIER;
this.nameResolver = nameResolver; 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( public SSLSocketFactory(
final KeyStore keystore, final KeyStore keystore,
final String keystorePassword, final String keystorePassword,
final KeyStore truststore) final KeyStore truststore)
throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException 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) public SSLSocketFactory(final KeyStore keystore, final String keystorePassword)
throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException 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) public SSLSocketFactory(final KeyStore truststore)
throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException 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, * @deprecated Use {@link #SSLSocketFactory(SSLContext)}
final HostNameResolver nameResolver) */
{ @Deprecated
public SSLSocketFactory(final SSLContext sslContext, final HostNameResolver nameResolver) {
super();
this.sslcontext = sslContext; this.sslcontext = sslContext;
this.socketfactory = this.sslcontext.getSocketFactory(); this.socketfactory = this.sslcontext.getSocketFactory();
this.hostnameVerifier = BROWSER_COMPATIBLE_HOSTNAME_VERIFIER;
this.nameResolver = nameResolver; this.nameResolver = nameResolver;
} }
public SSLSocketFactory(final SSLContext sslContext) /**
{ * @since 4.1
this(sslContext, null); */
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(); return tmfactory.getTrustManagers();
} }
// non-javadoc, see interface org.apache.http.conn.SocketFactory
@SuppressWarnings("cast") @SuppressWarnings("cast")
public Socket createSocket() public Socket createSocket() throws IOException {
throws IOException {
// the cast makes sure that the factory is working as expected // the cast makes sure that the factory is working as expected
return (SSLSocket) this.socketfactory.createSocket(); return (SSLSocket) this.socketfactory.createSocket();
} }
/**
// non-javadoc, see interface org.apache.http.conn.SocketFactory * @since 4.1
*/
public Socket connectSocket( public Socket connectSocket(
final Socket sock, final Socket sock,
final String host, final InetSocketAddress remoteAddress,
final int port, final InetSocketAddress localAddress,
final InetAddress localAddress, final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
int localPort, if (remoteAddress == null) {
final HttpParams params throw new IllegalArgumentException("Remote address may not be null");
) throws IOException {
if (host == null) {
throw new IllegalArgumentException("Target host may not be null.");
} }
if (params == 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());
SSLSocket sslsock = (SSLSocket) if (localAddress != null) {
((sock != null) ? sock : createSocket()); sslsock.bind(localAddress);
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);
} }
int connTimeout = HttpConnectionParams.getConnectionTimeout(params); int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
int soTimeout = HttpConnectionParams.getSoTimeout(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 { try {
sslsock.connect(remoteAddress, connTimeout); sslsock.connect(remoteAddress, connTimeout);
} catch (SocketTimeoutException ex) { } 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); sslsock.setSoTimeout(soTimeout);
try { if (this.hostnameVerifier != null) {
hostnameVerifier.verify(host, sslsock); try {
// verifyHostName() didn't blowup - good! this.hostnameVerifier.verify(remoteAddress.getHostName(), sslsock);
} catch (IOException iox) { // verifyHostName() didn't blowup - good!
// close the socket before re-throwing the exception } catch (IOException iox) {
try { sslsock.close(); } catch (Exception x) { /*ignore*/ } // close the socket before re-throwing the exception
throw iox; try { sslsock.close(); } catch (Exception x) { /*ignore*/ }
throw iox;
}
} }
return sslsock; return sslsock;
} }
@ -362,45 +391,43 @@ public class SSLSocketFactory implements LayeredSocketFactory {
* *
* @throws IllegalArgumentException if the argument is invalid * @throws IllegalArgumentException if the argument is invalid
*/ */
public boolean isSecure(Socket sock) public boolean isSecure(final Socket sock) throws IllegalArgumentException {
throws IllegalArgumentException {
if (sock == null) { 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. // This instanceof check is in line with createSocket() above.
if (!(sock instanceof SSLSocket)) { if (!(sock instanceof SSLSocket)) {
throw new IllegalArgumentException throw new IllegalArgumentException("Socket not created by this factory");
("Socket not created by this factory.");
} }
// This check is performed last since it calls the argument object. // This check is performed last since it calls the argument object.
if (sock.isClosed()) { if (sock.isClosed()) {
throw new IllegalArgumentException("Socket is closed."); throw new IllegalArgumentException("Socket is closed");
} }
return true; return true;
}
} // isSecure /**
* @since 4.1
*/
// non-javadoc, see interface LayeredSocketFactory public Socket createLayeredSocket(
public Socket createSocket(
final Socket socket, final Socket socket,
final String host, final String host,
final int port, final int port,
final boolean autoClose final boolean autoClose) throws IOException, UnknownHostException {
) throws IOException, UnknownHostException {
SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket( SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket(
socket, socket,
host, host,
port, port,
autoClose autoClose
); );
hostnameVerifier.verify(host, sslSocket); if (this.hostnameVerifier != null) {
this.hostnameVerifier.verify(host, sslSocket);
}
// verifyHostName() didn't blowup - good! // verifyHostName() didn't blowup - good!
return sslSocket; return sslSocket;
} }
@Deprecated
public void setHostnameVerifier(X509HostnameVerifier hostnameVerifier) { public void setHostnameVerifier(X509HostnameVerifier hostnameVerifier) {
if ( hostnameVerifier == null ) { if ( hostnameVerifier == null ) {
throw new IllegalArgumentException("Hostname verifier may not be null"); throw new IllegalArgumentException("Hostname verifier may not be null");
@ -409,7 +436,45 @@ public class SSLSocketFactory implements LayeredSocketFactory {
} }
public X509HostnameVerifier getHostnameVerifier() { 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);
} }
} }

View File

@ -221,9 +221,9 @@ public class DefaultHttpClient extends AbstractHttpClient {
protected ClientConnectionManager createClientConnectionManager() { protected ClientConnectionManager createClientConnectionManager() {
SchemeRegistry registry = new SchemeRegistry(); SchemeRegistry registry = new SchemeRegistry();
registry.register( registry.register(
new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
registry.register( registry.register(
new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); new Scheme("https", 443, SSLSocketFactory.getSocketFactory()));
ClientConnectionManager connManager = null; ClientConnectionManager connManager = null;
HttpParams params = getParams(); HttpParams params = getParams();

View File

@ -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 * @return list of all URIs
* *

View File

@ -29,6 +29,7 @@ package org.apache.http.impl.conn;
import java.io.IOException; import java.io.IOException;
import java.net.ConnectException; import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
import java.net.InetAddress; 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.HttpHostConnectException;
import org.apache.http.conn.OperatedClientConnection; import org.apache.http.conn.OperatedClientConnection;
import org.apache.http.conn.ClientConnectionOperator; 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.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry; 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 * 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.
* <p> * <p>
* The following parameters can be used to customize the behavior of this * The following parameters can be used to customize the behavior of this
* class: * class:
@ -113,16 +114,21 @@ public class DefaultClientConnectionOperator implements ClientConnectionOperator
("Connection must not be open."); ("Connection must not be open.");
} }
final Scheme schm = schemeRegistry.getScheme(target.getSchemeName()); Scheme schm = schemeRegistry.getScheme(target.getSchemeName());
final SocketFactory sf = schm.getSocketFactory(); SchemeSocketFactory sf = schm.getSchemeSocketFactory();
Socket sock = sf.createSocket(); Socket sock = sf.createSocket();
conn.opening(sock, target); 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 { try {
Socket connsock = sf.connectSocket(sock, target.getHostName(), Socket connsock = sf.connectSocket(sock, remoteAddress, localAddress, params);
schm.resolvePort(target.getPort()),
local, 0, params);
if (sock != connsock) { if (sock != connsock) {
sock = connsock; sock = connsock;
conn.opening(sock, target); conn.opening(sock, target);
@ -159,17 +165,17 @@ public class DefaultClientConnectionOperator implements ClientConnectionOperator
} }
final Scheme schm = schemeRegistry.getScheme(target.getSchemeName()); final Scheme schm = schemeRegistry.getScheme(target.getSchemeName());
if (!(schm.getSocketFactory() instanceof LayeredSocketFactory)) { if (!(schm.getSchemeSocketFactory() instanceof LayeredSchemeSocketFactory)) {
throw new IllegalArgumentException throw new IllegalArgumentException
("Target scheme (" + schm.getName() + ("Target scheme (" + schm.getName() +
") must have layered socket factory."); ") must have layered socket factory.");
} }
final LayeredSocketFactory lsf = (LayeredSocketFactory) schm.getSocketFactory(); LayeredSchemeSocketFactory lsf = (LayeredSchemeSocketFactory) schm.getSchemeSocketFactory();
final Socket sock; Socket sock;
try { try {
sock = lsf.createSocket sock = lsf.createLayeredSocket(
(conn.getSocket(), target.getHostName(), target.getPort(), true); conn.getSocket(), target.getHostName(), target.getPort(), true);
} catch (ConnectException ex) { } catch (ConnectException ex) {
throw new HttpHostConnectException(target, ex); throw new HttpHostConnectException(target, ex);
} }

View File

@ -135,7 +135,7 @@ public class ThreadSafeClientConnManager implements ClientConnectionManager {
* *
* @return the connection pool to use * @return the connection pool to use
* *
* @deprecated use {@link #createConnectionPool(ConnPerRouteBean)} * @deprecated use {@link #createConnectionPool()}
*/ */
@Deprecated @Deprecated
protected AbstractConnPool createConnectionPool(final HttpParams params) { protected AbstractConnPool createConnectionPool(final HttpParams params) {

View File

@ -47,7 +47,7 @@ import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry; 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.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.localserver.LocalTestServer; import org.apache.http.localserver.LocalTestServer;
@ -110,8 +110,8 @@ public class TestConnectionReuse extends TestCase {
HttpConnectionParams.setStaleCheckingEnabled(params, false); HttpConnectionParams.setStaleCheckingEnabled(params, false);
SchemeRegistry supportedSchemes = new SchemeRegistry(); SchemeRegistry supportedSchemes = new SchemeRegistry();
SocketFactory sf = PlainSocketFactory.getSocketFactory(); SchemeSocketFactory sf = PlainSocketFactory.getSocketFactory();
supportedSchemes.register(new Scheme("http", sf, 80)); supportedSchemes.register(new Scheme("http", 80, sf));
ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(supportedSchemes); ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(supportedSchemes);
mgr.setMaxTotalConnections(5); mgr.setMaxTotalConnections(5);
@ -180,8 +180,8 @@ public class TestConnectionReuse extends TestCase {
HttpConnectionParams.setStaleCheckingEnabled(params, false); HttpConnectionParams.setStaleCheckingEnabled(params, false);
SchemeRegistry supportedSchemes = new SchemeRegistry(); SchemeRegistry supportedSchemes = new SchemeRegistry();
SocketFactory sf = PlainSocketFactory.getSocketFactory(); SchemeSocketFactory sf = PlainSocketFactory.getSocketFactory();
supportedSchemes.register(new Scheme("http", sf, 80)); supportedSchemes.register(new Scheme("http", 80, sf));
ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(supportedSchemes); ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(supportedSchemes);
mgr.setMaxTotalConnections(5); mgr.setMaxTotalConnections(5);
@ -240,8 +240,8 @@ public class TestConnectionReuse extends TestCase {
HttpConnectionParams.setStaleCheckingEnabled(params, false); HttpConnectionParams.setStaleCheckingEnabled(params, false);
SchemeRegistry supportedSchemes = new SchemeRegistry(); SchemeRegistry supportedSchemes = new SchemeRegistry();
SocketFactory sf = PlainSocketFactory.getSocketFactory(); SchemeSocketFactory sf = PlainSocketFactory.getSocketFactory();
supportedSchemes.register(new Scheme("http", sf, 80)); supportedSchemes.register(new Scheme("http", 80, sf));
ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(supportedSchemes); ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(supportedSchemes);
mgr.setMaxTotalConnections(5); mgr.setMaxTotalConnections(5);
@ -301,8 +301,8 @@ public class TestConnectionReuse extends TestCase {
HttpConnectionParams.setStaleCheckingEnabled(params, false); HttpConnectionParams.setStaleCheckingEnabled(params, false);
SchemeRegistry supportedSchemes = new SchemeRegistry(); SchemeRegistry supportedSchemes = new SchemeRegistry();
SocketFactory sf = PlainSocketFactory.getSocketFactory(); SchemeSocketFactory sf = PlainSocketFactory.getSocketFactory();
supportedSchemes.register(new Scheme("http", sf, 80)); supportedSchemes.register(new Scheme("http", 80, sf));
ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(supportedSchemes); ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(supportedSchemes);
mgr.setMaxTotalConnections(1); mgr.setMaxTotalConnections(1);

View File

@ -61,48 +61,41 @@ public class TestScheme extends TestCase {
} }
public void testConstructor() { public void testConstructor() {
Scheme http = new Scheme Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory());
("http", PlainSocketFactory.getSocketFactory(), 80);
assertEquals("http", http.getName()); assertEquals("http", http.getName());
assertEquals(80, http.getDefaultPort()); assertEquals(80, http.getDefaultPort());
assertSame(PlainSocketFactory.getSocketFactory(), assertSame(PlainSocketFactory.getSocketFactory(), http.getSchemeSocketFactory());
http.getSocketFactory());
assertFalse(http.isLayered()); assertFalse(http.isLayered());
Scheme https = new Scheme Scheme https = new Scheme("https", 443, SecureSocketFactoryMockup.INSTANCE);
("https", SecureSocketFactoryMockup.INSTANCE, 443);
// ("https", SSLSocketFactory.getSocketFactory(), 443);
assertEquals("https", https.getName()); assertEquals("https", https.getName());
assertEquals(443, https.getDefaultPort()); assertEquals(443, https.getDefaultPort());
assertSame(//SSLSocketFactory.getSocketFactory() assertSame(SecureSocketFactoryMockup.INSTANCE, https.getSchemeSocketFactory());
SecureSocketFactoryMockup.INSTANCE,
https.getSocketFactory());
assertTrue(https.isLayered()); assertTrue(https.isLayered());
Scheme hTtP = new Scheme Scheme hTtP = new Scheme("hTtP", 80, PlainSocketFactory.getSocketFactory());
("hTtP", PlainSocketFactory.getSocketFactory(), 80);
assertEquals("http", hTtP.getName()); assertEquals("http", hTtP.getName());
// the rest is no different from above // the rest is no different from above
try { try {
new Scheme(null, PlainSocketFactory.getSocketFactory(), 80); new Scheme(null, 80, PlainSocketFactory.getSocketFactory());
fail("IllegalArgumentException should have been thrown"); fail("IllegalArgumentException should have been thrown");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
// expected // expected
} }
try { try {
new Scheme("http", null, 80); new Scheme("http", 80, null);
fail("IllegalArgumentException should have been thrown"); fail("IllegalArgumentException should have been thrown");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
// expected // expected
} }
try { try {
new Scheme("http", PlainSocketFactory.getSocketFactory(), -1); new Scheme("http", -1, PlainSocketFactory.getSocketFactory());
fail("IllegalArgumentException should have been thrown"); fail("IllegalArgumentException should have been thrown");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
// expected // expected
} }
try { try {
new Scheme("http", PlainSocketFactory.getSocketFactory(), 70000); new Scheme("http", 70000, PlainSocketFactory.getSocketFactory());
fail("IllegalArgumentException should have been thrown"); fail("IllegalArgumentException should have been thrown");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
// expected // expected
@ -112,13 +105,9 @@ public class TestScheme extends TestCase {
public void testRegisterUnregister() { public void testRegisterUnregister() {
SchemeRegistry schmreg = new SchemeRegistry(); SchemeRegistry schmreg = new SchemeRegistry();
Scheme http = new Scheme Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory());
("http", PlainSocketFactory.getSocketFactory(), 80); Scheme https = new Scheme("https", 443, SecureSocketFactoryMockup.INSTANCE);
Scheme https = new Scheme Scheme myhttp = new Scheme("http", 80, PlainSocketFactory.getSocketFactory());
("https", SecureSocketFactoryMockup.INSTANCE, 443);
// ("https", SSLSocketFactory.getSocketFactory(), 443);
Scheme myhttp = new Scheme
("http", PlainSocketFactory.getSocketFactory(), 80);
HttpHost host = new HttpHost("www.test.invalid", -1, "http"); HttpHost host = new HttpHost("www.test.invalid", -1, "http");
HttpHost hosts = new HttpHost("www.test.invalid", -1, "https"); HttpHost hosts = new HttpHost("www.test.invalid", -1, "https");
@ -151,11 +140,8 @@ public class TestScheme extends TestCase {
assertNotNull(names); assertNotNull(names);
assertTrue(names.isEmpty()); assertTrue(names.isEmpty());
Scheme http = new Scheme Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory());
("http", PlainSocketFactory.getSocketFactory(), 80); Scheme https = new Scheme("https", 443, SecureSocketFactoryMockup.INSTANCE);
Scheme https = new Scheme
("https", SecureSocketFactoryMockup.INSTANCE, 443);
// ("https", SSLSocketFactory.getSocketFactory(), 443);
schmreg.register(http); schmreg.register(http);
schmreg.register(https); schmreg.register(https);
@ -227,34 +213,25 @@ public class TestScheme extends TestCase {
} }
public void testResolvePort() { public void testResolvePort() {
Scheme http = new Scheme Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory());
("http", PlainSocketFactory.getSocketFactory(), 80);
assertEquals(8080, http.resolvePort(8080)); assertEquals(8080, http.resolvePort(8080));
assertEquals(80, http.resolvePort(-1)); assertEquals(80, http.resolvePort(-1));
} }
public void testHashCode() { public void testHashCode() {
Scheme http = new Scheme Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory());
("http", PlainSocketFactory.getSocketFactory(), 80); Scheme myhttp = new Scheme("http", 80, PlainSocketFactory.getSocketFactory());
Scheme myhttp = new Scheme Scheme https = new Scheme("https", 443, SecureSocketFactoryMockup.INSTANCE);
("http", PlainSocketFactory.getSocketFactory(), 80);
Scheme https = new Scheme
("https", SecureSocketFactoryMockup.INSTANCE, 443);
// ("https", SSLSocketFactory.getSocketFactory(), 443);
assertTrue(http.hashCode() != https.hashCode()); // not guaranteed assertTrue(http.hashCode() != https.hashCode()); // not guaranteed
assertTrue(http.hashCode() == myhttp.hashCode()); assertTrue(http.hashCode() == myhttp.hashCode());
} }
public void testEquals() { public void testEquals() {
Scheme http = new Scheme Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory());
("http", PlainSocketFactory.getSocketFactory(), 80); Scheme myhttp = new Scheme("http", 80, PlainSocketFactory.getSocketFactory());
Scheme myhttp = new Scheme Scheme https = new Scheme("https", 443, SecureSocketFactoryMockup.INSTANCE);
("http", PlainSocketFactory.getSocketFactory(), 80);
Scheme https = new Scheme
("https", SecureSocketFactoryMockup.INSTANCE, 443);
// ("https", SSLSocketFactory.getSocketFactory(), 443);
assertFalse(http.equals(https)); assertFalse(http.equals(https));
assertFalse(http.equals(null)); assertFalse(http.equals(null));
@ -265,8 +242,7 @@ public class TestScheme extends TestCase {
} }
public void testToString() { public void testToString() {
Scheme http = new Scheme Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory());
("http", PlainSocketFactory.getSocketFactory(), 80);
// test it twice, the result is cached // test it twice, the result is cached
assertEquals("http:80", http.toString()); assertEquals("http:80", http.toString());
assertEquals("http:80", http.toString()); assertEquals("http:80", http.toString());

View File

@ -50,7 +50,7 @@ public class TestScheme extends TestCase {
} }
public void testPortResolution() { 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(0));
assertEquals(80, http.resolvePort(-1)); assertEquals(80, http.resolvePort(-1));
assertEquals(8080, http.resolvePort(8080)); assertEquals(8080, http.resolvePort(8080));

View File

@ -168,10 +168,9 @@ public class TestSSLSocketFactory extends TestCase {
TestX509HostnameVerifier hostnameVerifier = new TestX509HostnameVerifier(); TestX509HostnameVerifier hostnameVerifier = new TestX509HostnameVerifier();
SSLSocketFactory socketFactory = new SSLSocketFactory(sslcontext); SSLSocketFactory socketFactory = new SSLSocketFactory(sslcontext, hostnameVerifier);
socketFactory.setHostnameVerifier(hostnameVerifier);
Scheme https = new Scheme("https", socketFactory, 443); Scheme https = new Scheme("https", 443, socketFactory);
DefaultHttpClient httpclient = new DefaultHttpClient(); DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getConnectionManager().getSchemeRegistry().register(https); httpclient.getConnectionManager().getSchemeRegistry().register(https);

View File

@ -185,7 +185,7 @@ public class TestContentCodings extends ServerTestBase {
int clients = 100; int clients = 100;
SchemeRegistry schemeRegistry = new SchemeRegistry(); 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); ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(schemeRegistry);
cm.setMaxTotalConnections(clients); cm.setMaxTotalConnections(clients);

View File

@ -150,7 +150,7 @@ public class TestDefaultClientRequestDirector extends BasicServerTestBase {
CountDownLatch releaseLatch = new CountDownLatch(1); CountDownLatch releaseLatch = new CountDownLatch(1);
SchemeRegistry registry = new SchemeRegistry(); 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); SingleClientConnManager conMan = new SingleClientConnManager(registry);
final AtomicReference<Throwable> throwableRef = new AtomicReference<Throwable>(); final AtomicReference<Throwable> throwableRef = new AtomicReference<Throwable>();
@ -190,7 +190,7 @@ public class TestDefaultClientRequestDirector extends BasicServerTestBase {
this.localServer.register("*", new BasicService()); this.localServer.register("*", new BasicService());
SchemeRegistry registry = new SchemeRegistry(); 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); SingleClientConnManager conMan = new SingleClientConnManager(registry);
final AtomicReference<Throwable> throwableRef = new AtomicReference<Throwable>(); final AtomicReference<Throwable> throwableRef = new AtomicReference<Throwable>();
@ -236,7 +236,7 @@ public class TestDefaultClientRequestDirector extends BasicServerTestBase {
this.localServer.register("*", new BasicRedirectService(port)); this.localServer.register("*", new BasicRedirectService(port));
SchemeRegistry registry = new SchemeRegistry(); 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 connLatch = new CountDownLatch(1);
CountDownLatch awaitLatch = new CountDownLatch(1); CountDownLatch awaitLatch = new CountDownLatch(1);
@ -295,7 +295,7 @@ public class TestDefaultClientRequestDirector extends BasicServerTestBase {
this.localServer.register("*", new ThrowingService()); this.localServer.register("*", new ThrowingService());
SchemeRegistry registry = new SchemeRegistry(); 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); ConnMan3 conMan = new ConnMan3(registry);
DefaultHttpClient client = new DefaultHttpClient(conMan, new BasicHttpParams()); DefaultHttpClient client = new DefaultHttpClient(conMan, new BasicHttpParams());
@ -474,7 +474,7 @@ public class TestDefaultClientRequestDirector extends BasicServerTestBase {
public SchemeRegistry getSchemeRegistry() { public SchemeRegistry getSchemeRegistry() {
SchemeRegistry registry = new SchemeRegistry(); SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", new SocketFactoryMockup(null), 80)); registry.register(new Scheme("http", 80, new SocketFactoryMockup(null)));
return registry; return registry;
} }
@ -549,7 +549,7 @@ public class TestDefaultClientRequestDirector extends BasicServerTestBase {
public SchemeRegistry getSchemeRegistry() { public SchemeRegistry getSchemeRegistry() {
SchemeRegistry registry = new SchemeRegistry(); SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", new SocketFactoryMockup(null), 80)); registry.register(new Scheme("http", 80, new SocketFactoryMockup(null)));
return registry; return registry;
} }

View File

@ -48,7 +48,7 @@ public class TestRequestRetryHandler extends TestCase {
throws Exception { throws Exception {
SchemeRegistry schemeRegistry = new SchemeRegistry(); 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); ClientConnectionManager connManager = new ThreadSafeClientConnManager(schemeRegistry);
assertOnRetry(connManager); assertOnRetry(connManager);
@ -58,14 +58,14 @@ public class TestRequestRetryHandler extends TestCase {
throws Exception { throws Exception {
SchemeRegistry schemeRegistry = new SchemeRegistry(); 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); ClientConnectionManager connManager = new SingleClientConnManager(schemeRegistry);
assertOnRetry(connManager); assertOnRetry(connManager);
} }
protected void assertOnRetry(ClientConnectionManager connManager) throws Exception { protected void assertOnRetry(ClientConnectionManager connManager) throws Exception {
SchemeRegistry schemeRegistry = new SchemeRegistry(); 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); DefaultHttpClient client = new DefaultHttpClient(connManager);
TestHttpRequestRetryHandler testRetryHandler = new TestHttpRequestRetryHandler(); TestHttpRequestRetryHandler testRetryHandler = new TestHttpRequestRetryHandler();

View File

@ -27,7 +27,6 @@
package org.apache.http.impl.conn; package org.apache.http.impl.conn;
import java.net.Proxy; import java.net.Proxy;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; 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.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.scheme.SocketFactory;
import org.apache.http.mockup.ProxySelectorMockup; import org.apache.http.mockup.ProxySelectorMockup;
/** /**
* Tests for <code>ProxySelectorRoutePlanner</code>. * Tests for <code>ProxySelectorRoutePlanner</code>.
*/ */
@ -81,8 +77,7 @@ public class TestProxySelRoutePlanner extends TestCase {
public SchemeRegistry createSchemeRegistry() { public SchemeRegistry createSchemeRegistry() {
SchemeRegistry schreg = new SchemeRegistry(); SchemeRegistry schreg = new SchemeRegistry();
SocketFactory sf = PlainSocketFactory.getSocketFactory(); schreg.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
schreg.register(new Scheme("http", sf, 80));
return schreg; return schreg;
} }

View File

@ -43,7 +43,6 @@ import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry; 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.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams; import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams; import org.apache.http.params.HttpParams;
@ -122,8 +121,7 @@ public class TestTSCCMNoServer extends TestCase {
public SchemeRegistry createSchemeRegistry() { public SchemeRegistry createSchemeRegistry() {
SchemeRegistry schreg = new SchemeRegistry(); SchemeRegistry schreg = new SchemeRegistry();
SocketFactory sf = PlainSocketFactory.getSocketFactory(); schreg.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
schreg.register(new Scheme("http", sf, 80));
return schreg; return schreg;
} }

View File

@ -30,6 +30,7 @@ package org.apache.http.impl.conn;
import java.io.IOException; import java.io.IOException;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
import java.net.SocketException; import java.net.SocketException;
import java.net.UnknownHostException; 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.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry; 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.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.localserver.ServerTestBase; import org.apache.http.localserver.ServerTestBase;
import org.apache.http.message.BasicHttpRequest; import org.apache.http.message.BasicHttpRequest;
@ -505,8 +506,9 @@ public class TestTSCCMWithServer extends ServerTestBase {
public void testAbortDuringConnecting() throws Exception { public void testAbortDuringConnecting() throws Exception {
final CountDownLatch connectLatch = new CountDownLatch(1); final CountDownLatch connectLatch = new CountDownLatch(1);
final StallingSocketFactory stallingSocketFactory = new StallingSocketFactory(connectLatch, WaitPolicy.BEFORE_CONNECT, PlainSocketFactory.getSocketFactory()); final StallingSocketFactory stallingSocketFactory = new StallingSocketFactory(
Scheme scheme = new Scheme("http", stallingSocketFactory, 80); connectLatch, WaitPolicy.BEFORE_CONNECT, PlainSocketFactory.getSocketFactory());
Scheme scheme = new Scheme("http", 80, stallingSocketFactory);
SchemeRegistry registry = new SchemeRegistry(); SchemeRegistry registry = new SchemeRegistry();
registry.register(scheme); registry.register(scheme);
@ -555,8 +557,9 @@ public class TestTSCCMWithServer extends ServerTestBase {
public void testAbortBeforeSocketCreate() throws Exception { public void testAbortBeforeSocketCreate() throws Exception {
final CountDownLatch connectLatch = new CountDownLatch(1); final CountDownLatch connectLatch = new CountDownLatch(1);
final StallingSocketFactory stallingSocketFactory = new StallingSocketFactory(connectLatch, WaitPolicy.BEFORE_CREATE, PlainSocketFactory.getSocketFactory()); final StallingSocketFactory stallingSocketFactory = new StallingSocketFactory(
Scheme scheme = new Scheme("http", stallingSocketFactory, 80); connectLatch, WaitPolicy.BEFORE_CREATE, PlainSocketFactory.getSocketFactory());
Scheme scheme = new Scheme("http", 80, stallingSocketFactory);
SchemeRegistry registry = new SchemeRegistry(); SchemeRegistry registry = new SchemeRegistry();
registry.register(scheme); registry.register(scheme);
@ -607,8 +610,9 @@ public class TestTSCCMWithServer extends ServerTestBase {
public void testAbortAfterSocketConnect() throws Exception { public void testAbortAfterSocketConnect() throws Exception {
final CountDownLatch connectLatch = new CountDownLatch(1); final CountDownLatch connectLatch = new CountDownLatch(1);
final StallingSocketFactory stallingSocketFactory = new StallingSocketFactory(connectLatch, WaitPolicy.AFTER_CONNECT, PlainSocketFactory.getSocketFactory()); final StallingSocketFactory stallingSocketFactory = new StallingSocketFactory(
Scheme scheme = new Scheme("http", stallingSocketFactory, 80); connectLatch, WaitPolicy.AFTER_CONNECT, PlainSocketFactory.getSocketFactory());
Scheme scheme = new Scheme("http", 80, stallingSocketFactory);
SchemeRegistry registry = new SchemeRegistry(); SchemeRegistry registry = new SchemeRegistry();
registry.register(scheme); registry.register(scheme);
@ -780,24 +784,27 @@ public class TestTSCCMWithServer extends ServerTestBase {
} }
} }
private static class StallingSocketFactory extends LatchSupport implements SocketFactory { private static class StallingSocketFactory extends LatchSupport implements SchemeSocketFactory {
private final SocketFactory delegate;
private final SchemeSocketFactory delegate;
public StallingSocketFactory(CountDownLatch continueLatch, public StallingSocketFactory(
WaitPolicy waitPolicy, SocketFactory delegate) { final CountDownLatch continueLatch,
final WaitPolicy waitPolicy,
final SchemeSocketFactory delegate) {
super(continueLatch, waitPolicy); super(continueLatch, waitPolicy);
this.delegate = delegate; this.delegate = delegate;
} }
public Socket connectSocket(Socket sock, String host, int port, public Socket connectSocket(
InetAddress localAddress, int localPort, HttpParams params) final Socket sock,
throws IOException, UnknownHostException, final InetSocketAddress remoteAddress,
ConnectTimeoutException { final InetSocketAddress localAddress,
final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
if(waitPolicy == WaitPolicy.BEFORE_CONNECT) if(waitPolicy == WaitPolicy.BEFORE_CONNECT)
latch(); latch();
Socket socket = delegate.connectSocket(sock, host, port, localAddress, Socket socket = delegate.connectSocket(sock, remoteAddress, localAddress, params);
localPort, params);
if(waitPolicy == WaitPolicy.AFTER_CONNECT) if(waitPolicy == WaitPolicy.AFTER_CONNECT)
latch(); latch();

View File

@ -42,7 +42,7 @@ import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry; 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.conn.params.ConnPerRoute;
import org.apache.http.impl.conn.GetConnThread; import org.apache.http.impl.conn.GetConnThread;
@ -130,8 +130,8 @@ public class TestSpuriousWakeup extends TestCase {
public void testSpuriousWakeup() throws Exception { public void testSpuriousWakeup() throws Exception {
SchemeRegistry schreg = new SchemeRegistry(); SchemeRegistry schreg = new SchemeRegistry();
SocketFactory sf = PlainSocketFactory.getSocketFactory(); SchemeSocketFactory sf = PlainSocketFactory.getSocketFactory();
schreg.register(new Scheme("http", sf, 80)); schreg.register(new Scheme("http", 80, sf));
XTSCCM mgr = new XTSCCM(schreg); XTSCCM mgr = new XTSCCM(schreg);
try { try {

View File

@ -27,6 +27,8 @@
package org.apache.http.localserver; package org.apache.http.localserver;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
import org.apache.http.HttpHost; 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.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry; 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.impl.DefaultHttpClientConnection;
import org.apache.http.params.HttpParams; import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams; import org.apache.http.params.HttpProtocolParams;
@ -116,8 +118,8 @@ public abstract class ServerTestBase extends BasicServerTestBase {
if (supportedSchemes == null) { if (supportedSchemes == null) {
supportedSchemes = new SchemeRegistry(); supportedSchemes = new SchemeRegistry();
SocketFactory sf = PlainSocketFactory.getSocketFactory(); SchemeSocketFactory sf = PlainSocketFactory.getSocketFactory();
supportedSchemes.register(new Scheme("http", sf, 80)); supportedSchemes.register(new Scheme("http", 80, sf));
} }
if (httpProcessor == null) { if (httpProcessor == null) {
@ -179,8 +181,9 @@ public abstract class ServerTestBase extends BasicServerTestBase {
int port = schm.resolvePort(target.getPort()); int port = schm.resolvePort(target.getPort());
DefaultHttpClientConnection conn = new DefaultHttpClientConnection(); DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
Socket sock = schm.getSocketFactory().connectSocket InetSocketAddress address = new InetSocketAddress(
(null, target.getHostName(), port, null, 0, params); InetAddress.getByName(target.getHostName()), port);
Socket sock = schm.getSchemeSocketFactory().connectSocket(null, address, null, params);
conn.bind(sock, params); conn.bind(sock, params);
return conn; return conn;

View File

@ -29,18 +29,16 @@ package org.apache.http.mockup;
import java.net.Socket; import java.net.Socket;
import org.apache.http.conn.scheme.LayeredSocketFactory; import org.apache.http.conn.scheme.LayeredSchemeSocketFactory;
/** /**
* {@link LayeredSocketFactory} mockup implementation. * {@link LayeredSocketFactory} mockup implementation.
*/ */
public class SecureSocketFactoryMockup extends SocketFactoryMockup public class SecureSocketFactoryMockup extends SocketFactoryMockup
implements LayeredSocketFactory { implements LayeredSchemeSocketFactory {
/* A default instance of this mockup. */ /* A default instance of this mockup. */
public final static LayeredSocketFactory INSTANCE = public final static LayeredSchemeSocketFactory INSTANCE = new SecureSocketFactoryMockup("INSTANCE");
new SecureSocketFactoryMockup("INSTANCE");
public SecureSocketFactoryMockup(String name) { public SecureSocketFactoryMockup(String name) {
super(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) { boolean autoClose) {
throw new UnsupportedOperationException("I'm a mockup!"); throw new UnsupportedOperationException("I'm a mockup!");
} }
} }

View File

@ -27,27 +27,26 @@
package org.apache.http.mockup; package org.apache.http.mockup;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket; 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; import org.apache.http.params.HttpParams;
/** /**
* {@link SocketFactory} mockup implementation. * {@link SocketFactory} mockup implementation.
*/ */
public class SocketFactoryMockup implements SocketFactory { public class SocketFactoryMockup implements SchemeSocketFactory {
/* A default instance of this mockup. */ /* A default instance of this mockup. */
public final static SocketFactory INSTANCE = public final static SchemeSocketFactory INSTANCE = new SocketFactoryMockup("INSTANCE");
new SocketFactoryMockup("INSTANCE");
/** The name of this mockup socket factory. */ /** The name of this mockup socket factory. */
protected final String mockup_name; protected final String mockup_name;
public SocketFactoryMockup(String name) { public SocketFactoryMockup(String name) {
mockup_name = (name != null) ? name : String.valueOf(hashCode()); mockup_name = (name != null) ? name : String.valueOf(hashCode());
} }
@ -59,14 +58,15 @@ public class SocketFactoryMockup implements SocketFactory {
return "SocketFactoryMockup." + mockup_name; return "SocketFactoryMockup." + mockup_name;
} }
public Socket createSocket() { public Socket createSocket() {
throw new UnsupportedOperationException("I'm a mockup!"); throw new UnsupportedOperationException("I'm a mockup!");
} }
public Socket connectSocket(Socket sock, String host, int port, public Socket connectSocket(
InetAddress localAddress, int localPort, Socket sock,
HttpParams params) { InetSocketAddress remoteAddress,
InetSocketAddress localAddress,
HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
throw new UnsupportedOperationException("I'm a mockup!"); 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... // no way that the argument is from *this* factory...
throw new IllegalArgumentException("I'm a mockup!"); throw new IllegalArgumentException("I'm a mockup!");
} }
} }

View File

@ -236,7 +236,7 @@
<title>Socket factories</title> <title>Socket factories</title>
<para>HTTP connections make use of a <classname>java.net.Socket</classname> object <para>HTTP connections make use of a <classname>java.net.Socket</classname> object
internally to handle transmission of data across the wire. They, however, rely on internally to handle transmission of data across the wire. They, however, rely on
<interfacename>SocketFactory</interfacename> interface to create, initialize and <interfacename>SchemeSocketFactory</interfacename> interface to create, initialize and
connect sockets. This enables the users of HttpClient to provide application specific connect sockets. This enables the users of HttpClient to provide application specific
socket initialization code at runtime. <classname>PlainSocketFactory</classname> is the socket initialization code at runtime. <classname>PlainSocketFactory</classname> is the
default factory for creating and initializing plain (unencrypted) sockets.</para> default factory for creating and initializing plain (unencrypted) sockets.</para>
@ -248,17 +248,19 @@ Socket socket = sf.createSocket();
HttpParams params = new BasicHttpParams(); HttpParams params = new BasicHttpParams();
params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 1000L); 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);
]]></programlisting> ]]></programlisting>
<section> <section>
<title>Secure socket layering</title> <title>Secure socket layering</title>
<para><interfacename>LayeredSocketFactory</interfacename> is an extension of <para><interfacename>LayeredSchemeSocketFactory</interfacename> is an extension of
<interfacename>SocketFactory</interfacename> interface. Layered socket factories <interfacename>SchemeSocketFactory</interfacename> interface. Layered socket
are capable of creating sockets that are layered over an existing plain socket. factories are capable of creating sockets layered over an existing plain socket.
Socket layering is used primarily for creating secure sockets through proxies. Socket layering is used primarily for creating secure sockets through proxies.
HttpClient ships with SSLSocketFactory that implements SSL/TLS layering. Please note HttpClient ships with <classname>SSLSocketFactory</classname> that implements
HttpClient does not use any custom encryption functionality. It is fully reliant on SSL/TLS layering. Please note HttpClient does not use any custom encryption
standard Java Cryptography (JCE) and Secure Sockets (JSEE) extensions.</para> functionality. It is fully reliant on standard Java Cryptography (JCE) and Secure
Sockets (JSEE) extensions.</para>
</section> </section>
<section> <section>
<title>SSL/TLS customization</title> <title>SSL/TLS customization</title>
@ -300,7 +302,8 @@ socket.setEnabledCipherSuites(new String[] { "SSL_RSA_WITH_RC4_128_MD5" });
HttpParams params = new BasicHttpParams(); HttpParams params = new BasicHttpParams();
params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 1000L); 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);
]]></programlisting> ]]></programlisting>
<para>Customization of SSLSocketFactory implies a certain degree of familiarity with the <para>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 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 implementation. One can specify a different hostname verifier implementation if
desired</para> desired</para>
<programlisting><![CDATA[ <programlisting><![CDATA[
SSLSocketFactory sf = new SSLSocketFactory(SSLContext.getInstance("TLS")); SSLSocketFactory sf = new SSLSocketFactory(
sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER); SSLContext.getInstance("TLS"),
SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
]]></programlisting> ]]></programlisting>
</section> </section>
</section> </section>
@ -371,11 +375,12 @@ sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
a set of <classname>Scheme</classname>s HttpClient can choose from when trying to a set of <classname>Scheme</classname>s HttpClient can choose from when trying to
establish a connection by a request URI:</para> establish a connection by a request URI:</para>
<programlisting><![CDATA[ <programlisting><![CDATA[
Scheme http = new Scheme("http", PlainSocketFactory.getSocketFactory(), 80); Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory());
SSLSocketFactory sf = new SSLSocketFactory(SSLContext.getInstance("TLS")); SSLSocketFactory sf = new SSLSocketFactory(
sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER); SSLContext.getInstance("TLS"),
Scheme https = new Scheme("https", sf, 443); SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
Scheme https = new Scheme("https", 443, sf);
SchemeRegistry sr = new SchemeRegistry(); SchemeRegistry sr = new SchemeRegistry();
sr.register(http); sr.register(http);
@ -434,7 +439,7 @@ httpclient.setRoutePlanner(new HttpRoutePlanner() {
<interfacename>ClientConnectionOperator</interfacename> interface represents a <interfacename>ClientConnectionOperator</interfacename> interface represents a
strategy for creating <interfacename>OperatedClientConnection</interfacename> strategy for creating <interfacename>OperatedClientConnection</interfacename>
instances and updating the underlying socket of those objects. Implementations will instances and updating the underlying socket of those objects. Implementations will
most likely make use <interfacename>SocketFactory</interfacename>s to create most likely make use <interfacename>SchemeSocketFactory</interfacename>s to create
<classname>java.net.Socket</classname> instances. The <classname>java.net.Socket</classname> instances. The
<interfacename>ClientConnectionOperator</interfacename> interface enables the <interfacename>ClientConnectionOperator</interfacename> interface enables the
users of HttpClient to provide a custom strategy for connection operators as well as users of HttpClient to provide a custom strategy for connection operators as well as
@ -475,7 +480,7 @@ httpclient.setRoutePlanner(new HttpRoutePlanner() {
unintentionally.</para> unintentionally.</para>
<para>This is an example of acquiring a connection from a connection manager:</para> <para>This is an example of acquiring a connection from a connection manager:</para>
<programlisting><![CDATA[ <programlisting><![CDATA[
Scheme http = new Scheme("http", PlainSocketFactory.getSocketFactory(), 80); Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory());
SchemeRegistry sr = new SchemeRegistry(); SchemeRegistry sr = new SchemeRegistry();
sr.register(http); sr.register(http);
ClientConnectionManager connMrg = new SingleClientConnManager(sr); ClientConnectionManager connMrg = new SingleClientConnManager(sr);
@ -562,9 +567,9 @@ try {
<programlisting><![CDATA[ <programlisting><![CDATA[
SchemeRegistry schemeRegistry = new SchemeRegistry(); SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register( schemeRegistry.register(
new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
schemeRegistry.register( schemeRegistry.register(
new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); new Scheme("https", 443, SSLSocketFactory.getSocketFactory()));
ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(schemeRegistry); ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(schemeRegistry);
// Increase max total connection to 200 // Increase max total connection to 200
@ -630,7 +635,7 @@ httpclient.getConnectionManager().shutdown();
<programlisting><![CDATA[ <programlisting><![CDATA[
SchemeRegistry schemeRegistry = new SchemeRegistry(); SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register( schemeRegistry.register(
new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
ClientConnectionManager cm = new ThreadSafeClientConnManager(schemeRegistry); ClientConnectionManager cm = new ThreadSafeClientConnManager(schemeRegistry);
HttpClient httpClient = new DefaultHttpClient(cm); HttpClient httpClient = new DefaultHttpClient(cm);