aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorritchie <ritchie@gmx.at>2015-09-13 09:18:09 +0200
committerritchie <ritchie@gmx.at>2015-09-13 09:18:09 +0200
commit3ea79cfc3ef8447430e6fcc9570c1551831ff9c4 (patch)
treef7f71ec03206af97984ce4ab13afd8fc003c0b0e
parentb7c544cefdb659bc78bfc57fd505fd45b5f1d1ff (diff)
downloadnanohttpd-3ea79cfc3ef8447430e6fcc9570c1551831ff9c4.tar.gz
unit tests for ssl support #197
-rw-r--r--README.md12
-rw-r--r--core/pom.xml2
-rw-r--r--core/src/main/java/fi/iki/elonen/NanoHTTPD.java36
-rw-r--r--core/src/test/java/fi/iki/elonen/HttpHeadRequestTest.java2
-rw-r--r--core/src/test/java/fi/iki/elonen/HttpSSLServerTest.java87
-rw-r--r--core/src/test/java/fi/iki/elonen/HttpServerTest.java8
-rw-r--r--core/src/test/java/fi/iki/elonen/HttpSessionHeadersTest.java5
-rw-r--r--core/src/test/resources/keystore.jksbin0 -> 2276 bytes
8 files changed, 128 insertions, 24 deletions
diff --git a/README.md b/README.md
index e1f5484..e7835a0 100644
--- a/README.md
+++ b/README.md
@@ -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
new file mode 100644
index 0000000..354b5d3
--- /dev/null
+++ b/core/src/test/resources/keystore.jks
Binary files differ