From 529d17d550fc2928f69c504967e644460e5c9d73 Mon Sep 17 00:00:00 2001 From: hoelzlwimmerf Date: Sun, 11 Oct 2015 03:51:43 +0200 Subject: Added ServerSocketFactory to allow custom ServerSockets; Added recognition of (non-standard) \n\n-headers for more tolerance --- core/src/main/java/fi/iki/elonen/NanoHTTPD.java | 135 ++++++++++++++++++------ 1 file changed, 101 insertions(+), 34 deletions(-) (limited to 'core/src/main/java/fi') diff --git a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java index 0d30d9f..cb98268 100644 --- a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java +++ b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java @@ -464,6 +464,58 @@ public abstract class NanoHTTPD { } } + /** + * Creates a normal ServerSocket for TCP connections + */ + public class DefaultServerSocketFactory implements ServerSocketFactory { + + @Override + public ServerSocket create() { + try { + return new ServerSocket(); + } catch (IOException e) { + e.printStackTrace(); + } + return myServerSocket; + } + + } + + /** + * Creates a new SSLServerSocket + */ + public class SecureServerSocketFactory implements ServerSocketFactory { + + private SSLServerSocketFactory sslServerSocketFactory; + + private String[] sslProtocols; + + public SecureServerSocketFactory(SSLServerSocketFactory sslServerSocketFactory, String[] sslProtocols) { + this.sslServerSocketFactory = sslServerSocketFactory; + this.sslProtocols = sslProtocols; + } + + @Override + public ServerSocket create() { + SSLServerSocket ss = null; + try { + ss = (SSLServerSocket) this.sslServerSocketFactory.createServerSocket(); + if (this.sslProtocols != null) { + ss.setEnabledProtocols(this.sslProtocols); + } else { + ss.setEnabledProtocols(ss.getSupportedProtocols()); + } + ss.setUseClientMode(false); + ss.setWantClientAuth(false); + ss.setNeedClientAuth(false); + } catch (IOException e) { + e.printStackTrace(); + } + return ss; + } + + } + private static final String CONTENT_DISPOSITION_REGEX = "([ |\t]*Content-Disposition[ |\t]*:)(.*)"; private static final Pattern CONTENT_DISPOSITION_PATTERN = Pattern.compile(CONTENT_DISPOSITION_REGEX, Pattern.CASE_INSENSITIVE); @@ -815,10 +867,17 @@ public abstract class NanoHTTPD { */ private int findHeaderEnd(final byte[] buf, int rlen) { int splitbyte = 0; - while (splitbyte + 3 < rlen) { - if (buf[splitbyte] == '\r' && buf[splitbyte + 1] == '\n' && buf[splitbyte + 2] == '\r' && buf[splitbyte + 3] == '\n') { + while (splitbyte + 1 < rlen) { + + // RFC2616 + if (buf[splitbyte] == '\r' && buf[splitbyte + 1] == '\n' && splitbyte + 3 < rlen && buf[splitbyte + 2] == '\r' && buf[splitbyte + 3] == '\n') { return splitbyte + 4; } + + // tolerance + if (buf[splitbyte] == '\n' && buf[splitbyte + 1] == '\n') { + return splitbyte + 2; + } splitbyte++; } return 0; @@ -1518,11 +1577,11 @@ public abstract class NanoHTTPD { */ public interface TempFile { - void delete() throws Exception; + public void delete() throws Exception; - String getName(); + public String getName(); - OutputStream open() throws Exception; + public OutputStream open() throws Exception; } /** @@ -1537,7 +1596,7 @@ public abstract class NanoHTTPD { void clear(); - TempFile createTempFile(String filename_hint) throws Exception; + public TempFile createTempFile(String filename_hint) throws Exception; } /** @@ -1545,7 +1604,16 @@ public abstract class NanoHTTPD { */ public interface TempFileManagerFactory { - TempFileManager create(); + public TempFileManager create(); + } + + /** + * Factory to create ServerSocketFactories. + */ + public interface ServerSocketFactory { + + public ServerSocket create(); + } /** @@ -1704,9 +1772,7 @@ public abstract class NanoHTTPD { private volatile ServerSocket myServerSocket; - private SSLServerSocketFactory sslServerSocketFactory; - - private String[] sslProtocols; + private ServerSocketFactory serverSocketFactory = new DefaultServerSocketFactory(); private Thread myThread; @@ -1861,12 +1927,27 @@ public abstract class NanoHTTPD { return wasStarted() && !this.myServerSocket.isClosed() && this.myThread.isAlive(); } + public ServerSocketFactory getServerSocketFactory() { + return serverSocketFactory; + } + + public void setServerSocketFactory(ServerSocketFactory serverSocketFactory) { + this.serverSocketFactory = serverSocketFactory; + } + + public String getHostname() { + return hostname; + } + + public TempFileManagerFactory getTempFileManagerFactory() { + return tempFileManagerFactory; + } + /** * Call before start() to serve over HTTPS instead of HTTP */ public void makeSecure(SSLServerSocketFactory sslServerSocketFactory, String[] sslProtocols) { - this.sslServerSocketFactory = sslServerSocketFactory; - this.sslProtocols = sslProtocols; + this.serverSocketFactory = new SecureServerSocketFactory(sslServerSocketFactory, sslProtocols); } /** @@ -1989,6 +2070,13 @@ public abstract class NanoHTTPD { start(NanoHTTPD.SOCKET_READ_TIMEOUT); } + /** + * Starts the server (in setDaemon(true) mode). + */ + public void start(final int timeout) throws IOException { + start(timeout, true); + } + /** * Start the server. * @@ -2000,21 +2088,7 @@ public abstract class NanoHTTPD { * if the socket is in use. */ public void start(final int timeout, boolean daemon) throws IOException { - if (this.sslServerSocketFactory != null) { - SSLServerSocket ss = (SSLServerSocket) this.sslServerSocketFactory.createServerSocket(); - if (this.sslProtocols != null) { - ss.setEnabledProtocols(this.sslProtocols); - } else { - ss.setEnabledProtocols(ss.getSupportedProtocols()); - } - ss.setUseClientMode(false); - ss.setWantClientAuth(false); - ss.setNeedClientAuth(false); - ss.setSoTimeout(timeout); - this.myServerSocket = ss; - } else { - this.myServerSocket = new ServerSocket(); - } + this.myServerSocket = this.serverSocketFactory.create(); this.myServerSocket.setReuseAddress(true); ServerRunnable serverRunnable = createServerRunnable(timeout); @@ -2036,13 +2110,6 @@ public abstract class NanoHTTPD { } } - /** - * Starts the server (in setDaemon(true) mode). - */ - public void start(final int timeout) throws IOException { - start(timeout, true); - } - /** * Stop the server. */ -- cgit v1.2.3 From e316510734c3e986f89155e0a3916ae6c5167395 Mon Sep 17 00:00:00 2001 From: hoelzlwimmerf Date: Sun, 18 Oct 2015 13:12:50 +0200 Subject: Added ServerSocketFactory JUnit test --- core/src/main/java/fi/iki/elonen/NanoHTTPD.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'core/src/main/java/fi') diff --git a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java index 52598e5..676f8f7 100644 --- a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java +++ b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java @@ -2088,7 +2088,7 @@ public abstract class NanoHTTPD { * if the socket is in use. */ public void start(final int timeout, boolean daemon) throws IOException { - this.myServerSocket = this.serverSocketFactory.create(); + this.myServerSocket = this.getServerSocketFactory().create(); this.myServerSocket.setReuseAddress(true); ServerRunnable serverRunnable = createServerRunnable(timeout); -- cgit v1.2.3 From 1ea2389061205bf7872a02794f652616ab204a41 Mon Sep 17 00:00:00 2001 From: hoelzlwimmerf Date: Wed, 21 Oct 2015 16:49:17 +0200 Subject: Added SSLServerSocketFactoryTest; Fixed non-static classes and wrong return. --- core/src/main/java/fi/iki/elonen/NanoHTTPD.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'core/src/main/java/fi') diff --git a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java index bf58c7b..2f3c665 100644 --- a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java +++ b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java @@ -478,7 +478,7 @@ public abstract class NanoHTTPD { /** * Creates a normal ServerSocket for TCP connections */ - public class DefaultServerSocketFactory implements ServerSocketFactory { + public static class DefaultServerSocketFactory implements ServerSocketFactory { @Override public ServerSocket create() { @@ -487,7 +487,7 @@ public abstract class NanoHTTPD { } catch (IOException e) { e.printStackTrace(); } - return myServerSocket; + return null; } } @@ -495,7 +495,7 @@ public abstract class NanoHTTPD { /** * Creates a new SSLServerSocket */ - public class SecureServerSocketFactory implements ServerSocketFactory { + public static class SecureServerSocketFactory implements ServerSocketFactory { private SSLServerSocketFactory sslServerSocketFactory; -- cgit v1.2.3 From 4c3db1479b17ae004301a6214e9adb88040fefc4 Mon Sep 17 00:00:00 2001 From: Hoeze Date: Wed, 21 Oct 2015 18:56:48 +0200 Subject: Added more tests; all coverage checks are met now. --- core/src/main/java/fi/iki/elonen/NanoHTTPD.java | 33 +++++++++---------------- 1 file changed, 12 insertions(+), 21 deletions(-) (limited to 'core/src/main/java/fi') diff --git a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java index 2f3c665..530ba94 100644 --- a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java +++ b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java @@ -481,13 +481,8 @@ public abstract class NanoHTTPD { public static class DefaultServerSocketFactory implements ServerSocketFactory { @Override - public ServerSocket create() { - try { - return new ServerSocket(); - } catch (IOException e) { - e.printStackTrace(); - } - return null; + public ServerSocket create() throws IOException { + return new ServerSocket(); } } @@ -507,21 +502,17 @@ public abstract class NanoHTTPD { } @Override - public ServerSocket create() { + public ServerSocket create() throws IOException { SSLServerSocket ss = null; - try { - ss = (SSLServerSocket) this.sslServerSocketFactory.createServerSocket(); - if (this.sslProtocols != null) { - ss.setEnabledProtocols(this.sslProtocols); - } else { - ss.setEnabledProtocols(ss.getSupportedProtocols()); - } - ss.setUseClientMode(false); - ss.setWantClientAuth(false); - ss.setNeedClientAuth(false); - } catch (IOException e) { - e.printStackTrace(); + ss = (SSLServerSocket) this.sslServerSocketFactory.createServerSocket(); + if (this.sslProtocols != null) { + ss.setEnabledProtocols(this.sslProtocols); + } else { + ss.setEnabledProtocols(ss.getSupportedProtocols()); } + ss.setUseClientMode(false); + ss.setWantClientAuth(false); + ss.setNeedClientAuth(false); return ss; } @@ -1621,7 +1612,7 @@ public abstract class NanoHTTPD { */ public interface ServerSocketFactory { - public ServerSocket create(); + public ServerSocket create() throws IOException; } -- cgit v1.2.3