diff options
author | ritchie <ritchie@gmx.at> | 2015-09-13 09:18:09 +0200 |
---|---|---|
committer | ritchie <ritchie@gmx.at> | 2015-09-13 09:18:09 +0200 |
commit | 3ea79cfc3ef8447430e6fcc9570c1551831ff9c4 (patch) | |
tree | f7f71ec03206af97984ce4ab13afd8fc003c0b0e | |
parent | b7c544cefdb659bc78bfc57fd505fd45b5f1d1ff (diff) | |
download | nanohttpd-3ea79cfc3ef8447430e6fcc9570c1551831ff9c4.tar.gz |
unit tests for ssl support #197
-rw-r--r-- | README.md | 12 | ||||
-rw-r--r-- | core/pom.xml | 2 | ||||
-rw-r--r-- | core/src/main/java/fi/iki/elonen/NanoHTTPD.java | 36 | ||||
-rw-r--r-- | core/src/test/java/fi/iki/elonen/HttpHeadRequestTest.java | 2 | ||||
-rw-r--r-- | core/src/test/java/fi/iki/elonen/HttpSSLServerTest.java | 87 | ||||
-rw-r--r-- | core/src/test/java/fi/iki/elonen/HttpServerTest.java | 8 | ||||
-rw-r--r-- | core/src/test/java/fi/iki/elonen/HttpSessionHeadersTest.java | 5 | ||||
-rw-r--r-- | core/src/test/resources/keystore.jks | bin | 0 -> 2276 bytes |
8 files changed, 128 insertions, 24 deletions
@@ -211,7 +211,19 @@ The latest Github master version can be fetched through sonatype.org: </repository> </repositories> +### generating an self signed ssl certificate +Just a hint how to generate a certificate for localhost. + + keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 2048 -ext SAN=DNS:localhost,IP:127.0.0.1 -validity 9999 + +This will generate a keystore file named 'keystore.jks' with a self signed certificate for a host named localhost with the ip adress 127.0.0.1 . Now +you can use: + + server.makeSecure(NanoHTTPD.makeSSLSocketFactory("/keystore.jks", "password".toCharArray())); + +Before you start the server to make Nanohttpd serve https connections, when you make sure 'keystore.jks' is in your classpath . + ----- *Thank you to everyone who has reported bugs and suggested fixes.* diff --git a/core/pom.xml b/core/pom.xml index 2f8f36e..b742250 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -23,6 +23,6 @@ </dependency> </dependencies> <properties> - <minimal.coverage>0.77</minimal.coverage> + <minimal.coverage>0.81</minimal.coverage> </properties> </project> diff --git a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java index d75c762..14e5299 100644 --- a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java +++ b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java @@ -33,7 +33,25 @@ package fi.iki.elonen; * #L% */ -import java.io.*; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.PushbackInputStream; +import java.io.RandomAccessFile; +import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; @@ -1576,17 +1594,11 @@ public abstract class NanoHTTPD { * by the caller. */ public static SSLServerSocketFactory makeSSLSocketFactory(KeyStore loadedKeyStore, KeyManagerFactory loadedKeyFactory) throws IOException { - SSLServerSocketFactory res = null; try { - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - trustManagerFactory.init(loadedKeyStore); - SSLContext ctx = SSLContext.getInstance("TLS"); - ctx.init(loadedKeyFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); - res = ctx.getServerSocketFactory(); + return makeSSLSocketFactory(loadedKeyStore, loadedKeyFactory.getKeyManagers()); } catch (Exception e) { throw new IOException(e.getMessage()); } - return res; } /** @@ -1594,22 +1606,16 @@ public abstract class NanoHTTPD { * certificate and passphrase */ public static SSLServerSocketFactory makeSSLSocketFactory(String keyAndTrustStoreClasspathPath, char[] passphrase) throws IOException { - SSLServerSocketFactory res = null; try { KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); InputStream keystoreStream = NanoHTTPD.class.getResourceAsStream(keyAndTrustStoreClasspathPath); keystore.load(keystoreStream, passphrase); - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - trustManagerFactory.init(keystore); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keystore, passphrase); - SSLContext ctx = SSLContext.getInstance("TLS"); - ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); - res = ctx.getServerSocketFactory(); + return makeSSLSocketFactory(keystore, keyManagerFactory); } catch (Exception e) { throw new IOException(e.getMessage()); } - return res; } private static final void safeClose(Object closeable) { diff --git a/core/src/test/java/fi/iki/elonen/HttpHeadRequestTest.java b/core/src/test/java/fi/iki/elonen/HttpHeadRequestTest.java index 4eb3147..9b5983e 100644 --- a/core/src/test/java/fi/iki/elonen/HttpHeadRequestTest.java +++ b/core/src/test/java/fi/iki/elonen/HttpHeadRequestTest.java @@ -45,7 +45,7 @@ import org.junit.Test; public class HttpHeadRequestTest extends HttpServerTest { @Override - public void setUp() { + public void setUp() throws Exception { super.setUp(); String responseBody = "Success!"; this.testServer.response = NanoHTTPD.newFixedLengthResponse(responseBody); diff --git a/core/src/test/java/fi/iki/elonen/HttpSSLServerTest.java b/core/src/test/java/fi/iki/elonen/HttpSSLServerTest.java new file mode 100644 index 0000000..4923cca --- /dev/null +++ b/core/src/test/java/fi/iki/elonen/HttpSSLServerTest.java @@ -0,0 +1,87 @@ +package fi.iki.elonen; + +/* + * #%L + * NanoHttpd-Core + * %% + * Copyright (C) 2012 - 2015 nanohttpd + * %% + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the nanohttpd nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * #L% + */ + +import java.io.File; +import java.io.IOException; + +import javax.net.ssl.SSLServerSocketFactory; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpTrace; +import org.apache.http.impl.client.DefaultHttpClient; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class HttpSSLServerTest extends HttpServerTest { + + @Test + public void testSSLConnection() throws ClientProtocolException, IOException { + DefaultHttpClient httpclient = new DefaultHttpClient(); + HttpTrace httphead = new HttpTrace("https://localhost:9043/index.html"); + HttpResponse response = httpclient.execute(httphead); + HttpEntity entity = response.getEntity(); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + } + + @Before + public void setUp() throws Exception { + System.setProperty("javax.net.ssl.trustStore", new File("src/test/resources/keystore.jks").getAbsolutePath()); + this.testServer = new TestServer(9043); + this.testServer.makeSecure(NanoHTTPD.makeSSLSocketFactory("/keystore.jks", "password".toCharArray())); + this.tempFileManager = new TestTempFileManager(); + this.testServer.start(); + try { + long start = System.currentTimeMillis(); + Thread.sleep(100L); + while (!this.testServer.wasStarted()) { + Thread.sleep(100L); + if (System.currentTimeMillis() - start > 2000) { + Assert.fail("could not start server"); + } + } + } catch (InterruptedException e) { + } + } + + @After + public void tearDown() { + this.testServer.stop(); + } +} diff --git a/core/src/test/java/fi/iki/elonen/HttpServerTest.java b/core/src/test/java/fi/iki/elonen/HttpServerTest.java index a8215f7..742942d 100644 --- a/core/src/test/java/fi/iki/elonen/HttpServerTest.java +++ b/core/src/test/java/fi/iki/elonen/HttpServerTest.java @@ -83,6 +83,10 @@ public class HttpServerTest { super(8192); } + public TestServer(int port) { + super(port); + } + public HTTPSession createSession(TempFileManager tempFileManager, InputStream inputStream, OutputStream outputStream) { return new HTTPSession(tempFileManager, inputStream, outputStream); } @@ -131,7 +135,7 @@ public class HttpServerTest { protected TestServer testServer; - private TestTempFileManager tempFileManager; + protected TestTempFileManager tempFileManager; protected void assertLinesOfText(String[] expected, List<String> lines) { // assertEquals(expected.length, lines.size()); @@ -177,7 +181,7 @@ public class HttpServerTest { } @Before - public void setUp() { + public void setUp() throws Exception { this.testServer = new TestServer(); this.tempFileManager = new TestTempFileManager(); } diff --git a/core/src/test/java/fi/iki/elonen/HttpSessionHeadersTest.java b/core/src/test/java/fi/iki/elonen/HttpSessionHeadersTest.java index 65947b9..1494e28 100644 --- a/core/src/test/java/fi/iki/elonen/HttpSessionHeadersTest.java +++ b/core/src/test/java/fi/iki/elonen/HttpSessionHeadersTest.java @@ -48,11 +48,6 @@ public class HttpSessionHeadersTest extends HttpServerTest { private static final TestTempFileManager TEST_TEMP_FILE_MANAGER = new TestTempFileManager(); - @Override - public void setUp() { - super.setUp(); - } - @Test @Ignore public void testHeadersRemoteIp() throws Exception { diff --git a/core/src/test/resources/keystore.jks b/core/src/test/resources/keystore.jks Binary files differnew file mode 100644 index 0000000..354b5d3 --- /dev/null +++ b/core/src/test/resources/keystore.jks |