[WebSocket]The Sec-WebSocket-Protocol must not appear more than once in an HTTP response
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 28 Mar 2012 09:12:00 +0000 (09:12 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 28 Mar 2012 09:12:00 +0000 (09:12 +0000)
https://bugs.webkit.org/show_bug.cgi?id=82432

Patch by Li Yin <li.yin@intel.com> on 2012-03-28
Reviewed by Kent Tamura.

Source/WebCore:

From RFC6455: http://tools.ietf.org/html/rfc6455#section-11.3.4
The |Sec-WebSocket-Protocol| header field must not appear
more than once in an HTTP response.

Test: http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header.html

* Modules/websockets/WebSocketHandshake.cpp:
(WebCore::WebSocketHandshake::readHTTPHeaders):

LayoutTests:

From RFC6455: http://tools.ietf.org/html/rfc6455#section-11.3.4
The |Sec-WebSocket-Protocol| header field must not appear
more than once in an HTTP response.

* http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header-expected.txt: Added.
* http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header.html: Added.
* http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header_wsh.py: Added.
(web_socket_do_extra_handshake):
(web_socket_transfer_data):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@112377 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header.html [new file with mode: 0644]
LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header_wsh.py [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/websockets/WebSocketHandshake.cpp

index 743ee57..99b9f6f 100644 (file)
@@ -1,3 +1,20 @@
+2012-03-28  Li Yin  <li.yin@intel.com>
+
+        [WebSocket]The Sec-WebSocket-Protocol must not appear more than once in an HTTP response
+        https://bugs.webkit.org/show_bug.cgi?id=82432
+
+        Reviewed by Kent Tamura.
+
+        From RFC6455: http://tools.ietf.org/html/rfc6455#section-11.3.4
+        The |Sec-WebSocket-Protocol| header field must not appear
+        more than once in an HTTP response.
+
+        * http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header.html: Added.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header_wsh.py: Added.
+        (web_socket_do_extra_handshake):
+        (web_socket_transfer_data):
+
 2012-03-28  Philippe Normand  <pnormand@igalia.com>
 
         Unreviewed, GTK rebaseline after r112254.
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header-expected.txt b/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header-expected.txt
new file mode 100644 (file)
index 0000000..d57c7a9
--- /dev/null
@@ -0,0 +1,9 @@
+CONSOLE MESSAGE: The Sec-WebSocket-Protocol header MUST NOT appear more than once in an HTTP response
+Test that WebSocket handshake fails if there are more than one Sec-WebSocket-Protocol header field in the response.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header.html b/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header.html
new file mode 100644 (file)
index 0000000..001d1b9
--- /dev/null
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<script src="../../../../js-test-resources/js-test-pre.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+description("Test that WebSocket handshake fails if there are more than one Sec-WebSocket-Protocol header field in the response.");
+
+window.jsTestIsAsync = true;
+if (window.layoutTestController)
+    layoutTestController.overridePreference("WebKitHixie76WebSocketProtocolEnabled", 0);
+
+function endTest()
+{
+    clearTimeout(timeoutID);
+    finishJSTest();
+}
+
+var url = "ws://localhost:8880/websocket/tests/hybi/handshake-fail-by-more-protocol-header";
+var ws = new WebSocket(url, "MatchProtocol");
+
+ws.onopen = function()
+{
+    testFailed("Unexpectedly Connected.");
+};
+
+ws.onmessage = function(messageEvent)
+{
+    testFailed("Unexpectedly Received: '" + messageEvent.data + "'");
+};
+
+ws.onclose = function()
+{
+    endTest();
+};
+
+function timeOutCallback()
+{
+    debug("Timed out in state: " + ws.readyState);
+    endTest();
+}
+
+var timeoutID = setTimeout(timeOutCallback, 3000);
+
+</script>
+<script src="../../../../js-test-resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header_wsh.py b/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header_wsh.py
new file mode 100644 (file)
index 0000000..88a5635
--- /dev/null
@@ -0,0 +1,18 @@
+from mod_pywebsocket import handshake
+from mod_pywebsocket.handshake.hybi import compute_accept
+
+
+def web_socket_do_extra_handshake(request):
+    msg = 'HTTP/1.1 101 Switching Protocols\r\n'
+    msg += 'Upgrade: websocket\r\n'
+    msg += 'Connection: Upgrade\r\n'
+    msg += 'Sec-WebSocket-Accept: %s\r\n' % compute_accept(request.headers_in['Sec-WebSocket-Key'])[0]
+    msg += 'Sec-WebSocket-Protocol: MatchProtocol\r\n'
+    msg += 'Sec-WebSocket-Protocol: MismatchProtocol\r\n'
+    msg += '\r\n'
+    request.connection.write(msg)
+    raise handshake.AbortedByUserException('Abort the connection') # Prevents pywebsocket from sending its own handshake message.
+
+
+def web_socket_transfer_data(request):
+    pass
index 8cc0dc4..fc98729 100644 (file)
@@ -1,3 +1,19 @@
+2012-03-28  Li Yin  <li.yin@intel.com>
+
+        [WebSocket]The Sec-WebSocket-Protocol must not appear more than once in an HTTP response
+        https://bugs.webkit.org/show_bug.cgi?id=82432
+
+        Reviewed by Kent Tamura.
+
+        From RFC6455: http://tools.ietf.org/html/rfc6455#section-11.3.4
+        The |Sec-WebSocket-Protocol| header field must not appear 
+        more than once in an HTTP response.
+
+        Test: http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header.html
+
+        * Modules/websockets/WebSocketHandshake.cpp:
+        (WebCore::WebSocketHandshake::readHTTPHeaders):
+
 2012-03-27  James Robinson  <jamesr@chromium.org>
 
         [chromium] Transfer wheel fling via WebCompositorInputHandlerClient
index e221a9d..17c59e1 100644 (file)
@@ -576,6 +576,7 @@ const char* WebSocketHandshake::readHTTPHeaders(const char* start, const char* e
     Vector<char> name;
     Vector<char> value;
     bool sawSecWebSocketAcceptHeaderField = false;
+    bool sawSecWebSocketProtocolHeaderField = false;
     for (const char* p = start; p < end; p++) {
         name.clear();
         value.clear();
@@ -652,6 +653,13 @@ const char* WebSocketHandshake::readHTTPHeaders(const char* start, const char* e
             }
             m_response.addHeaderField(nameStr, valueStr);
             sawSecWebSocketAcceptHeaderField = true;
+        } else if (equalIgnoringCase("Sec-WebSocket-Protocol", nameStr)) {
+            if (sawSecWebSocketProtocolHeaderField) {
+                m_failureReason = "The Sec-WebSocket-Protocol header MUST NOT appear more than once in an HTTP response";
+                return 0;
+            }
+            m_response.addHeaderField(nameStr, valueStr);
+            sawSecWebSocketProtocolHeaderField = true;
         } else
             m_response.addHeaderField(nameStr, valueStr);
     }