You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2012/12/24 22:46:31 UTC

svn commit: r1425685 - in /tomcat/trunk/java/org/apache/tomcat/websocket: LocalStrings.properties WsFrame.java

Author: markt
Date: Mon Dec 24 21:46:31 2012
New Revision: 1425685

URL: http://svn.apache.org/viewvc?rev=1425685&view=rev
Log:
Fix the Autobahn UTF-8 test failures except those that test for fail-fast on invalid UTF-8. Failing fast will require some further refactoring.

Modified:
    tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties
    tomcat/trunk/java/org/apache/tomcat/websocket/WsFrame.java

Modified: tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties?rev=1425685&r1=1425684&r2=1425685&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties Mon Dec 24 21:46:31 2012
@@ -24,6 +24,7 @@ wsFrame.controlFragmented=A fragmented c
 wsFrame.controlPayloadTooBig=A control frame was sent with a payload of length [{0}] which is larger than the maximum length permitted of 125 bytes
 wsFrame.controlNoFin=A control frame was sent that did not have the fin bit set. Control frames are not permitted to use continuation frames.
 wsFrame.invalidOpCode= A WebSocket frame was sent with an unrecognised opCode of [{0}]
+wsFrame.invalidUtf8=A WebSocket text frame was received that could not be decoded to UTF-8 because it contained invalid byte sequences
 wsFrame.noContinuation=A new message was started when a continuation frame was expected
 wsFrame.notMasked=The client frame was not masked but all client frames must be masked
 wsFrame.wrongRsv=The client frame set the reserved bits to [{0}] which was not supported by this endpoint
\ No newline at end of file

Modified: tomcat/trunk/java/org/apache/tomcat/websocket/WsFrame.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/WsFrame.java?rev=1425685&r1=1425684&r2=1425685&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/WsFrame.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/WsFrame.java Mon Dec 24 21:46:31 2012
@@ -18,8 +18,9 @@ package org.apache.tomcat.websocket;
 
 import java.io.EOFException;
 import java.io.IOException;
-import java.io.UnsupportedEncodingException;
 import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CoderResult;
 
 import javax.servlet.ServletInputStream;
 import javax.websocket.CloseReason;
@@ -49,7 +50,9 @@ public class WsFrame {
     private final ByteBuffer controlBuffer = ByteBuffer.allocate(125);
 
     // Attributes of the current message
-    private final ByteBuffer messageBuffer;
+    private final ByteBuffer messageBufferBinary;
+    private final CharBuffer messageBufferText;
+    private final Utf8Decoder utf8Decoder = new Utf8Decoder();
     private boolean continuationExpected = false;
     private boolean textMessage = false;
 
@@ -77,7 +80,8 @@ public class WsFrame {
                 ServerContainerImpl.getServerContainer().getReadBufferSize();
 
         inputBuffer = new byte[readBufferSize];
-        messageBuffer = ByteBuffer.allocate(readBufferSize);
+        messageBufferBinary = ByteBuffer.allocate(readBufferSize);
+        messageBufferText = CharBuffer.allocate(readBufferSize);
     }
 
 
@@ -253,27 +257,28 @@ public class WsFrame {
             newFrame();
             return true;
         }
-        appendPayloadToMessage(messageBuffer);
+        appendPayloadToMessage(messageBufferBinary);
+
         if (payloadWritten == payloadLength) {
             if (continuationExpected) {
                 if (usePartial()) {
-                    messageBuffer.flip();
+                    messageBufferBinary.flip();
                     sendMessage(false);
-                    messageBuffer.clear();
+                    messageBufferBinary.clear();
                 }
                 newFrame();
                 return true;
             } else {
-                messageBuffer.flip();
+                messageBufferBinary.flip();
                 sendMessage(true);
                 newMessage();
                 return true;
             }
         } else {
             if (usePartial()) {
-                messageBuffer.flip();
+                messageBufferBinary.flip();
                 sendMessage(false);
-                messageBuffer.clear();
+                messageBufferBinary.clear();
             }
             return false;
         }
@@ -281,32 +286,36 @@ public class WsFrame {
 
 
     @SuppressWarnings("unchecked")
-    private void sendMessage(boolean last) {
+    private void sendMessage(boolean last) throws IOException {
         if (textMessage) {
-            String payload = null;
-            try {
-                payload = new String(messageBuffer.array(), 0,
-                        messageBuffer.limit(), "UTF8");
-            } catch (UnsupportedEncodingException e) {
-                // All JVMs must support UTF8
-            }
             MessageHandler mh = wsSession.getTextMessageHandler();
             if (mh != null) {
+                CoderResult cr = utf8Decoder.decode(
+                        messageBufferBinary, messageBufferText, last);
+                if (cr.isError()) {
+                    throw new WsIOException(new CloseReason(
+                            CloseCodes.NOT_CONSISTENT,
+                            sm.getString("wsFrame.invalidUtf8")));
+                }
+                messageBufferText.flip();
                 if (mh instanceof MessageHandler.Async<?>) {
-                    ((MessageHandler.Async<String>) mh).onMessage(payload, last);
+                    ((MessageHandler.Async<String>) mh).onMessage(
+                            messageBufferText.toString(), last);
                 } else {
-                    ((MessageHandler.Basic<String>) mh).onMessage(payload);
+                    ((MessageHandler.Basic<String>) mh).onMessage(
+                            messageBufferText.toString());
                 }
+                messageBufferText.clear();
             }
         } else {
             MessageHandler mh = wsSession.getBinaryMessageHandler();
             if (mh != null) {
                 if (mh instanceof MessageHandler.Async<?>) {
                     ((MessageHandler.Async<ByteBuffer>) mh).onMessage(
-                            messageBuffer, last);
+                            messageBufferBinary, last);
                 } else {
                     ((MessageHandler.Basic<ByteBuffer>) mh).onMessage(
-                            messageBuffer);
+                            messageBufferBinary);
                 }
             }
         }
@@ -314,7 +323,9 @@ public class WsFrame {
 
 
     private void newMessage() {
-        messageBuffer.clear();
+        messageBufferBinary.clear();
+        messageBufferText.clear();
+        utf8Decoder.reset();
         continuationExpected = false;
         newFrame();
     }



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org