diff options
Diffstat (limited to 'core/src')
-rw-r--r-- | core/src/main/java/fi/iki/elonen/NanoHTTPD.java | 135 | ||||
-rw-r--r-- | core/src/test/java/fi/iki/elonen/ServerSocketFactoryTest.java | 75 |
2 files changed, 176 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 847aee2..bf58c7b 100644 --- a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java +++ b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java @@ -475,6 +475,58 @@ public abstract class NanoHTTPD { private static final Pattern BOUNDARY_PATTERN = Pattern.compile(BOUNDARY_REGEX, Pattern.CASE_INSENSITIVE); + /** + * 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); @@ -826,10 +878,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; @@ -1527,11 +1586,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; } /** @@ -1546,7 +1605,7 @@ public abstract class NanoHTTPD { void clear(); - TempFile createTempFile(String filename_hint) throws Exception; + public TempFile createTempFile(String filename_hint) throws Exception; } /** @@ -1554,7 +1613,16 @@ public abstract class NanoHTTPD { */ public interface TempFileManagerFactory { - TempFileManager create(); + public TempFileManager create(); + } + + /** + * Factory to create ServerSocketFactories. + */ + public interface ServerSocketFactory { + + public ServerSocket create(); + } /** @@ -1713,9 +1781,7 @@ public abstract class NanoHTTPD { private volatile ServerSocket myServerSocket; - private SSLServerSocketFactory sslServerSocketFactory; - - private String[] sslProtocols; + private ServerSocketFactory serverSocketFactory = new DefaultServerSocketFactory(); private Thread myThread; @@ -1870,12 +1936,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); } /** @@ -1999,6 +2080,13 @@ public abstract class NanoHTTPD { } /** + * Starts the server (in setDaemon(true) mode). + */ + public void start(final int timeout) throws IOException { + start(timeout, true); + } + + /** * Start the server. * * @param timeout @@ -2009,21 +2097,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.getServerSocketFactory().create(); this.myServerSocket.setReuseAddress(true); ServerRunnable serverRunnable = createServerRunnable(timeout); @@ -2046,13 +2120,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. */ public void stop() { diff --git a/core/src/test/java/fi/iki/elonen/ServerSocketFactoryTest.java b/core/src/test/java/fi/iki/elonen/ServerSocketFactoryTest.java new file mode 100644 index 0000000..17b6913 --- /dev/null +++ b/core/src/test/java/fi/iki/elonen/ServerSocketFactoryTest.java @@ -0,0 +1,75 @@ +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.IOException; +import java.net.ServerSocket; + +import org.junit.Assert; +import org.junit.Test; + +public class ServerSocketFactoryTest extends NanoHTTPD { + + public static final int PORT = 8192; + + public ServerSocketFactoryTest() { + super(PORT); + + this.setServerSocketFactory(new TestFactory()); + } + + @Test + public void isCustomServerSocketFactory() { + Assert.assertTrue(this.getServerSocketFactory() instanceof TestFactory); + } + + @Test + public void testCreateServerSocket() { + ServerSocket ss = this.getServerSocketFactory().create(); + Assert.assertTrue(ss != null); + } + + private class TestFactory implements ServerSocketFactory { + + @Override + public ServerSocket create() { + try { + return new ServerSocket(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + } +} |