Title: [199434] releases/WebKitGTK/webkit-2.12
Revision
199434
Author
carlo...@webkit.org
Date
2016-04-13 01:52:20 -0700 (Wed, 13 Apr 2016)

Log Message

Merge r198561 - Restrict WebSockets header parsing according to RFC6455 and RFC7230. Based on Lamarque V. Souza's original patch.
https://bugs.webkit.org/show_bug.cgi?id=82714

Patch by John Wilander <wilan...@apple.com> on 2016-03-22
Reviewed by Brent Fulgham.

Source/WebCore:

Tests: http/tests/websocket/tests/hybi/error-event-ready-state-non-existent-url-with-server-responding-404.html
       http/tests/websocket/tests/hybi/handshake-fail-by-invalid-http-version.html
       http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-accept.html
       http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-extensions.html
       http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-protocol.html
       http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-status-line.html
       http/tests/websocket/tests/hybi/handshake-fail-by-null-char-in-status.html
       http/tests/websocket/tests/hybi/handshake-ok-with-http-version-beyond-1_1.html

* Modules/websockets/WebSocketHandshake.cpp:
(WebCore::WebSocketHandshake::httpURLForAuthenticationAndCookies):
(WebCore::headerHasValidHTTPVersion):
    - Check for HTTP version 1.1 and above.
(WebCore::WebSocketHandshake::readStatusLine):
    - Only allow ASCII characters in status line.
    - Only allow HTTP version 1.1 and above in status line.
(WebCore::WebSocketHandshake::readHTTPHeaders):
    - Only allow ASCII characters in values for new HTTP headers.

LayoutTests:

* http/tests/websocket/tests/hybi/error-event-ready-state-expected.txt: Removed.
    - See comment below on the associated HTML file.
* http/tests/websocket/tests/hybi/error-event-ready-state-non-existent-url-with-server-responding-404-expected.txt: Added.
* http/tests/websocket/tests/hybi/error-event-ready-state-non-existent-url-with-server-responding-404.html: Added.
    - Uses PHP to respond with an HTTP 1.1 404. The old (now removed) test case failed once we restricted WebSockets to HTTP 1.1 and above because the test server responded with an HTTP 1.0 404 for non-existing files.
* http/tests/websocket/tests/hybi/error-event-ready-state.html: Removed.
    - This test case was renamed "error-event-ready-state-non-existent-url-with-server-responding-404" to make it clear it now relies on a server responding with HTTP 1.1 404.
* http/tests/websocket/tests/hybi/handshake-fail-by-invalid-http-version-expected.txt: Added.
* http/tests/websocket/tests/hybi/handshake-fail-by-invalid-http-version.html: Added.
* http/tests/websocket/tests/hybi/handshake-fail-by-invalid-http-version_wsh.py: Added.
(web_socket_do_extra_handshake):
(web_socket_transfer_data):
    - Test case for lower than HTTP 1.1 versions.
* http/tests/websocket/tests/hybi/handshake-fail-by-more-accept-header-expected.txt:
* http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header-expected.txt:
* http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header-expected.txt:
    - Updated to pass with lowercase 'must not' in the failure reason.
* http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-accept-expected.txt: Added.
* http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-accept.html: Added.
* http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-accept_wsh.py: Added.
(web_socket_do_extra_handshake):
(web_socket_transfer_data):
    - Test case for non-ASCII characters in new HTTP header Sec-WebSocket-Accept.
* http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-extensions-expected.txt: Added.
* http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-extensions.html: Added.
* http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-extensions_wsh.py: Added.
(web_socket_do_extra_handshake):
(web_socket_transfer_data):
    - Test case for non-ASCII characters in new HTTP header Sec-WebSocket-Extensions.
* http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-protocol-expected.txt: Added.
* http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-protocol.html: Added.
* http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-protocol_wsh.py: Added.
(web_socket_do_extra_handshake):
(web_socket_transfer_data):
    - Test case for non-ASCII characters in new HTTP header Sec-WebSocket-Protocol.
* http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-status-line-expected.txt: Added.
* http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-status-line.html: Added.
* http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-status-line_wsh.py: Added.
(web_socket_do_extra_handshake):
(web_socket_transfer_data):
    - Test case for non-ASCII characters in HTTP status line.
* http/tests/websocket/tests/hybi/handshake-fail-by-null-char-in-status-expected.txt: Added.
* http/tests/websocket/tests/hybi/handshake-fail-by-null-char-in-status.html: Added.
* http/tests/websocket/tests/hybi/handshake-fail-by-null-char-in-status_wsh.py: Added.
(web_socket_do_extra_handshake):
(web_socket_transfer_data):
    - Test case for null character in the middle of the HTTP status line.
