SocketFactory.isSecure(...)
git-svn-id: https://svn.apache.org/repos/asf/jakarta/httpcomponents/httpclient/trunk@498143 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3d8d85a915
commit
43601a506d
|
@ -95,12 +95,19 @@ public class TalkativeSocketFactory implements SocketFactory {
|
|||
HttpParams params)
|
||||
throws IOException {
|
||||
|
||||
// just delegate the call to the default
|
||||
// just delegate the call to the default factory
|
||||
return PlainSocketFactory.getSocketFactory().connectSocket
|
||||
(sock, host, port, localAddress, localPort, params);
|
||||
}
|
||||
|
||||
|
||||
// non-javadoc, see interface org.apache.http.conn.SocketFactory
|
||||
public boolean isSecure(Socket sock)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a byte for debug printing.
|
||||
*
|
||||
|
|
|
@ -114,6 +114,41 @@ public final class PlainSocketFactory implements SocketFactory {
|
|||
} // connectSocket
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether a socket connection is secure.
|
||||
* This factory creates plain socket connections
|
||||
* which are not considered secure.
|
||||
*
|
||||
* @param sock the connected socket
|
||||
*
|
||||
* @return <code>false</code>
|
||||
*
|
||||
* @throws IllegalArgumentException if the argument is invalid
|
||||
*/
|
||||
public final boolean isSecure(Socket sock)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
if (sock == null) {
|
||||
throw new IllegalArgumentException("Socket may not be null.");
|
||||
}
|
||||
// This class check assumes that createSocket() calls the constructor
|
||||
// directly. If it was using javax.net.SocketFactory, we couldn't make
|
||||
// an assumption about the socket class here.
|
||||
if (sock.getClass() != Socket.class) {
|
||||
throw new IllegalArgumentException
|
||||
("Socket not created by this factory.");
|
||||
}
|
||||
// This check is performed last since it calls a method implemented
|
||||
// by the argument object. getClass() is final in java.lang.Object.
|
||||
if (sock.isClosed()) {
|
||||
throw new IllegalArgumentException("Socket is closed.");
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
} // isSecure
|
||||
|
||||
|
||||
/**
|
||||
* Compares this factory with an object.
|
||||
* There is only one instance of this class.
|
||||
|
|
|
@ -124,12 +124,13 @@ public class Scheme {
|
|||
/** The default port for this scheme */
|
||||
private int defaultPort;
|
||||
|
||||
/** True if this scheme is secure */
|
||||
private boolean secure;
|
||||
/** True if this scheme allows for layered connections */
|
||||
private boolean layered;
|
||||
|
||||
/**
|
||||
* Constructs a new Protocol. Whether the created scheme is secure depends on
|
||||
* the class of <code>factory</code>.
|
||||
* Constructs a new scheme.
|
||||
* Whether the created scheme allows for layered connections
|
||||
* depends on the class of <code>factory</code>.
|
||||
*
|
||||
* @param name the scheme name (e.g. http, https)
|
||||
* @param factory the factory for creating sockets for communication using
|
||||
|
@ -151,7 +152,7 @@ public class Scheme {
|
|||
this.name = name;
|
||||
this.socketFactory = factory;
|
||||
this.defaultPort = defaultPort;
|
||||
this.secure = (factory instanceof SecureSocketFactory);
|
||||
this.layered = (factory instanceof SecureSocketFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -179,11 +180,12 @@ public class Scheme {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns true if this scheme is secure
|
||||
* @return true if this scheme is secure
|
||||
* Indicates whether this scheme allows for layered connections.
|
||||
* @return <code>true</code> if layered connections are possible,
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public boolean isSecure() {
|
||||
return secure;
|
||||
public boolean isLayered() {
|
||||
return layered;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -223,7 +225,7 @@ public class Scheme {
|
|||
return (
|
||||
defaultPort == p.getDefaultPort()
|
||||
&& name.equalsIgnoreCase(p.getName())
|
||||
&& secure == p.isSecure()
|
||||
&& layered == p.isLayered()
|
||||
&& socketFactory.equals(p.getSocketFactory()));
|
||||
|
||||
} else {
|
||||
|
@ -240,7 +242,7 @@ public class Scheme {
|
|||
int hash = LangUtils.HASH_SEED;
|
||||
hash = LangUtils.hashCode(hash, this.defaultPort);
|
||||
hash = LangUtils.hashCode(hash, this.name.toLowerCase());
|
||||
hash = LangUtils.hashCode(hash, this.secure);
|
||||
hash = LangUtils.hashCode(hash, this.layered);
|
||||
hash = LangUtils.hashCode(hash, this.socketFactory);
|
||||
return hash;
|
||||
}
|
||||
|
|
|
@ -100,4 +100,38 @@ public interface SocketFactory {
|
|||
HttpParams params
|
||||
) throws IOException, UnknownHostException, ConnectTimeoutException;
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether a socket provides a secure connection.
|
||||
* The socket must be {@link #connectSocket connected}
|
||||
* by this factory.
|
||||
* The factory will <i>not</i> perform I/O operations
|
||||
* in this method.
|
||||
* <br/>
|
||||
* 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 cypher 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
|
||||
;
|
||||
|
||||
}
|
||||
|
|
|
@ -112,8 +112,7 @@ public class DefaultSocketConnectionOperator
|
|||
(sock, target.getHostName(), target.getPort(), local, 0, params);
|
||||
prepareSocket(sock, context, params);
|
||||
|
||||
//@@@ ask the factory whether the new socket is secure?
|
||||
boolean secure = (sf instanceof SecureSocketFactory);
|
||||
final boolean secure = sf.isSecure(sock);
|
||||
|
||||
conn.open(sock, target, secure, params);
|
||||
//@@@ error handling: unprepare the connection?
|
||||
|
@ -166,8 +165,7 @@ public class DefaultSocketConnectionOperator
|
|||
(conn.getSocket(), target.getHostName(), target.getPort(), true);
|
||||
prepareSocket(sock, context, params);
|
||||
|
||||
//@@@ ask the factory whether the new socket is secure?
|
||||
boolean secure = true;
|
||||
final boolean secure = ssf.isSecure(sock);
|
||||
|
||||
conn.update(sock, target, secure, params);
|
||||
//@@@ error handling: close the layered socket in case of exception?
|
||||
|
|
|
@ -295,6 +295,42 @@ public class SSLSocketFactory implements SecureSocketFactory {
|
|||
return sslock;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether a socket connection is secure.
|
||||
* This factory creates TLS/SSL socket connections
|
||||
* which, by default, are considered secure.
|
||||
* <br/>
|
||||
* Derived classes may override this method to perform
|
||||
* runtime checks, for example based on the cypher suite.
|
||||
*
|
||||
* @param sock the connected socket
|
||||
*
|
||||
* @return <code>true</code>
|
||||
*
|
||||
* @throws IllegalArgumentException if the argument is invalid
|
||||
*/
|
||||
public boolean isSecure(Socket sock)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
if (sock == null) {
|
||||
throw new IllegalArgumentException("Socket may not be null.");
|
||||
}
|
||||
// This instanceof check is in line with createSocket() above.
|
||||
if (!(sock instanceof SSLSocket)) {
|
||||
throw new IllegalArgumentException
|
||||
("Socket not created by this factory.");
|
||||
}
|
||||
// This check is performed last since it calls the argument object.
|
||||
if (sock.isClosed()) {
|
||||
throw new IllegalArgumentException("Socket is closed.");
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
} // isSecure
|
||||
|
||||
|
||||
/**
|
||||
* @see SecureSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
|
||||
*/
|
||||
|
|
|
@ -62,12 +62,12 @@ public class TestScheme extends TestCase {
|
|||
assertEquals("http", http.getName());
|
||||
assertEquals(80, http.getDefaultPort());
|
||||
assertEquals(PlainSocketFactory.getSocketFactory(), http.getSocketFactory());
|
||||
assertFalse(http.isSecure());
|
||||
assertFalse(http.isLayered());
|
||||
Scheme https = new Scheme("http", SSLSocketFactory.getSocketFactory(), 443);
|
||||
assertEquals("http", https.getName());
|
||||
assertEquals(443, https.getDefaultPort());
|
||||
assertEquals(SSLSocketFactory.getSocketFactory(), https.getSocketFactory());
|
||||
assertTrue(https.isSecure());
|
||||
assertTrue(https.isLayered());
|
||||
|
||||
try {
|
||||
new Scheme(null, PlainSocketFactory.getSocketFactory(), 80);
|
||||
|
|
Loading…
Reference in New Issue