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(-) 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