* http/tests/websocket/tests/hybi/handshake-fail-by-prepended-null_wsh.py:
(web_socket_do_extra_handshake):
(web_socket_transfer_data):
    - This test case was changed to prepend a null character to the actual status line. Previously it used a WebSockets frame with a prepended null before the status line. The Python WebSockets lib uses non-ASCII characters in that frame which meant the test case hit the non-ASCII check before the null check. It was confusing to me that the description and intent of the test was to run with a null in the status line, not in a frame before the status line. I believe the changed test case better reflects the intention of the test.
* http/tests/websocket/tests/hybi/handshake-ok-with-http-version-beyond-1_1-expected.txt: Added.
* http/tests/websocket/tests/hybi/handshake-ok-with-http-version-beyond-1_1.html: Added.
* http/tests/websocket/tests/hybi/handshake-ok-with-http-version-beyond-1_1_wsh.py: Added.
(web_socket_do_extra_handshake):
(web_socket_transfer_data):
    - Test case for HTTP versions higher than 1.1.
* http/tests/websocket/tests/hybi/resources/status-404-without-body.php: Added.
    - To use with the error-event-ready-state-non-existent-url-with-server-responding-404.html test described above.

Modified Paths

Added Paths

Removed Paths

Diff

Modified: releases/WebKitGTK/webkit-2.12/LayoutTests/ChangeLog (199433 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/ChangeLog	2016-04-13 08:47:20 UTC (rev 199433)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/ChangeLog	2016-04-13 08:52:20 UTC (rev 199434)
@@ -1,3 +1,70 @@
+2016-03-22  John Wilander  <wilan...@apple.com>
+
+        Restrict WebSockets header parsing according to RFC6455 and RFC7230. Based on Lamarque V. Souza's original patch.
+        https://bugs.webkit.org/show_bug.cgi?id=82714
+
+        Reviewed by Brent Fulgham.
+
+        * http/tests/websocket/tests/hybi/error-event-ready-state-expected.txt: Removed.
+            - See comment below on the associated HTML file.
+        * http/tests/websocket/tests/hybi/error-event-ready-state-non-existent-url-with-server-responding-404-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/error-event-ready-state-non-existent-url-with-server-responding-404.html: Added.
+            - Uses PHP to respond with an HTTP 1.1 404. The old (now removed) test case failed once we restricted WebSockets to HTTP 1.1 and above because the test server responded with an HTTP 1.0 404 for non-existing files.
+        * http/tests/websocket/tests/hybi/error-event-ready-state.html: Removed.
+            - This test case was renamed "error-event-ready-state-non-existent-url-with-server-responding-404" to make it clear it now relies on a server responding with HTTP 1.1 404.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-invalid-http-version-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-invalid-http-version.html: Added.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-invalid-http-version_wsh.py: Added.
+        (web_socket_do_extra_handshake):
+        (web_socket_transfer_data):
+            - Test case for lower than HTTP 1.1 versions.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-more-accept-header-expected.txt:
+        * http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header-expected.txt:
+        * http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header-expected.txt:
+            - Updated to pass with lowercase 'must not' in the failure reason.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-accept-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-accept.html: Added.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-accept_wsh.py: Added.
+        (web_socket_do_extra_handshake):
+        (web_socket_transfer_data):
+            - Test case for non-ASCII characters in new HTTP header Sec-WebSocket-Accept.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-extensions-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-extensions.html: Added.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-extensions_wsh.py: Added.
+        (web_socket_do_extra_handshake):
+        (web_socket_transfer_data):
+            - Test case for non-ASCII characters in new HTTP header Sec-WebSocket-Extensions.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-protocol-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-protocol.html: Added.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-protocol_wsh.py: Added.
+        (web_socket_do_extra_handshake):
+        (web_socket_transfer_data):
+            - Test case for non-ASCII characters in new HTTP header Sec-WebSocket-Protocol.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-status-line-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-status-line.html: Added.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-status-line_wsh.py: Added.
+        (web_socket_do_extra_handshake):
+        (web_socket_transfer_data):
+            - Test case for non-ASCII characters in HTTP status line.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-null-char-in-status-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-null-char-in-status.html: Added.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-null-char-in-status_wsh.py: Added.
+        (web_socket_do_extra_handshake):
+        (web_socket_transfer_data):
+            - Test case for null character in the middle of the HTTP status line.
+        * http/tests/websocket/tests/hybi/handshake-fail-by-prepended-null_wsh.py:
+        (web_socket_do_extra_handshake):
+        (web_socket_transfer_data):
+            - This test case was changed to prepend a null character to the actual status line. Previously it used a WebSockets frame with a prepended null before the status line. The Python WebSockets lib uses non-ASCII characters in that frame which meant the test case hit the non-ASCII check before the null check. It was confusing to me that the description and intent of the test was to run with a null in the status line, not in a frame before the status line. I believe the changed test case better reflects the intention of the test.
+        * http/tests/websocket/tests/hybi/handshake-ok-with-http-version-beyond-1_1-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/handshake-ok-with-http-version-beyond-1_1.html: Added.
+        * http/tests/websocket/tests/hybi/handshake-ok-with-http-version-beyond-1_1_wsh.py: Added.
+        (web_socket_do_extra_handshake):
+        (web_socket_transfer_data):
+            - Test case for HTTP versions higher than 1.1.
+        * http/tests/websocket/tests/hybi/resources/status-404-without-body.php: Added.
+            - To use with the error-event-ready-state-non-existent-url-with-server-responding-404.html test described above.
+
 2016-03-21  Zalan Bujtas  <za...@apple.com>
 
         WebCore::RenderTableCell::setCol should put a cap on the column value. 

Deleted: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/error-event-ready-state-expected.txt (199433 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/error-event-ready-state-expected.txt	2016-04-13 08:47:20 UTC (rev 199433)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/error-event-ready-state-expected.txt	2016-04-13 08:52:20 UTC (rev 199434)
@@ -1,11 +0,0 @@
-CONSOLE MESSAGE: WebSocket connection to 'ws://localhost:8880/non-existent-url' failed: Unexpected response code: 404
-Test that readyState is CLOSED within onerror event
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-onerror() was called.
-PASS ws.readyState is 3
-PASS successfullyParsed is true
-
-TEST COMPLETE
-

Copied: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/error-event-ready-state-non-existent-url-with-server-responding-404-expected.txt (from rev 199433, releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/error-event-ready-state-expected.txt) (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/error-event-ready-state-non-existent-url-with-server-responding-404-expected.txt	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/error-event-ready-state-non-existent-url-with-server-responding-404-expected.txt	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,11 @@
+CONSOLE MESSAGE: WebSocket connection to 'ws://localhost:8000/websocket/tests/hybi/resources/status-404-without-body.php' failed: Unexpected response code: 404
+Test that readyState is CLOSED within onerror event
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+onerror() was called.
+PASS ws.readyState is 3
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Copied: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/error-event-ready-state-non-existent-url-with-server-responding-404.html (from rev 199433, releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/error-event-ready-state.html) (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/error-event-ready-state-non-existent-url-with-server-responding-404.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/error-event-ready-state-non-existent-url-with-server-responding-404.html	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script type="text/_javascript_">
+description("Test that readyState is CLOSED within onerror event");
+
+window.jsTestIsAsync = true;
+
+var ws = new WebSocket("ws://localhost:8000/websocket/tests/hybi/resources/status-404-without-body.php");
+
+ws._onerror_ = function(event) {
+    debug("onerror() was called.");
+    shouldBe("ws.readyState", "3");
+    finishJSTest();
+};
+
+</script>
+<script src=""
+</body>
+</html>

Deleted: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/error-event-ready-state.html (199433 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/error-event-ready-state.html	2016-04-13 08:47:20 UTC (rev 199433)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/error-event-ready-state.html	2016-04-13 08:52:20 UTC (rev 199434)
@@ -1,25 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<script src=""
-</head>
-<body>
-<div id="description"></div>
-<div id="console"></div>
-<script type="text/_javascript_">
-description("Test that readyState is CLOSED within onerror event");
-
-window.jsTestIsAsync = true;
-
-var ws = new WebSocket("ws://localhost:8880/non-existent-url");
-
-ws._onerror_ = function(event) {
-    debug("onerror() was called.");
-    shouldBe("ws.readyState", "3");
-    finishJSTest();
-};
-
-</script>
-<script src=""
-</body>
-</html>

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-invalid-http-version-expected.txt (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-invalid-http-version-expected.txt	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-invalid-http-version-expected.txt	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,10 @@
+CONSOLE MESSAGE: WebSocket connection to 'ws://localhost:8880/websocket/tests/hybi/handshake-fail-by-invalid-http-version' failed: Invalid HTTP version string: HTTP/1.0
+Test whether WebSocket handshake fails if the server sends status line with invalid http version.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS closeEvent.wasClean is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-invalid-http-version.html (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-invalid-http-version.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-invalid-http-version.html	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <script src=""
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+    description("Test whether WebSocket handshake fails if the server sends status line with invalid http version.");
+
+    window.jsTestIsAsync = true;
+
+    var url = ""
+    var ws = new WebSocket(url);
+    var closeEvent;
+
+    ws._onopen_ = function() {
+        testFailed("Connection established.");
+        ws.close();
+    };
+
+    ws._onclose_ = function(event) {
+        closeEvent = event;
+        shouldBeFalse("closeEvent.wasClean");
+        finishJSTest();
+    };
+</script>
+<script src=""
+</body>
+</html>
\ No newline at end of file

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-invalid-http-version_wsh.py (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-invalid-http-version_wsh.py	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-invalid-http-version_wsh.py	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,17 @@
+from mod_pywebsocket import handshake
+from mod_pywebsocket import stream
+from mod_pywebsocket.handshake.hybi import compute_accept
+
+
+def web_socket_do_extra_handshake(request):
+    message = 'HTTP/1.0 101 Switching Protocols\r\n'
+    message += 'Upgrade: websocket\r\n'
+    message += 'Connection: Upgrade\r\n'
+    message += 'Sec-WebSocket-Accept: %s\r\n' % compute_accept(request.headers_in['Sec-WebSocket-Key'])[0]
+    message += '\r\n'
+    request.connection.write(message)
+    raise handshake.AbortedByUserException('Abort the connection') # Prevents pywebsocket from sending its own handshake message.
+
+
+def web_socket_transfer_data(request):
+    pass

Modified: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-accept-header-expected.txt (199433 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-accept-header-expected.txt	2016-04-13 08:47:20 UTC (rev 199433)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-accept-header-expected.txt	2016-04-13 08:52:20 UTC (rev 199434)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: WebSocket connection to 'ws://localhost:8880/websocket/tests/hybi/handshake-fail-by-more-accept-header' failed: The Sec-WebSocket-Accept header MUST NOT appear more than once in an HTTP response
+CONSOLE MESSAGE: WebSocket connection to 'ws://localhost:8880/websocket/tests/hybi/handshake-fail-by-more-accept-header' failed: The Sec-WebSocket-Accept header must not appear more than once in an HTTP response
 Test that WebSocket handshake fails if there are more one Sec-WebSocket-Accept header field in the response.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".

Modified: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header-expected.txt (199433 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header-expected.txt	2016-04-13 08:47:20 UTC (rev 199433)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-extensions-header-expected.txt	2016-04-13 08:52:20 UTC (rev 199434)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: WebSocket connection to 'ws://localhost:8880/websocket/tests/hybi/handshake-fail-by-more-extensions-header' failed: The Sec-WebSocket-Extensions header MUST NOT appear more than once in an HTTP response
+CONSOLE MESSAGE: WebSocket connection to 'ws://localhost:8880/websocket/tests/hybi/handshake-fail-by-more-extensions-header' failed: The Sec-WebSocket-Extensions header must not appear more than once in an HTTP response
 Test that WebSocket handshake fails if there are more than one Sec-WebSocket-Extensions header field in the response..
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".

Modified: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header-expected.txt (199433 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header-expected.txt	2016-04-13 08:47:20 UTC (rev 199433)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-more-protocol-header-expected.txt	2016-04-13 08:52:20 UTC (rev 199434)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: WebSocket connection to 'ws://localhost:8880/websocket/tests/hybi/handshake-fail-by-more-protocol-header' failed: The Sec-WebSocket-Protocol header MUST NOT appear more than once in an HTTP response
+CONSOLE MESSAGE: WebSocket connection to 'ws://localhost:8880/websocket/tests/hybi/handshake-fail-by-more-protocol-header' failed: 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".

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-accept-expected.txt (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-accept-expected.txt	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-accept-expected.txt	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,10 @@
+CONSOLE MESSAGE: WebSocket connection to 'ws://localhost:8880/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-accept' failed: Sec-WebSocket-Accept header value should only contain ASCII characters
+Test whether WebSocket handshake fails if the server sends header with non-ascii characters in name.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS closeEvent.wasClean is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-accept.html (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-accept.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-accept.html	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <script src=""
+    </head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+    description("Test whether WebSocket handshake fails if the server sends header with non-ascii characters in name.");
+
+    window.jsTestIsAsync = true;
+
+    var url = ""
+    var ws = new WebSocket(url);
+    var closeEvent;
+
+    ws._onopen_ = function() {
+        testFailed("Connection established.");
+        ws.close();
+    };
+
+    ws._onclose_ = function(event) {
+        closeEvent = event;
+        shouldBeFalse("closeEvent.wasClean");
+        finishJSTest();
+    };
+</script>
+<script src=""
+</body>
+</html>

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-accept_wsh.py (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-accept_wsh.py	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-accept_wsh.py	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,14 @@
+from mod_pywebsocket import handshake
+
+def web_socket_do_extra_handshake(request):
+    message = 'HTTP/1.1 101 Switching Protocols\r\n'
+    message += 'Upgrade: websocket\r\n'
+    message += 'Connection: Upgrade\r\n'
+    message += 'Sec-WebSocket-Accept: Non-áscii-value\r\n'
+    message += '\r\n'
+    request.connection.write(message)
+    raise handshake.AbortedByUserException('Abort the connection') # Prevents pywebsocket from sending its own handshake message.
+
+
+def web_socket_transfer_data(request):
+    pass

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-extensions-expected.txt (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-extensions-expected.txt	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-extensions-expected.txt	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,10 @@
+CONSOLE MESSAGE: WebSocket connection to 'ws://localhost:8880/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-extensions' failed: Sec-WebSocket-Extensions header value should only contain ASCII characters
+Test whether WebSocket handshake fails if the server sends a WebSocket extensions header with non-ascii characters in its value.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS closeEvent.wasClean is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-extensions.html (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-extensions.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-extensions.html	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <script src=""
+    </head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+    description("Test whether WebSocket handshake fails if the server sends a WebSocket extensions header with non-ascii characters in its value.");
+
+    window.jsTestIsAsync = true;
+
+    var url = ""
+    var ws = new WebSocket(url);
+    var closeEvent;
+
+    ws._onopen_ = function() {
+        testFailed("Connection established.");
+        ws.close();
+    };
+
+    ws._onclose_ = function(event) {
+        closeEvent = event;
+        shouldBeFalse("closeEvent.wasClean");
+        finishJSTest();
+    };
+</script>
+<script src=""
+</body>
+</html>

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-extensions_wsh.py (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-extensions_wsh.py	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-extensions_wsh.py	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,16 @@
+from mod_pywebsocket import handshake
+from mod_pywebsocket.handshake.hybi import compute_accept
+
+def web_socket_do_extra_handshake(request):
+    message = 'HTTP/1.1 101 Switching Protocols\r\n'
+    message += 'Upgrade: websocket\r\n'
+    message += 'Connection: Upgrade\r\n'
+    message += 'Sec-WebSocket-Accept: %s\r\n' % compute_accept(request.headers_in['Sec-WebSocket-Key'])[0]
+    message += 'Sec-WebSocket-Extensions: Non-áscii-value\r\n'
+    message += '\r\n'
+    request.connection.write(message)
+    raise handshake.AbortedByUserException('Abort the connection') # Prevents pywebsocket from sending its own handshake message.
+
+
+def web_socket_transfer_data(request):
+    pass

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-protocol-expected.txt (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-protocol-expected.txt	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-protocol-expected.txt	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,10 @@
+CONSOLE MESSAGE: WebSocket connection to 'ws://localhost:8880/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-protocol' failed: Sec-WebSocket-Protocol header value should only contain ASCII characters
+Test whether WebSocket handshake fails if the server sends a WebSocket protocol header with non-ascii characters in its value.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS closeEvent.wasClean is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-protocol.html (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-protocol.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-protocol.html	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <script src=""
+    </head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+    description("Test whether WebSocket handshake fails if the server sends a WebSocket protocol header with non-ascii characters in its value.");
+
+    window.jsTestIsAsync = true;
+
+    var url = ""
+    var ws = new WebSocket(url);
+    var closeEvent;
+
+    ws._onopen_ = function() {
+        testFailed("Connection established.");
+        ws.close();
+    };
+
+    ws._onclose_ = function(event) {
+        closeEvent = event;
+        shouldBeFalse("closeEvent.wasClean");
+        finishJSTest();
+    };
+</script>
+<script src=""
+</body>
+</html>

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-protocol_wsh.py (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-protocol_wsh.py	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-protocol_wsh.py	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,16 @@
+from mod_pywebsocket import handshake
+from mod_pywebsocket.handshake.hybi import compute_accept
+
+def web_socket_do_extra_handshake(request):
+    message = 'HTTP/1.1 101 Switching Protocols\r\n'
+    message += 'Upgrade: websocket\r\n'
+    message += 'Connection: Upgrade\r\n'
+    message += 'Sec-WebSocket-Accept: %s\r\n' % compute_accept(request.headers_in['Sec-WebSocket-Key'])[0]
+    message += 'Sec-WebSocket-Protocol: Non-áscii-value\r\n'
+    message += '\r\n'
+    request.connection.write(message)
+    raise handshake.AbortedByUserException('Abort the connection') # Prevents pywebsocket from sending its own handshake message.
+
+
+def web_socket_transfer_data(request):
+    pass

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-status-line-expected.txt (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-status-line-expected.txt	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-status-line-expected.txt	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,10 @@
+CONSOLE MESSAGE: WebSocket connection to 'ws://localhost:8880/websocket/tests/hybi/handshake-fail-by-non-ascii-status-line' failed: Status line contains non-ASCII character
+Test whether WebSocket handshake fails if the server sends status line with non-ascii characters.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS closeEvent.wasClean is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-status-line.html (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-status-line.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-status-line.html	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <script src=""
+    </head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+    description("Test whether WebSocket handshake fails if the server sends status line with non-ascii characters.");
+
+    window.jsTestIsAsync = true;
+
+    var url = ""
+    var ws = new WebSocket(url);
+    var closeEvent;
+
+    ws._onopen_ = function() {
+        testFailed("Connection established.");
+        ws.close();
+    };
+
+    ws._onclose_ = function(event) {
+        closeEvent = event;
+        shouldBeFalse("closeEvent.wasClean");
+        finishJSTest();
+    };
+</script>
+<script src=""
+</body>
+</html>
\ No newline at end of file

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-status-line_wsh.py (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-status-line_wsh.py	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-status-line_wsh.py	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,19 @@
+from mod_pywebsocket import handshake
+from mod_pywebsocket import stream
+from mod_pywebsocket.handshake.hybi import compute_accept
+
+def web_socket_do_extra_handshake(request):
+    frame = stream.create_text_frame('Frame-contains-thirty-one-bytes')
+
+    message = frame
+    message += 'HTTP/1.1 101 Switching Protocols non-ascií\r\n'
+    message += 'Upgrade: websocket\r\n'
+    message += 'Connection: Upgrade\r\n'
+    message += 'Sec-WebSocket-Accept: %s\r\n' % compute_accept(request.headers_in['Sec-WebSocket-Key'])[0]
+    message += '\r\n'
+    request.connection.write(message)
+    raise handshake.AbortedByUserException('Abort the connection') # Prevents pywebsocket from sending its own handshake message.
+
+
+def web_socket_transfer_data(request):
+    pass

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-null-char-in-status-expected.txt (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-null-char-in-status-expected.txt	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-null-char-in-status-expected.txt	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,12 @@
+CONSOLE MESSAGE: WebSocket connection to 'ws://localhost:8880/websocket/tests/hybi/handshake-fail-by-null-char-in-status' failed: Status line contains embedded null
+Connection should fail immediately, rather than succeeding or staying in limbo until timeout, if a null byte is received in the status header.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS timedOut is false
+PASS connected is false
+PASS origin is undefined.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-null-char-in-status.html (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-null-char-in-status.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-null-char-in-status.html	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+description('Connection should fail immediately, rather than succeeding or staying in limbo until timeout, if a null byte is received in the status header.');
+
+window.jsTestIsAsync = true;
+
+var timedOut = false;
+var connected = false;
+var origin;
+
+function endTest() {
+    shouldBeFalse('timedOut');
+    shouldBeFalse('connected');
+    shouldBeUndefined('origin');
+    clearTimeout(timeoutID);
+    finishJSTest();
+}
+
+var url = '';
+var ws = new WebSocket(url);
+
+ws._onopen_ = function()
+{
+    debug('Connected');
+    connected = true;
+}
+
+ws._onmessage_ = function(messageEvent)
+{
+    origin = messageEvent.data;
+    debug('origin = ' + origin);
+    ws.close();
+}
+
+ws._onclose_ = function()
+{
+    endTest();
+}
+
+function timeoutCallback()
+{
+    debug('Timed out (state = ' + ws.readyState + ')');
+    timedOut = true;
+    endTest();
+}
+
+var timeoutID = setTimeout(timeoutCallback, 3000);
+
+</script>
+<script src=""
+</body>
+</html>

Copied: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-null-char-in-status_wsh.py (from rev 199433, releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-prepended-null_wsh.py) (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-null-char-in-status_wsh.py	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-null-char-in-status_wsh.py	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,50 @@
+# Copyright (C) Research In Motion Limited 2011. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
+# following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
+# disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
+# following disclaimer in the documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS “AS IS” AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+# APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+import time
+from mod_pywebsocket import stream
+from mod_pywebsocket.handshake.hybi import compute_accept
+
+
+def web_socket_do_extra_handshake(request):
+    # This simulates a broken server that sends a WebSocket frame before the
+    # handshake, and more frames afterwards.  It is important that if this
+    # happens the client does not buffer all the frames as the server continues
+    # to send more data - it should abort after reading a reasonable number of
+    # bytes (set arbitrarily to 1024).
+
+    msg = 'HTTP/1.1 101 Switching \0Protocols\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 += '\r\n'
+    request.connection.write(msg)
+    # continue writing data until the client disconnects
+    while True:
+        time.sleep(1)
+        numFrames = 1024 / len(frame) # write over 1024 bytes including the above handshake
+        for i in range(0, numFrames):
+            request.connection.write(frame)
+
+
+def web_socket_transfer_data(request):
+    pass

Modified: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-prepended-null_wsh.py (199433 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-prepended-null_wsh.py	2016-04-13 08:47:20 UTC (rev 199433)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-fail-by-prepended-null_wsh.py	2016-04-13 08:52:20 UTC (rev 199434)
@@ -19,22 +19,13 @@
 # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-
 import time
 from mod_pywebsocket import stream
 from mod_pywebsocket.handshake.hybi import compute_accept
 
-
 def web_socket_do_extra_handshake(request):
-    # This simulates a broken server that sends a WebSocket frame before the
-    # handshake, and more frames afterwards.  It is important that if this
-    # happens the client does not buffer all the frames as the server continues
-    # to send more data - it should abort after reading a reasonable number of
-    # bytes (set arbitrarily to 1024).
-    frame = stream.create_text_frame('\0Frame-contains-thirty-two-bytes')
 
-    msg = frame
-    msg += 'HTTP/1.1 101 Switching Protocols\r\n'
+    msg = '\0HTTP/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]
@@ -47,6 +38,5 @@
         for i in range(0, numFrames):
             request.connection.write(frame)
 
-
 def web_socket_transfer_data(request):
     pass

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-ok-with-http-version-beyond-1_1-expected.txt (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-ok-with-http-version-beyond-1_1-expected.txt	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-ok-with-http-version-beyond-1_1-expected.txt	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,9 @@
+Test whether WebSocket handshake is OK with if server sends status line with http version beyond 1.1.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS handshake_success is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-ok-with-http-version-beyond-1_1.html (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-ok-with-http-version-beyond-1_1.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-ok-with-http-version-beyond-1_1.html	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <script src=""
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+    description("Test whether WebSocket handshake is OK with if server sends status line with http version beyond 1.1.");
+
+    window.jsTestIsAsync = true;
+
+    var url = ""
+    var handshake_success = false;
+    var ws = new WebSocket(url);
+    var closeEvent;
+
+    function endTest() {
+        clearTimeout(timeoutID);
+        shouldBeTrue("handshake_success");
+        finishJSTest();
+    }
+    ws._onopen_ = function() {
+        handshake_success = true;
+        ws.close();
+    };
+
+    ws._onclose_ = function () {
+        endTest();
+    };
+    
+    var timeoutID = setTimeout("endTest()", 2000);
+</script>
+<script src=""
+</body>
+</html>
\ No newline at end of file

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-ok-with-http-version-beyond-1_1_wsh.py (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-ok-with-http-version-beyond-1_1_wsh.py	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/handshake-ok-with-http-version-beyond-1_1_wsh.py	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,17 @@
+from mod_pywebsocket import handshake
+from mod_pywebsocket import stream
+from mod_pywebsocket.handshake.hybi import compute_accept
+
+
+def web_socket_do_extra_handshake(request):
+    message = 'HTTP/3.0 101 Switching Protocols\r\n'
+    message += 'Upgrade: websocket\r\n'
+    message += 'Connection: Upgrade\r\n'
+    message += 'Sec-WebSocket-Accept: %s\r\n' % compute_accept(request.headers_in['Sec-WebSocket-Key'])[0]
+    message += '\r\n'
+    request.connection.write(message)
+    raise handshake.AbortedByUserException('Abort the connection') # Prevents pywebsocket from sending its own handshake message.
+
+
+def web_socket_transfer_data(request):
+    pass

Added: releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/resources/status-404-without-body.php (0 => 199434)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/resources/status-404-without-body.php	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/http/tests/websocket/tests/hybi/resources/status-404-without-body.php	2016-04-13 08:52:20 UTC (rev 199434)
@@ -0,0 +1,4 @@
+<?php
+    header('http/1.1 404 Not Found');
+    exit();
+?>

Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog (199433 => 199434)


--- releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog	2016-04-13 08:47:20 UTC (rev 199433)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog	2016-04-13 08:52:20 UTC (rev 199434)
@@ -1,3 +1,29 @@
+2016-03-22  John Wilander  <wilan...@apple.com>
+
+        Restrict WebSockets header parsing according to RFC6455 and RFC7230. Based on Lamarque V. Souza's original patch.
+        https://bugs.webkit.org/show_bug.cgi?id=82714
+
+        Reviewed by Brent Fulgham.
+
+        Tests: http/tests/websocket/tests/hybi/error-event-ready-state-non-existent-url-with-server-responding-404.html
+               http/tests/websocket/tests/hybi/handshake-fail-by-invalid-http-version.html
+               http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-accept.html
+               http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-extensions.html
+               http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-header-value-sec-websocket-protocol.html
+               http/tests/websocket/tests/hybi/handshake-fail-by-non-ascii-status-line.html
+               http/tests/websocket/tests/hybi/handshake-fail-by-null-char-in-status.html
+               http/tests/websocket/tests/hybi/handshake-ok-with-http-version-beyond-1_1.html
+
+        * Modules/websockets/WebSocketHandshake.cpp:
+        (WebCore::WebSocketHandshake::httpURLForAuthenticationAndCookies):
+        (WebCore::headerHasValidHTTPVersion):
+            - Check for HTTP version 1.1 and above.
+        (WebCore::WebSocketHandshake::readStatusLine):
+            - Only allow ASCII characters in status line.
+            - Only allow HTTP version 1.1 and above in status line.
+        (WebCore::WebSocketHandshake::readHTTPHeaders):
+            - Only allow ASCII characters in values for new HTTP headers.
+
 2016-03-22  Alex Christensen  <achristen...@webkit.org>
 
         Add null check in CachedResourceLoader::determineRevalidationPolicy

Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/websockets/WebSocketHandshake.cpp (199433 => 199434)


--- releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/websockets/WebSocketHandshake.cpp	2016-04-13 08:47:20 UTC (rev 199433)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/Modules/websockets/WebSocketHandshake.cpp	2016-04-13 08:52:20 UTC (rev 199434)
@@ -47,6 +47,7 @@
 #include "ResourceRequest.h"
 #include "ScriptExecutionContext.h"
 #include "SecurityOrigin.h"
+#include <wtf/ASCIICType.h>
 #include <wtf/CryptographicallyRandomNumber.h>
 #include <wtf/MD5.h>
 #include <wtf/SHA1.h>
@@ -56,6 +57,7 @@
 #include <wtf/text/Base64.h>
 #include <wtf/text/CString.h>
 #include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringView.h>
 #include <wtf/text/WTFString.h>
 #include <wtf/unicode/CharacterNames.h>
 
@@ -390,6 +392,31 @@
     return url;
 }
 
+// https://tools.ietf.org/html/rfc6455#section-4.1
+// "The HTTP version MUST be at least 1.1."
+static inline bool headerHasValidHTTPVersion(const String& httpVersionString, const size_t headerLength)
+{
+    const size_t posOfHttp = httpVersionString.find("HTTP/");
+    if (posOfHttp == notFound)
+        return false;
+
+    // Check that there is a version number which should be three characters after "HTTP/"
+    const size_t posOfHttpVersionNumberString = posOfHttp + 5;
+    if (posOfHttpVersionNumberString + 3 >= headerLength)
+        return false;
+
+    // Check that the version number is 1.1 or above
+    bool versionNumberIsOneDotOneOrAbove = false;
+    if (httpVersionString.characterAt(posOfHttpVersionNumberString + 1) == '.') {
+        UChar majorVersion = httpVersionString.characterAt(posOfHttpVersionNumberString);
+        UChar minorVersion = httpVersionString.characterAt(posOfHttpVersionNumberString + 2);
+        if ((majorVersion == '1' && minorVersion >= '1' && minorVersion <= '9')
+            || (majorVersion > '1' && majorVersion <= '9' && minorVersion >= '0' && minorVersion <= '9'))
+            versionNumberIsOneDotOneOrAbove = true;
+    }
+    return versionNumberIsOneDotOneOrAbove;
+}
+
 // Returns the header length (including "\r\n"), or -1 if we have not received enough data yet.
 // If the line is malformed or the status code is not a 3-digit number,
 // statusCode and statusText will be set to -1 and a null string, respectively.
@@ -419,6 +446,9 @@
             // does, so we'll just treat this as an error.
             m_failureReason = "Status line contains embedded null";
             return p + 1 - header;
+        } else if (!isASCII(*p)) {
+            m_failureReason = "Status line contains non-ASCII character";
+            return p + 1 - header;
         } else if (*p == '\n')
             break;
     }
@@ -443,6 +473,12 @@
         return lineLength;
     }
 
+    String httpVersionString(header, space1 - header);
+    if (!headerHasValidHTTPVersion(httpVersionString, headerLength)) {
+        m_failureReason = "Invalid HTTP version string: " + httpVersionString;
+        return lineLength;
+    }
+
     String statusCodeString(space1 + 1, space2 - space1 - 1);
     if (statusCodeString.length() != 3) // Status code must consist of three digits.
         return lineLength;
@@ -478,9 +514,19 @@
         if (name.isEmpty())
             break;
 
+        // https://tools.ietf.org/html/rfc7230#section-3.2.4
+        // "Newly defined header fields SHOULD limit their field values to US-ASCII octets."
+        if ((equalLettersIgnoringASCIICase(name, "sec-websocket-extensions")
+            || equalLettersIgnoringASCIICase(name, "sec-websocket-accept")
+            || equalLettersIgnoringASCIICase(name, "sec-websocket-protocol"))
+            && !value.containsOnlyASCII()) {
+            m_failureReason = name + " header value should only contain ASCII characters";
+            return nullptr;
+        }
+        
         if (equalLettersIgnoringASCIICase(name, "sec-websocket-extensions")) {
             if (sawSecWebSocketExtensionsHeaderField) {
-                m_failureReason = "The Sec-WebSocket-Extensions header MUST NOT appear more than once in an HTTP response";
+                m_failureReason = "The Sec-WebSocket-Extensions header must not appear more than once in an HTTP response";
                 return nullptr;
             }
             if (!m_extensionDispatcher.processHeaderValue(value)) {
@@ -490,14 +536,14 @@
             sawSecWebSocketExtensionsHeaderField = true;
         } else if (equalLettersIgnoringASCIICase(name, "sec-websocket-accept")) {
             if (sawSecWebSocketAcceptHeaderField) {
-                m_failureReason = "The Sec-WebSocket-Accept header MUST NOT appear more than once in an HTTP response";
+                m_failureReason = "The Sec-WebSocket-Accept header must not appear more than once in an HTTP response";
                 return nullptr;
             }
             m_serverHandshakeResponse.addHTTPHeaderField(name, value);
             sawSecWebSocketAcceptHeaderField = true;
         } else if (equalLettersIgnoringASCIICase(name, "sec-websocket-protocol")) {
             if (sawSecWebSocketProtocolHeaderField) {
-                m_failureReason = "The Sec-WebSocket-Protocol header MUST NOT appear more than once in an HTTP response";
+                m_failureReason = "The Sec-WebSocket-Protocol header must not appear more than once in an HTTP response";
                 return nullptr;
             }
             m_serverHandshakeResponse.addHTTPHeaderField(name, value);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to