Author: rjung
Date: Tue Dec 17 21:43:02 2013
New Revision: 1551729

URL: http://svn.apache.org/r1551729
Log:
Fix occasional test failure.

The WebSocketClient first read headers via
a BufferedReader, then tried to read the body
via the underlying InputStream. Depending on
the structure of the incoming packets reading
the body failed because some bytes were already
buffered in the reader and no longer available
by the stream. The switch between rader and stream
was motivated, because the decoding also had to
switch from ISO-8859-1 (headers) to UTF-8 (body).

We now simulate a rudimentary reader which always
reads from the stream and allows to change the
decoding charset while reading.

Modified:
    tomcat/tc7.0.x/trunk/test/org/apache/catalina/websocket/TestWebSocket.java

Modified: 
tomcat/tc7.0.x/trunk/test/org/apache/catalina/websocket/TestWebSocket.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/catalina/websocket/TestWebSocket.java?rev=1551729&r1=1551728&r2=1551729&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/test/org/apache/catalina/websocket/TestWebSocket.java 
(original)
+++ tomcat/tc7.0.x/trunk/test/org/apache/catalina/websocket/TestWebSocket.java 
Tue Dec 17 21:43:02 2013
@@ -16,13 +16,11 @@
  */
 package org.apache.catalina.websocket;
 
-import java.io.BufferedReader;
+import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
-import java.io.Reader;
 import java.io.Writer;
 import java.net.InetSocketAddress;
 import java.net.Socket;
@@ -382,12 +380,11 @@ public class TestWebSocket extends Tomca
 
     private static class WebSocketClient {
         private OutputStream os;
-        private InputStream is;
         private boolean isContinuation = false;
         final String encoding = "ISO-8859-1";
-        private Socket socket ;
-        private Writer writer ;
-        private BufferedReader reader;
+        private Socket socket;
+        private Writer writer;
+        private CustomReader reader;
 
         public WebSocketClient(int port) {
             SocketAddress addr = new InetSocketAddress("localhost", port);
@@ -397,9 +394,7 @@ public class TestWebSocket extends Tomca
                 socket.connect(addr, 10000);
                 os = socket.getOutputStream();
                 writer = new OutputStreamWriter(os, encoding);
-                is = socket.getInputStream();
-                Reader r = new InputStreamReader(is, encoding);
-                reader = new BufferedReader(r);
+                reader = new CustomReader(socket.getInputStream(), encoding);
             } catch (Exception e) {
                 throw new RuntimeException(e);
             }
@@ -449,28 +444,100 @@ public class TestWebSocket extends Tomca
         }
 
         private String readMessage() throws IOException {
-            ByteChunk bc = new ByteChunk(125);
-            CharChunk cc = new CharChunk(125);
 
             // Skip first byte
-            is.read();
+            reader.read();
 
             // Get payload length
-            int len = is.read() & 0x7F;
+            int len = reader.read() & 0x7F;
             assertTrue(len < 126);
 
             // Read payload
-            int read = 0;
-            while (read < len) {
-                read = read + is.read(bc.getBytes(), read, len - read);
+            reader.setEncoding("UTF-8");
+            return reader.read(len);
+        }
+        /*
+         * This is not a real reader but just a thin wrapper around
+         * an input stream that allows to switch encoding during
+         * reading.
+         * An example is reading headers using ISO-8859-1 and a body
+         * using UTF-8.
+         * The class is not thread-safe and not well-performing.
+         */
+        private class CustomReader {
+            private InputStream is;
+            private String encoding;
+            private boolean markSupported;
+            private B2CConverter b2c;
+
+            public CustomReader(InputStream is, String encoding) throws 
IOException {
+                this.is = new BufferedInputStream(is);
+                this.encoding = encoding;
+                markSupported = is.markSupported();
+                b2c = new B2CConverter(encoding);
+            }
+
+            public String getEncoding() {
+                return encoding;
+            }
+
+            public void setEncoding(String encoding) throws IOException {
+                this.encoding = encoding;
+                b2c = new B2CConverter(encoding);
             }
 
-            bc.setEnd(len);
+            public int read() throws IOException {
+                return is.read();
+            }
 
-            B2CConverter b2c = new B2CConverter("UTF-8");
-            b2c.convert(bc, cc, true);
+            public String read(int len) throws IOException {
+                ByteChunk bc = new ByteChunk(125);
+                CharChunk cc = new CharChunk(125);
+                int read = 0;
+                while (read < len) {
+                    read = read + is.read(bc.getBytes(), read, len - read);
+                }
+
+                bc.setEnd(len);
+                b2c.convert(bc, cc, true);
+                return cc.toString();
+            }
 
-            return cc.toString();
+            public String readLine() throws IOException {
+                ByteChunk bc = new ByteChunk(125);
+                CharChunk cc = new CharChunk(125);
+                char c;
+                int i = is.read();
+                int read = 0;
+                while (i != -1) {
+                    if (i != '\r' && i != '\n') {
+                        bc.append((byte)i);
+                        read++;
+                    } else if (i == '\n') {
+                        break;
+                    } else if (i == '\r') {
+                        if (markSupported) {
+                            is.mark(2);
+                        }
+                        i = read();
+                        if (i == -1) {
+                            break;
+                        } else {
+                            if (i == '\n') {
+                                break;
+                            } else {
+                                if (markSupported) {
+                                    is.reset();
+                                }
+                            }
+                        }
+                    }
+                    i = is.read();
+                }
+                bc.setEnd(read);
+                b2c.convert(bc, cc, true);
+                return cc.toString();
+            }
         }
     }
 }



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

Reply via email to