Author: pero
Date: Fri Apr  6 17:51:25 2012
New Revision: 1310506

URL: http://svn.apache.org/viewvc?rev=1310506&view=rev
Log:
Correct websocket protocol version detection

Modified:
    
tomcat/tc7.0.x/trunk/java/org/apache/catalina/websocket/WebSocketServlet.java
    tomcat/tc7.0.x/trunk/test/org/apache/catalina/websocket/TestWebSocket.java
    tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/websocket/WebSocketServlet.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/websocket/WebSocketServlet.java?rev=1310506&r1=1310505&r2=1310506&view=diff
==============================================================================
--- 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/websocket/WebSocketServlet.java 
(original)
+++ 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/websocket/WebSocketServlet.java 
Fri Apr  6 17:51:25 2012
@@ -143,7 +143,7 @@ public abstract class WebSocketServlet e
                 }
             }
         }
-        return true;
+        return false;
     }
 
 
@@ -166,7 +166,7 @@ public abstract class WebSocketServlet e
         return result;
     }
 
-
+    // ToDo: Use ThreadLocal pool sha1Helper
     private String getWebSocketAccept(String key) {
         synchronized (sha1Helper) {
             sha1Helper.reset();

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=1310506&r1=1310505&r2=1310506&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 
Fri Apr  6 17:51:25 2012
@@ -16,6 +16,10 @@
  */
 package org.apache.catalina.websocket;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.IOException;
@@ -28,21 +32,25 @@ import java.io.Writer;
 import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.net.SocketAddress;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import org.junit.Test;
+import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.catalina.startup.Tomcat;
 import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.catalina.util.Base64;
 import org.apache.tomcat.util.buf.B2CConverter;
 import org.apache.tomcat.util.buf.ByteChunk;
 import org.apache.tomcat.util.buf.C2BConverter;
 import org.apache.tomcat.util.buf.CharChunk;
+import org.junit.Test;
 
 public class TestWebSocket extends TomcatBaseTest {
 
     private static final String CRLF = "\r\n";
+    private static final byte[] WS_ACCEPT =
+        "258EAFA5-E914-47DA-95CA-C5AB0DC85B11".getBytes(
+                B2CConverter.ISO_8859_1);
 
     private OutputStream os;
     private InputStream is;
@@ -56,36 +64,27 @@ public class TestWebSocket extends Tomca
 
         tomcat.start();
 
-        // Open the socket
-        final String encoding = "ISO-8859-1";
-        SocketAddress addr = new InetSocketAddress("localhost", getPort());
-        Socket socket = new Socket();
-        socket.setSoTimeout(10000);
-        socket.connect(addr, 10000);
-        os = socket.getOutputStream();
-        Writer writer = new OutputStreamWriter(os, encoding);
-        is = socket.getInputStream();
-        Reader r = new InputStreamReader(is, encoding);
-        BufferedReader reader = new BufferedReader(r);
+        WebSocketCLient client= new WebSocketCLient();
+
 
         // Send the WebSocket handshake
-        writer.write("GET /examples/websocket/echoStream HTTP/1.1" + CRLF);
-        writer.write("Host: foo" + CRLF);
-        writer.write("Upgrade: websocket" + CRLF);
-        writer.write("Connection: upgrade" + CRLF);
-        writer.write("Sec-WebSocket-Version: 13" + CRLF);
-        writer.write("Sec-WebSocket-Key: TODO" + CRLF);
-        writer.write(CRLF);
-        writer.flush();
+        client.writer.write("GET /examples/websocket/echoStream HTTP/1.1" + 
CRLF);
+        client.writer.write("Host: foo" + CRLF);
+        client.writer.write("Upgrade: websocket" + CRLF);
+        client.writer.write("Connection: keep-alive, upgrade" + CRLF);
+        client.writer.write("Sec-WebSocket-Version: 13" + CRLF);
+        client.writer.write("Sec-WebSocket-Key: TODO" + CRLF);
+        client.writer.write(CRLF);
+        client.writer.flush();
 
         // Make sure we got an upgrade response
-        String responseLine = reader.readLine();
+        String responseLine = client.reader.readLine();
         assertTrue(responseLine.startsWith("HTTP/1.1 101"));
 
         // Swallow the headers
-        String responseHeaderLine = reader.readLine();
+        String responseHeaderLine = client.reader.readLine();
         while (!responseHeaderLine.equals("")) {
-            responseHeaderLine = reader.readLine();
+            responseHeaderLine = client.reader.readLine();
         }
 
         // Now we can do WebSocket
@@ -95,11 +94,153 @@ public class TestWebSocket extends Tomca
         assertEquals("foofoo",readMessage());
 
         // Finished with the socket
-        socket.close();
+        client.close();
+    }
+
+    @Test
+    public void testDetectWrongVersion() throws Exception {
+        Tomcat tomcat = getTomcatInstance();
+        File appDir = new File(getBuildDirectory(), "webapps/examples");
+        tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath());
+
+        tomcat.start();
+        WebSocketCLient client= new WebSocketCLient();
+
+        // Send the WebSocket handshake
+        client.writer.write("GET /examples/websocket/echoStream HTTP/1.1" + 
CRLF);
+        client.writer.write("Host: foo" + CRLF);
+        client.writer.write("Upgrade: websocket" + CRLF);
+        client.writer.write("Connection: upgrade" + CRLF);
+        client.writer.write("Sec-WebSocket-Version: 8" + CRLF);
+        client.writer.write("Sec-WebSocket-Key: TODO" + CRLF);
+        client.writer.write(CRLF);
+        client.writer.flush();
+
+        // Make sure we got an upgrade response
+        String responseLine = client.reader.readLine();
+        assertTrue(responseLine.startsWith("HTTP/1.1 426"));
+
+        // Swallow the headers
+        List<String> headerlines = new ArrayList<String>();
+
+        String responseHeaderLine = client.reader.readLine();
+        while (!responseHeaderLine.equals("")) {
+            headerlines.add(responseHeaderLine);
+            responseHeaderLine = client.reader.readLine();
+        }
+
+        assertTrue(headerlines.contains("Sec-WebSocket-Version: 13"));
+        // Finished with the socket
+        client.close();
+    }
+
+    @Test
+    public void testNoConnection() throws Exception {
+        Tomcat tomcat = getTomcatInstance();
+        File appDir = new File(getBuildDirectory(), "webapps/examples");
+        tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath());
+
+        tomcat.start();
+        WebSocketCLient client= new WebSocketCLient();
+
+
+        // Send the WebSocket handshake
+        client.writer.write("GET /examples/websocket/echoStream HTTP/1.1" + 
CRLF);
+        client.writer.write("Host: foo" + CRLF);
+        client.writer.write("Upgrade: websocket" + CRLF);
+        client.writer.write("Sec-WebSocket-Version: 13" + CRLF);
+        client.writer.write("Sec-WebSocket-Key: TODO" + CRLF);
+        client.writer.write(CRLF);
+        client.writer.flush();
+
+        // Make sure we got an upgrade response
+        String responseLine = client.reader.readLine();
+        assertTrue(responseLine.startsWith("HTTP/1.1 400"));
+
+        // Finished with the socket
+        client.close();
     }
 
