Author: markt Date: Thu Feb 23 11:30:55 2012 New Revision: 1292742 URL: http://svn.apache.org/viewvc?rev=1292742&view=rev Log: Handle close and pong control frames inside fragmented message.
Modified: tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java tomcat/trunk/java/org/apache/catalina/websocket/WsInputStream.java tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.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=1292742&r1=1292741&r2=1292742&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java (original) +++ tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java Thu Feb 23 11:30:55 2012 @@ -80,7 +80,7 @@ public abstract class StreamInbound impl } if (opCode == Constants.OPCODE_CLOSE){ - doClose(frame); + getOutbound().close(frame); return SocketState.CLOSED; } else if (opCode == Constants.OPCODE_PING) { doPing(frame); @@ -109,21 +109,6 @@ public abstract class StreamInbound impl } } - private void doClose(WsFrame frame) throws IOException { - if (frame.getPayLoadLength() > 0) { - // Must be status (2 bytes) plus optional message - if (frame.getPayLoadLength() == 1) { - throw new IOException(); - } - int status = (frame.getPayLoad().get() & 0xFF) << 8; - status += frame.getPayLoad().get() & 0xFF; - getOutbound().close(status, frame.getPayLoad()); - } else { - // No status - getOutbound().close(0, null); - } - } - private void doPing(WsFrame frame) throws IOException { getOutbound().pong(frame.getPayLoad()); } 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=1292742&r1=1292741&r2=1292742&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/websocket/WsInputStream.java (original) +++ tomcat/trunk/java/org/apache/catalina/websocket/WsInputStream.java Thu Feb 23 11:30:55 2012 @@ -68,7 +68,11 @@ public class WsInputStream extends java. while (frame.isControl()) { if (getFrame().getOpCode() == Constants.OPCODE_PING) { outbound.pong(frame.getPayLoad()); - } else { + } else if (getFrame().getOpCode() == Constants.OPCODE_PONG) { + // NO-OP. Swallow it. + } else if (getFrame().getOpCode() == Constants.OPCODE_CLOSE) { + outbound.close(frame); + } else{ // TODO throw new IOException("TODO"); } Modified: tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java?rev=1292742&r1=1292741&r2=1292742&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java (original) +++ tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java Thu Feb 23 11:30:55 2012 @@ -115,6 +115,46 @@ public class WsOutbound { } + + public void close(WsFrame frame) throws IOException { + if (frame.getPayLoadLength() > 0) { + // Must be status (2 bytes) plus optional message + if (frame.getPayLoadLength() == 1) { + throw new IOException(); + } + int status = (frame.getPayLoad().get() & 0xFF) << 8; + status += frame.getPayLoad().get() & 0xFF; + + if (validateCloseStatus(status)) { + // Echo the status back to the client + close(status, frame.getPayLoad()); + } else { + // Invalid close code + close(1002, null); + } + } else { + // No status + close(0, null); + } + } + + private boolean validateCloseStatus(int status) { + + if (status == 1000 || status == 1001 || status == 1002 || + status == 1003 || status == 1007 || status == 1008 || + status == 1009 || status == 1010 || status == 1011 || + (status > 2999 && status < 5000)) { + // Other 1xxx reserved / not permitted + // 2xxx reserved + // 3xxx framework defined + // 4xxx application defined + return true; + } + // <1000 unused + // >4999 undefined + return false; + } + public void close(int status, ByteBuffer data) throws IOException { // TODO Think about threading requirements for writing. This is not // currently thread safe and writing almost certainly needs to be. --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org