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: [email protected]
For additional commands, e-mail: [email protected]