+
+    @Test
+    public void testNoUpgrade() throws Exception {
+        Tomcat tomcat = getTomcatInstance();
+        File appDir = new File(getBuildDirectory(), "webapps/examples");
+        tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath());
+
+        tomcat.start();
+        WebSocketCLient client= new WebSocketCLient();
+
+        // Send the WebSocket handshake
+        client.writer.write("GET /examples/websocket/echoStream HTTP/1.1" + 
CRLF);
+        client.writer.write("Host: foo" + CRLF);
+        client.writer.write("Connection: upgrade" + CRLF);
+        client.writer.write("Sec-WebSocket-Version: 13" + CRLF);
+        client.writer.write("Sec-WebSocket-Key: TODO" + CRLF);
+        client.writer.write(CRLF);
+        client.writer.flush();
+
+        // Make sure we got an upgrade response
+        String responseLine = client.reader.readLine();
+        assertTrue(responseLine.startsWith("HTTP/1.1 400"));
+
+        // Finished with the socket
+        client.close();
+    }
+
+    @Test
+    public void testKey() throws Exception {
+        Tomcat tomcat = getTomcatInstance();
+        File appDir = new File(getBuildDirectory(), "webapps/examples");
+        tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath());
+
+        tomcat.start();
+        WebSocketCLient client= new WebSocketCLient();
+
+        // Send the WebSocket handshake
+        client.writer.write("GET /examples/websocket/echoStream HTTP/1.1" + 
CRLF);
+        client.writer.write("Host: foo" + CRLF);
+        client.writer.write("Upgrade: websocket" + CRLF);
+        client.writer.write("Connection: upgrade" + CRLF);
+        client.writer.write("Sec-WebSocket-Version: 13" + CRLF);
+        client.writer.write("Sec-WebSocket-Key: TODO" + CRLF);
+        client.writer.write(CRLF);
+        client.writer.flush();
+
+        // Make sure we got an upgrade response
+        String responseLine = client.reader.readLine();
+        assertTrue(responseLine.startsWith("HTTP/1.1 101"));
+
+        // Swallow the headers
+        String accept = null;
+
+        String responseHeaderLine = client.reader.readLine();
+        while (!responseHeaderLine.equals("")) {
+            if(responseHeaderLine.startsWith("Sec-WebSocket-Accept: ")) {
+                accept = 
responseHeaderLine.substring(responseHeaderLine.indexOf(":")+2);
+                break;
+            }
+            responseHeaderLine = client.reader.readLine();
+        }
+        assertTrue(accept != null);
+        MessageDigest sha1Helper = MessageDigest.getInstance("SHA1");
+        sha1Helper.reset();
+        sha1Helper.update("TODO".getBytes(B2CConverter.ISO_8859_1));
+        String source = Base64.encode(sha1Helper.digest(WS_ACCEPT));
+        assertEquals(source,accept);
+
+        sha1Helper.reset();
+        sha1Helper.update("TOD".getBytes(B2CConverter.ISO_8859_1));
+        source = Base64.encode(sha1Helper.digest(WS_ACCEPT));
+        assertFalse(source.equals(accept));
+        // Finished with the socket
+        client.close();
+    }
+
+
+
     private void sendMessage(String message, boolean finalFragment)
