From dbf391f99a8def88dbc94f362546b64ac90d0234 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 12 Mar 2018 14:19:35 +0100 Subject: NanoHTTPD: Fix infinite loop --- src/main/java/fi/iki/elonen/NanoHTTPD.java | 43 +++++++++++++----------------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/src/main/java/fi/iki/elonen/NanoHTTPD.java b/src/main/java/fi/iki/elonen/NanoHTTPD.java index bb882ee..19508c7 100644 --- a/src/main/java/fi/iki/elonen/NanoHTTPD.java +++ b/src/main/java/fi/iki/elonen/NanoHTTPD.java @@ -169,7 +169,7 @@ public abstract class NanoHTTPD implements Runnable setAsyncRunner( new DefaultAsyncRunner() ); } - protected static final void safeClose( Closeable closeable ) + public static final void safeClose( Closeable closeable ) { if ( closeable != null ) { try { @@ -218,7 +218,7 @@ public abstract class NanoHTTPD implements Runnable // When the socket is closed by the client, we throw our own SocketException // to break the "keep alive" loop above. if ( ! ( e instanceof SocketTimeoutException ) - && ! ( e instanceof SocketException && "NanoHttpd Shutdown".equals( e.getMessage() ) ) ) { + && ! ( e instanceof SocketException ) ) { e.printStackTrace(); } } finally { @@ -567,7 +567,7 @@ public abstract class NanoHTTPD implements Runnable /** * Sends given response to the socket. */ - protected void send( OutputStream outputStream ) + protected void send( OutputStream outputStream ) throws IOException { String mime = mimeType; @@ -602,25 +602,21 @@ public abstract class NanoHTTPD implements Runnable sendConnectionHeaderIfNotAlreadyPresent( sb, header ); - try { - if ( requestMethod != Method.HEAD && chunkedTransfer ) { - sendAsChunked( outputStream, sb ); - } else { - int pending = data != null ? data.available() : 0; - pending = sendContentLengthHeaderIfNotAlreadyPresent( sb, header, pending ); - sb.append( "\r\n" ); - outputStream.write( sb.toString().getBytes( StandardCharsets.UTF_8 ) ); - sb.setLength( 0 ); - sendAsFixedLength( outputStream, pending ); - } + if ( requestMethod != Method.HEAD && chunkedTransfer ) { + sendAsChunked( outputStream, sb ); + } else { + int pending = data != null ? data.available() : 0; + pending = sendContentLengthHeaderIfNotAlreadyPresent( sb, header, pending ); + sb.append( "\r\n" ); + outputStream.write( sb.toString().getBytes( StandardCharsets.UTF_8 ) ); + sb.setLength( 0 ); + sendAsFixedLength( outputStream, pending ); + } - if ( sb.length() != 0 ) { - outputStream.write( sb.toString().getBytes( StandardCharsets.UTF_8 ) ); - } - safeClose( data ); - } catch ( IOException ioe ) { - // Couldn't write? No can do. + if ( sb.length() != 0 ) { + outputStream.write( sb.toString().getBytes( StandardCharsets.UTF_8 ) ); } + safeClose( data ); } protected int sendContentLengthHeaderIfNotAlreadyPresent( StringBuilder sb, @@ -893,14 +889,10 @@ public abstract class NanoHTTPD implements Runnable try { read = inputStream.read( buf, 0, BUFSIZE ); } catch ( Exception e ) { - safeClose( inputStream ); - safeClose( outputStream ); throw e; } if ( read == -1 ) { // socket was been closed - safeClose( inputStream ); - safeClose( outputStream ); throw new SocketException( "NanoHttpd Shutdown" ); } while ( read > 0 ) { @@ -912,6 +904,9 @@ public abstract class NanoHTTPD implements Runnable if ( maxRequestSize != 0 && rlen > maxRequestSize ) throw new SocketException( "Request too large" ); } + if ( splitbyte == 0 ) { + throw new SocketException( "Connection was closed" ); + } } if ( splitbyte < rlen ) { -- cgit v1.2.3-55-g7522