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:
Roland Weber 2007-01-20 16:48:33 +00:00
parent 3d8d85a915
commit 43601a506d
7 changed files with 130 additions and 18 deletions

View File

@ -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.
*

View File

@ -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.

View File

@ -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;
}

View File

@ -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
;
}

View File

@ -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?

View File

@ -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)
*/

View File

@ -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);