Author: markt Date: Wed Feb 22 19:20:46 2012 New Revision: 1292456 URL: http://svn.apache.org/viewvc?rev=1292456&view=rev Log: Check for unexpected EOS. Close the connection if one is seen.
Modified: tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java tomcat/trunk/java/org/apache/catalina/websocket/WsInputStream.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java Modified: tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java?rev=1292456&r1=1292455&r2=1292456&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java (original) +++ tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java Wed Feb 22 19:20:46 2012 @@ -51,49 +51,58 @@ public abstract class StreamInbound impl @Override public SocketState onData() throws IOException { // Must be start the start of a frame or series of frames - WsInputStream wsIs = new WsInputStream(processor); - WsFrameHeader header = wsIs.getFrameHeader(); + try { + WsInputStream wsIs = new WsInputStream(processor); - // TODO User defined extensions may define values for rsv - if (header.getRsv() > 0) { - getOutbound().close(1002, null); - return SocketState.CLOSED; - } + WsFrameHeader header = wsIs.getFrameHeader(); + + // TODO User defined extensions may define values for rsv + if (header.getRsv() > 0) { + getOutbound().close(1002, null); + return SocketState.CLOSED; + } - byte opCode = header.getOpCode(); + byte opCode = header.getOpCode(); - if (opCode == Constants.OPCODE_BINARY) { - onBinaryData(wsIs); - return SocketState.UPGRADED; - } else if (opCode == Constants.OPCODE_TEXT) { - InputStreamReader r = - new InputStreamReader(wsIs, B2CConverter.UTF_8); - onTextData(r); - return SocketState.UPGRADED; - } + if (opCode == Constants.OPCODE_BINARY) { + onBinaryData(wsIs); + return SocketState.UPGRADED; + } else if (opCode == Constants.OPCODE_TEXT) { + InputStreamReader r = + new InputStreamReader(wsIs, B2CConverter.UTF_8); + onTextData(r); + return SocketState.UPGRADED; + } - // Must be a control frame and control frames: - // - have a limited payload length - // - must not be fragmented - if (wsIs.getPayloadLength() > 125 || !wsIs.getFrameHeader().getFin()) { + // Must be a control frame and control frames: + // - have a limited payload length + // - must not be fragmented + if (wsIs.getPayloadLength() > 125 || !wsIs.getFrameHeader().getFin()) { + getOutbound().close(1002, null); + return SocketState.CLOSED; + } + + if (opCode == Constants.OPCODE_CLOSE){ + doClose(wsIs); + return SocketState.CLOSED; + } else if (opCode == Constants.OPCODE_PING) { + doPing(wsIs); + return SocketState.UPGRADED; + } else if (opCode == Constants.OPCODE_PONG) { + doPong(wsIs); + return SocketState.UPGRADED; + } + + // Unknown OpCode getOutbound().close(1002, null); return SocketState.CLOSED; - } - - if (opCode == Constants.OPCODE_CLOSE){ - doClose(wsIs); + } catch (IOException ioe) { + // Given something must have gone to reach this point, this might + // not work but try it anyway. + getOutbound().close(1002, null); return SocketState.CLOSED; - } else if (opCode == Constants.OPCODE_PING) { - doPing(wsIs); - return SocketState.UPGRADED; - } else if (opCode == Constants.OPCODE_PONG) { - doPong(wsIs); - return SocketState.UPGRADED; } - - getOutbound().close(1002, null); - return SocketState.CLOSED; } private void doClose(WsInputStream is) throws IOException { Modified: tomcat/trunk/java/org/apache/catalina/websocket/WsInputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/websocket/WsInputStream.java?rev=1292456&r1=1292455&r2=1292456&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/websocket/WsInputStream.java (original) +++ tomcat/trunk/java/org/apache/catalina/websocket/WsInputStream.java Wed Feb 22 19:20:46 2012 @@ -51,11 +51,10 @@ public class WsInputStream extends java. // TODO: Handle control frames between fragments - int i = processor.read(); - this.wsFrameHeader = new WsFrameHeader(i); + this.wsFrameHeader = new WsFrameHeader(processorRead()); // Client data must be masked - i = processor.read(); + int i = processorRead(); if ((i & 0x80) == 0) { // TODO: StringManager / i18n throw new IOException("Client frame not masked"); @@ -64,11 +63,11 @@ public class WsInputStream extends java. payloadLength = i & 0x7F; if (payloadLength == 126) { byte[] extended = new byte[2]; - processor.read(extended); + processorRead(extended); payloadLength = Conversions.byteArrayToLong(extended); } else if (payloadLength == 127) { byte[] extended = new byte[8]; - processor.read(extended); + processorRead(extended); payloadLength = Conversions.byteArrayToLong(extended); } remaining = payloadLength; @@ -89,6 +88,30 @@ public class WsInputStream extends java. } + // ----------------------------------- Guaranteed read methods for processor + + private int processorRead() throws IOException { + int result = processor.read(); + if (result == -1) { + // TODO i18n + throw new IOException("End of stream before end of frame"); + } + return result; + } + + + private void processorRead(byte[] bytes) throws IOException { + int read = 0; + int last = 0; + while (read < bytes.length) { + last = processor.read(bytes, read, bytes.length - read); + if (last == -1) { + // TODO i18n + throw new IOException("End of stream before end of frame"); + } + } + } + // ----------------------------------------------------- InputStream methods @Override Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java?rev=1292456&r1=1292455&r2=1292456&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java Wed Feb 22 19:20:46 2012 @@ -67,7 +67,7 @@ public class UpgradeAprProcessor extends @Override - public int read(byte[] bytes) throws IOException { - return Socket.recv(socket, bytes, 0, bytes.length); + public int read(byte[] bytes, int off, int len) throws IOException { + return Socket.recv(socket, bytes, off, len); } } Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java?rev=1292456&r1=1292455&r2=1292456&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java Wed Feb 22 19:20:46 2012 @@ -68,7 +68,7 @@ public class UpgradeBioProcessor extends @Override - public int read(byte[] bytes) throws IOException { - return inputStream.read(bytes); + public int read(byte[] bytes, int off, int len) throws IOException { + return inputStream.read(bytes, off, len); } } Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java?rev=1292456&r1=1292455&r2=1292456&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java Wed Feb 22 19:20:46 2012 @@ -91,8 +91,8 @@ public class UpgradeNioProcessor extends } @Override - public int read(byte[] bytes) throws IOException { - return readSocket(true, bytes, 0, bytes.length); + public int read(byte[] bytes, int off, int len) throws IOException { + return readSocket(true, bytes, off, len); } Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java?rev=1292456&r1=1292455&r2=1292456&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java Wed Feb 22 19:20:46 2012 @@ -46,7 +46,7 @@ public abstract class UpgradeProcessor<S // Input methods public abstract int read() throws IOException; - public abstract int read(byte[] bytes) throws IOException; + public abstract int read(byte[] bytes, int off, int len) throws IOException; @Override public final UpgradeInbound getUpgradeInbound() { --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org