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

Reply via email to