-            throws IOException{
+    throws IOException{
         ByteChunk bc = new ByteChunk(8192);
         C2BConverter c2b = new C2BConverter(bc, "UTF-8");
         c2b.convert(message);
@@ -161,4 +302,34 @@ public class TestWebSocket extends Tomca
 
         return cc.toString();
     }
+
+    private class WebSocketCLient 
+    {
+        // Open the socket
+        final String encoding = "ISO-8859-1";
+        Socket socket ;
+        Writer writer ;
+        BufferedReader reader;
+
+        private WebSocketCLient() {
+            SocketAddress addr = new InetSocketAddress("localhost", getPort());
+            socket = new Socket();
+            try {
+                socket.setSoTimeout(10000);
+                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);
+            } catch (Exception e) {
+                new RuntimeException(e);
+            }
+        }
+
+        void close() throws IOException {
+            socket.close();
+        }
+
+    }
 }

Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1310506&r1=1310505&r2=1310506&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Fri Apr  6 17:51:25 2012
@@ -56,6 +56,9 @@
 <section name="Tomcat 7.0.28 (markt)">
   <subsection name="Catalina">
     <changelog>
+      <fix>
+        Correct websocket protocol version detection. (pero)
+      </fix>
       <add>
         Add new attributes of allow and deny to UserConfig. (kfujino)
       </add>



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

Reply via email to