Posts Tagged ‘ssl’
Testing SSL (HTTPS) clients with Junit and Jetty
Wednesday, July 14th, 2010
Posted in: https, junit, ssl, unit test J2EE, java, maven 2, open source.
I recently ran into a situation where a web service client had issues when invoking a webservice via HTTPS. To reproduce, I needed a lightweight, JUnit-based test to reproduce the problem and write a regression test. Here is how I got it to work:
First, I used the basic HTTP test setup. Now however, I needed Jetty to provide a HTTPS connector. For this to work, Jetty – just like any other webserver, such as apache – needs a server certificate and a private key in a keystore. To create the keystore, I simply followed the excellent Jetty SSL guide. Namingly, I did this (using Ubuntu, see the above link for alternatives):
openssl genrsa -des3 -out jetty.key openssl req -new -x509 -key jetty.key -out jetty.crt openssl pkcs12 -inkey jetty.key -in jetty.crt -export -out jetty.pkcs12 $JAVA_HOME/bin/keytool -importkeystore -srckeystore jetty.pkcs12 -srcstoretype PKCS12 -destkeystore keystore
Once I had the keystore set up, I placed it in the src/main/resources folder (the root of the classpath, in case you’re not a maven user) and extended the HttpTestServer like so:
import java.net.URL;
import org.junit.Ignore;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.security.SslSocketConnector;
/**
* A test server for testing SSL requests.
*
* @author Olaf Otto
*/
@Ignore
public class SslTestServer extends HttpTestServer {
private static final int HTTPS_PORT = 50443;
public SslTestServer() {
}
public SslTestServer(String mockData) {
super(mockData);
}
@Override
protected void configureServer() {
super.configureServer();
Connector secureConnector = createSecureConnector();
getServer().addConnector(secureConnector);
}
private Connector createSecureConnector() {
SslSocketConnector connector = new SslSocketConnector();
connector.setPort(HTTPS_PORT);
URL keystoreUrl = getClass().getClassLoader().getResource("keystore");
connector.setKeystore(keystoreUrl.getFile());
connector.setKeyPassword("test");
return connector;
}
public static void main(String[] args) {
SslTestServer server = new SslTestServer();
try {
server.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
(I added the @Ignore annotation as I placed the class in the test sources folder, though it’s not a test…)
You might use it in your JUnit-based test like so:
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* @author Olaf Otto
*/
public class MySslTest {
private SslTestServer _server;
@Before
public void startServer() throws Exception {
_server = new SslTestServer();
_server.start();
}
@After
public void stopServer() throws Exception {
_server.stop();
}
@Test
public void mySsltest() {
_server.setMockResponseData("<xml>My client expects this response</xml>");
// Perform tests on port 50443...
}
}
Here is the whole package as a maven 2 project (including the keystore with a self-signed certificate). Download, unzip, and give it a try (mvn test).
