You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2008/12/01 20:09:46 UTC
svn commit: r722180 - in
/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http:
conn/ssl/TestSSLSocketFactory.java localserver/LocalTestServer.java
Author: olegk
Date: Mon Dec 1 11:09:46 2008
New Revision: 722180
URL: http://svn.apache.org/viewvc?rev=722180&view=rev
Log:
* refactored local test server
* added option to specify an SSL context for the local test server
* fixed SSL socket factory test case failing intermittently when running JRE 1.6
Modified:
httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.java
httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/localserver/LocalTestServer.java
Modified: httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.java?rev=722180&r1=722179&r2=722180&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.java Mon Dec 1 11:09:46 2008
@@ -32,14 +32,9 @@
package org.apache.http.conn.ssl;
import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
import java.math.BigInteger;
-import java.net.ServerSocket;
-import java.net.Socket;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PrivateKey;
@@ -47,13 +42,25 @@
import java.security.cert.X509Certificate;
import java.security.spec.RSAPrivateCrtKeySpec;
-import javax.net.ServerSocketFactory;
-import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.localserver.LocalTestServer;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
@@ -81,6 +88,30 @@
return ts;
}
+ static class TestX509HostnameVerifier implements X509HostnameVerifier {
+
+ private boolean fired = false;
+
+ public boolean verify(String host, SSLSession session) {
+ return true;
+ }
+
+ public void verify(String host, SSLSocket ssl) throws IOException {
+ this.fired = true;
+ }
+
+ public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
+ }
+
+ public void verify(String host, X509Certificate cert) throws SSLException {
+ }
+
+ public boolean isFired() {
+ return this.fired;
+ }
+
+ }
+
public void testCreateSocket() throws Exception {
HttpParams params = new BasicHttpParams();
String password = "changeit";
@@ -113,95 +144,44 @@
ks.setKeyEntry("RSA_KEY", pk, pwd, chain);
ks.setCertificateEntry("CERT", chain[2]); // Let's trust ourselves. :-)
- File tempFile = File.createTempFile("junit", "jks");
+ KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory
+ .getDefaultAlgorithm());
+ kmfactory.init(ks, pwd);
+ KeyManager[] keymanagers = kmfactory.getKeyManagers();
+
+ TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
+ TrustManagerFactory.getDefaultAlgorithm());
+ tmfactory.init(ks);
+ TrustManager[] trustmanagers = tmfactory.getTrustManagers();
+
+ SSLContext sslcontext = SSLContext.getInstance("TLSv1");
+ sslcontext.init(keymanagers, trustmanagers, null);
+
+ LocalTestServer server = new LocalTestServer(null, null, null, sslcontext);
+ server.registerDefaultHandlers();
+ server.start();
try {
- String path = tempFile.getCanonicalPath();
- tempFile.deleteOnExit();
- FileOutputStream fOut = new FileOutputStream(tempFile);
- ks.store(fOut, pwd);
- fOut.close();
-
- System.setProperty("javax.net.ssl.keyStore", path);
- System.setProperty("javax.net.ssl.keyStorePassword", password);
- System.setProperty("javax.net.ssl.trustStore", path);
- System.setProperty("javax.net.ssl.trustStorePassword", password);
-
- ServerSocketFactory server = SSLServerSocketFactory.getDefault();
- // Let the operating system just choose an available port:
- ServerSocket serverSocket = server.createServerSocket(0);
- serverSocket.setSoTimeout(30000);
- int port = serverSocket.getLocalPort();
- // System.out.println("\nlistening on port: " + port);
-
- SSLSocketFactory ssf = SSLSocketFactory.getSocketFactory();
- ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
-
- // Test 1 - createSocket()
- IOException[] e = new IOException[1];
- boolean[] success = new boolean[1];
- listen(serverSocket, e, success);
- Socket s = ssf.connectSocket(null, "localhost", port,
- null, 0, params);
- exerciseSocket(s, e, success);
-
- // Test 2 - createSocket( Socket ), where we upgrade a plain socket
- // to SSL.
- success[0] = false;
- listen(serverSocket, e, success);
- s = new Socket("localhost", port);
- s = ssf.createSocket(s, "localhost", port, true);
- exerciseSocket(s, e, success);
- }
- finally {
- tempFile.delete();
+
+ TestX509HostnameVerifier hostnameVerifier = new TestX509HostnameVerifier();
+
+ SSLSocketFactory socketFactory = new SSLSocketFactory(sslcontext);
+ socketFactory.setHostnameVerifier(hostnameVerifier);
+
+ Scheme https = new Scheme("https", socketFactory, 443);
+ DefaultHttpClient httpclient = new DefaultHttpClient();
+ httpclient.getConnectionManager().getSchemeRegistry().register(https);
+
+ HttpHost target = new HttpHost(
+ LocalTestServer.TEST_SERVER_ADDR.getHostName(),
+ server.getServicePort(),
+ "https");
+ HttpGet httpget = new HttpGet("/random/100");
+ HttpResponse response = httpclient.execute(target, httpget);
+ assertEquals(200, response.getStatusLine().getStatusCode());
+ assertTrue(hostnameVerifier.isFired());
+ } finally {
+ server.stop();
}
}
- private static void listen(final ServerSocket ss,
- final IOException[] e,
- final boolean[] success) {
- Runnable r = new Runnable() {
- public void run() {
- try {
- Socket s = ss.accept();
- InputStream in = s.getInputStream();
- OutputStream out = s.getOutputStream();
- out.write("server says hello\n".getBytes());
- byte[] buf = new byte[4096];
- in.read(buf);
- out.close();
- in.close();
- s.close();
- } catch(IOException ioe) {
- e[0] = ioe;
- } finally {
- success[0] = true;
- }
- }
- };
- new Thread(r).start();
- Thread.yield();
- }
-
- private static void exerciseSocket(Socket s, IOException[] e,
- boolean[] success)
- throws IOException {
- InputStream in = s.getInputStream();
- OutputStream out = s.getOutputStream();
- out.write(42);
- byte[] buf = new byte[4096];
- in.read(buf);
- out.close();
- in.close();
- s.close();
- // String response = new String( buf, 0, c );
- while(!success[0]) {
- Thread.yield();
- }
- if(e[0] != null) {
- throw e[0];
- }
- }
-
-
}
Modified: httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/localserver/LocalTestServer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/localserver/LocalTestServer.java?rev=722180&r1=722179&r2=722180&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/localserver/LocalTestServer.java (original)
+++ httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/localserver/LocalTestServer.java Mon Dec 1 11:09:46 2008
@@ -41,6 +41,9 @@
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocketFactory;
+
import org.apache.http.ConnectionReuseStrategy;
import org.apache.http.HttpException;
import org.apache.http.HttpServerConnection;
@@ -85,21 +88,24 @@
new InetSocketAddress("127.0.0.1", 0);
/** The request handler registry. */
- public HttpRequestHandlerRegistry handlerRegistry;
+ private final HttpRequestHandlerRegistry handlerRegistry;
/** The server-side connection re-use strategy. */
- public ConnectionReuseStrategy reuseStrategy;
+ private final ConnectionReuseStrategy reuseStrategy;
/**
* The HTTP processor.
* If the interceptors are thread safe and the list is not
* modified during operation, the processor is thread safe.
*/
- public BasicHttpProcessor httpProcessor;
+ private final BasicHttpProcessor httpProcessor;
/** The server parameters. */
- public HttpParams serverParams;
+ private final HttpParams serverParams;
+ /** Optional SSL context */
+ private final SSLContext sslcontext;
+
/** The server socket, while being served. */
protected volatile ServerSocket servicedSocket;
@@ -116,24 +122,52 @@
* @param proc the HTTP processors to be used by the server, or
* <code>null</code> to use a
* {@link #newProcessor default} processor
+ * @param reuseStrat the connection reuse strategy to be used by the
+ * server, or <code>null</code> to use
+ * {@link #newConnectionReuseStrategy() default}
+ * strategy.
* @param params the parameters to be used by the server, or
* <code>null</code> to use
* {@link #newDefaultParams default} parameters
+ * @param sslcontext optional SSL context if the server is to leverage
+ * SSL/TLS transport security
*/
- public LocalTestServer(BasicHttpProcessor proc, HttpParams params) {
- handlerRegistry = new HttpRequestHandlerRegistry();
- reuseStrategy = new DefaultConnectionReuseStrategy();
- httpProcessor = (proc != null) ? proc : newProcessor();
- serverParams = (params != null) ? params : newDefaultParams();
+ public LocalTestServer(
+ BasicHttpProcessor proc,
+ ConnectionReuseStrategy reuseStrat,
+ HttpParams params,
+ SSLContext sslcontext) {
+ super();
+ this.handlerRegistry = new HttpRequestHandlerRegistry();
+ this.reuseStrategy = (reuseStrat != null) ? reuseStrat: newConnectionReuseStrategy();
+ this.httpProcessor = (proc != null) ? proc : newProcessor();
+ this.serverParams = (params != null) ? params : newDefaultParams();
+ this.sslcontext = sslcontext;
}
/**
+ * Creates a new test server.
+ *
+ * @param proc the HTTP processors to be used by the server, or
+ * <code>null</code> to use a
+ * {@link #newProcessor default} processor
+ * @param params the parameters to be used by the server, or
+ * <code>null</code> to use
+ * {@link #newDefaultParams default} parameters
+ */
+ public LocalTestServer(
+ BasicHttpProcessor proc,
+ HttpParams params) {
+ this(proc, null, params, null);
+ }
+
+ /**
* Obtains an HTTP protocol processor with default interceptors.
*
* @return a protocol processor for server-side use
*/
- public static BasicHttpProcessor newProcessor() {
+ protected BasicHttpProcessor newProcessor() {
BasicHttpProcessor httpproc = new BasicHttpProcessor();
httpproc.addInterceptor(new ResponseDate());
@@ -150,7 +184,7 @@
*
* @return default parameters
*/
- public static HttpParams newDefaultParams() {
+ protected HttpParams newDefaultParams() {
HttpParams params = new BasicHttpParams();
params
.setIntParameter(CoreConnectionPNames.SO_TIMEOUT,
@@ -166,6 +200,11 @@
return params;
}
+ protected ConnectionReuseStrategy newConnectionReuseStrategy() {
+ return new DefaultConnectionReuseStrategy();
+ }
+
+
/**
* Returns the number of connections this test server has accepted.
*/
@@ -210,16 +249,6 @@
/**
- * Specifies the connection re-use strategy.
- *
- * @param strategy the re-use strategy
- */
- public void setReuseStrategy(ConnectionReuseStrategy strategy) {
- reuseStrategy = strategy;
- }
-
-
- /**
* Starts this test server.
* Use {@link #getServicePort getServicePort}
* to obtain the port number afterwards.
@@ -229,7 +258,14 @@
throw new IllegalStateException
(this.toString() + " already running");
- ServerSocket ssock = new ServerSocket();
+ ServerSocket ssock;
+ if (sslcontext != null) {
+ SSLServerSocketFactory sf = sslcontext.getServerSocketFactory();
+ ssock = sf.createServerSocket();
+ } else {
+ ssock = new ServerSocket();
+ }
+
ssock.setReuseAddress(true); // probably pointless for port '0'
ssock.bind(TEST_SERVER_ADDR);
servicedSocket = ssock;
@@ -257,12 +293,16 @@
if (listenerThread != null) {
listenerThread.interrupt();
- //@@@ listenerThread.join(); ?
- listenerThread = null;
}
}
+ public void awaitTermination(long timeMs) throws InterruptedException {
+ if (listenerThread != null) {
+ listenerThread.join(timeMs);
+ }
+ }
+
@Override
public String toString() {
ServerSocket ssock = servicedSocket; // avoid synchronization