Title: [204127] trunk
Revision
204127
Author
commit-qu...@webkit.org
Date
2016-08-04 11:07:45 -0700 (Thu, 04 Aug 2016)

Log Message

Content Blocker cannot block WebSocket connections
https://bugs.webkit.org/show_bug.cgi?id=160159

Patch by Alex Christensen <achristen...@webkit.org> on 2016-08-04
Reviewed by Brady Eidson.

Source/WebCore:

Tests: http/tests/websocket/tests/hybi/contentextensions/block-cookies-worker.php
       http/tests/websocket/tests/hybi/contentextensions/block-cookies.php
       http/tests/websocket/tests/hybi/contentextensions/block-worker.html
       http/tests/websocket/tests/hybi/contentextensions/block.html
       http/tests/websocket/tests/hybi/contentextensions/display-none-worker.html
       http/tests/websocket/tests/hybi/contentextensions/display-none.html
       http/tests/websocket/tests/hybi/contentextensions/upgrade-worker.html
       http/tests/websocket/tests/hybi/contentextensions/upgrade.html

* Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp:
(WebCore::ThreadableWebSocketChannelClientWrapper::didReceiveMessageError):
(WebCore::ThreadableWebSocketChannelClientWrapper::didUpgradeURL):
(WebCore::ThreadableWebSocketChannelClientWrapper::suspend):
* Modules/websockets/ThreadableWebSocketChannelClientWrapper.h:
* Modules/websockets/WebSocket.cpp:
(WebCore::WebSocket::didClose):
(WebCore::WebSocket::didUpgradeURL):
(WebCore::WebSocket::getFramingOverhead):
* Modules/websockets/WebSocket.h:

Added didUpgradeURL to WebSocketChannelClient so the WebSocketChannel can tell the WebSocket
that it has upgraded a ws: url to a wss: url.

* Modules/websockets/WebSocketChannel.cpp:
(WebCore::WebSocketChannel::~WebSocketChannel):
(WebCore::WebSocketChannel::connect):

If content extensions are being used, run the URL through the content extension and apply its actions
before connecting the WebSocket.  This is done in WebSocketChannel instead of WebSocket like the CSP checks
because we need access to the Document in order to get access to the main document's URL for if-domain and
unless-domain rules, and to apply any display:none css to the Document.

(WebCore::WebSocketChannel::disconnect):
* Modules/websockets/WebSocketChannelClient.h:
(WebCore::WebSocketChannelClient::~WebSocketChannelClient):
(WebCore::WebSocketChannelClient::WebSocketChannelClient):
(WebCore::WebSocketChannelClient::didConnect):
(WebCore::WebSocketChannelClient::didReceiveMessage):
(WebCore::WebSocketChannelClient::didReceiveBinaryData):
(WebCore::WebSocketChannelClient::didReceiveMessageError):
(WebCore::WebSocketChannelClient::didUpdateBufferedAmount):
(WebCore::WebSocketChannelClient::didStartClosingHandshake):
(WebCore::WebSocketChannelClient::didClose):

Made WebSocketChannelClient purely virtual to avoid accidentally making an implementation that is missing functionality.

(WebCore::WebSocketChannelClient::didUpgradeURL): Added.
* Modules/websockets/WebSocketHandshake.cpp:
(WebCore::WebSocketHandshake::getExpectedWebSocketAccept):
(WebCore::WebSocketHandshake::WebSocketHandshake):
(WebCore::WebSocketHandshake::clientOrigin):
(WebCore::WebSocketHandshake::clientLocation):
(WebCore::WebSocketHandshake::clientHandshakeMessage):

Only put cookies on the WebSocket's handshake if we are allowed to use cookies.

(WebCore::WebSocketHandshake::clientHandshakeRequest):

A WebSocketHandshake always has a Document* for its ScriptExecutionContext, so I replaced m_context with
m_document and removed a suspicious-looking check for is<Document> that turned out to not be suspicious at all.

(WebCore::WebSocketHandshake::reset):
(WebCore::WebSocketHandshake::clearDocument):
(WebCore::WebSocketHandshake::readServerHandshake):
(WebCore::WebSocketHandshake::clearScriptExecutionContext): Deleted.
* Modules/websockets/WebSocketHandshake.h:
* Modules/websockets/WorkerThreadableWebSocketChannel.cpp:
(WebCore::WorkerThreadableWebSocketChannel::Peer::didReceiveMessageError):
(WebCore::WorkerThreadableWebSocketChannel::Peer::didUpgradeURL):
(WebCore::WorkerThreadableWebSocketChannel::Bridge::Bridge):
* Modules/websockets/WorkerThreadableWebSocketChannel.h:
* contentextensions/ContentExtensionActions.h:

Before this change we would pass a ResourceRequest as a parameter to the content extension engine.
The ResourceRequest would be used to get the URL, and it would be modified by possibly disabling cookies
or making the URL https.  Any display:none CSS rules added were put into the Document through the DocumentLoader.
The only information it needed to return was whether the load was blocked.
To make content extensions work with WebSockets, we need to pass a URL as a parameter instead of a ResourceRequest
because there is no ResourceRequest with WebSockets, only a URL.  We can still put CSS rules in through the DocumentLoader,
but the rest of the actions need to be returned through the return value, which is then processed by the callers.
BlockedStatus is now a struct containing a set of actions to apply, and applyBlockedStatusToRequest is a helper function
that applies the actions to the ResourceRequests we have at all previously existing call sites of processContentExtensionRulesForLoad.

* contentextensions/ContentExtensionsBackend.cpp:
(WebCore::ContentExtensions::ContentExtensionsBackend::globalDisplayNoneStyleSheet):
(WebCore::ContentExtensions::ContentExtensionsBackend::processContentExtensionRulesForLoad):
(WebCore::ContentExtensions::ContentExtensionsBackend::displayNoneCSSRule):
(WebCore::ContentExtensions::applyBlockedStatusToRequest):
* contentextensions/ContentExtensionsBackend.h:
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::loadResource):

Here, we also only had a URL.  Before, we were making a ResourceRequest from the URL just for the content extension engine,
but now we can just pass the URL.

* loader/FrameLoader.cpp:
(WebCore::FrameLoader::loadResourceSynchronously):
* loader/PingLoader.cpp:
(WebCore::processContentExtensionRulesForLoad):
(WebCore::PingLoader::loadImage):
(WebCore::PingLoader::sendPing):
(WebCore::PingLoader::sendViolationReport):
* loader/ResourceLoader.cpp:
(WebCore::ResourceLoader::willSendRequestInternal):
* loader/cache/CachedResourceLoader.cpp:
(WebCore::CachedResourceLoader::requestResource):
* page/UserContentProvider.cpp:
(WebCore::contentExtensionsEnabled):
(WebCore::UserContentProvider::processContentExtensionRulesForLoad):
(WebCore::UserContentProvider::actionsForResourceLoad):
* page/UserContentProvider.h:

LayoutTests:

* http/tests/contentextensions/make-https-expected.txt:
Rebased to reflect slight change in console logged messages which contain the same information.
* http/tests/websocket/tests/hybi/contentextensions: Added.
* http/tests/websocket/tests/hybi/contentextensions/block-cookies-expected.txt: Added.
* http/tests/websocket/tests/hybi/contentextensions/block-cookies-worker-expected.txt: Added.
* http/tests/websocket/tests/hybi/contentextensions/block-cookies-worker.php: Added.
* http/tests/websocket/tests/hybi/contentextensions/block-cookies-worker.php.json: Added.
* http/tests/websocket/tests/hybi/contentextensions/block-cookies.php: Copied from LayoutTests/http/tests/websocket/tests/hybi/httponly-cookie.pl.
* http/tests/websocket/tests/hybi/contentextensions/block-cookies.php.json: Added.
* http/tests/websocket/tests/hybi/contentextensions/block-expected.txt: Added.
* http/tests/websocket/tests/hybi/contentextensions/block-worker-expected.txt: Added.
* http/tests/websocket/tests/hybi/contentextensions/block-worker.html: Added.
* http/tests/websocket/tests/hybi/contentextensions/block-worker.html.json: Added.
* http/tests/websocket/tests/hybi/contentextensions/block.html: Added.
* http/tests/websocket/tests/hybi/contentextensions/block.html.json: Added.
* http/tests/websocket/tests/hybi/contentextensions/display-none-expected.txt: Added.
* http/tests/websocket/tests/hybi/contentextensions/display-none-worker-expected.txt: Added.
* http/tests/websocket/tests/hybi/contentextensions/display-none-worker.html: Added.
* http/tests/websocket/tests/hybi/contentextensions/display-none-worker.html.json: Added.
* http/tests/websocket/tests/hybi/contentextensions/display-none.html: Added.
* http/tests/websocket/tests/hybi/contentextensions/display-none.html.json: Added.
* http/tests/websocket/tests/hybi/contentextensions/resources: Added.
* http/tests/websocket/tests/hybi/contentextensions/resources/block-cookies-worker.js: Added.
* http/tests/websocket/tests/hybi/contentextensions/resources/block-worker.js: Added.
* http/tests/websocket/tests/hybi/contentextensions/resources/display-none-worker.js: Added.
* http/tests/websocket/tests/hybi/contentextensions/resources/echo-cookie_wsh.py: Copied from LayoutTests/http/tests/websocket/tests/hybi/echo-cookie_wsh.py.
* http/tests/websocket/tests/hybi/contentextensions/resources/echo_wsh.py: Added.
* http/tests/websocket/tests/hybi/contentextensions/resources/upgrade-worker.js: Added.
* http/tests/websocket/tests/hybi/contentextensions/upgrade-expected.txt: Added.
* http/tests/websocket/tests/hybi/contentextensions/upgrade-worker-expected.txt: Added.
* http/tests/websocket/tests/hybi/contentextensions/upgrade-worker.html: Added.
* http/tests/websocket/tests/hybi/contentextensions/upgrade-worker.html.json: Added.
* http/tests/websocket/tests/hybi/contentextensions/upgrade.html: Added.
* http/tests/websocket/tests/hybi/contentextensions/upgrade.html.json: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (204126 => 204127)


--- trunk/LayoutTests/ChangeLog	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/LayoutTests/ChangeLog	2016-08-04 18:07:45 UTC (rev 204127)
@@ -1,3 +1,45 @@
+2016-08-04  Alex Christensen  <achristen...@webkit.org>
+
+        Content Blocker cannot block WebSocket connections
+        https://bugs.webkit.org/show_bug.cgi?id=160159
+
+        Reviewed by Brady Eidson.
+
+        * http/tests/contentextensions/make-https-expected.txt:
+        Rebased to reflect slight change in console logged messages which contain the same information.
+        * http/tests/websocket/tests/hybi/contentextensions: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/block-cookies-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/block-cookies-worker-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/block-cookies-worker.php: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/block-cookies-worker.php.json: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/block-cookies.php: Copied from LayoutTests/http/tests/websocket/tests/hybi/httponly-cookie.pl.
+        * http/tests/websocket/tests/hybi/contentextensions/block-cookies.php.json: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/block-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/block-worker-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/block-worker.html: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/block-worker.html.json: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/block.html: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/block.html.json: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/display-none-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/display-none-worker-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/display-none-worker.html: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/display-none-worker.html.json: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/display-none.html: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/display-none.html.json: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/resources: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/resources/block-cookies-worker.js: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/resources/block-worker.js: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/resources/display-none-worker.js: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/resources/echo-cookie_wsh.py: Copied from LayoutTests/http/tests/websocket/tests/hybi/echo-cookie_wsh.py.
+        * http/tests/websocket/tests/hybi/contentextensions/resources/echo_wsh.py: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/resources/upgrade-worker.js: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/upgrade-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/upgrade-worker-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/upgrade-worker.html: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/upgrade-worker.html.json: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/upgrade.html: Added.
+        * http/tests/websocket/tests/hybi/contentextensions/upgrade.html.json: Added.
+
 2016-08-04  Chris Dumez  <cdu...@apple.com>
 
         [[Prototype]] property of an interface object for a callback interface must be the Object.prototype object

Modified: trunk/LayoutTests/TestExpectations (204126 => 204127)


--- trunk/LayoutTests/TestExpectations	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/LayoutTests/TestExpectations	2016-08-04 18:07:45 UTC (rev 204127)
@@ -696,6 +696,7 @@
 
 # Content extensions are Mac-WK2-only for now
 http/tests/contentextensions [ Skip ]
+http/tests/websocket/tests/hybi/contentextensions [ Skip ]
 
 webkit.org/b/149072 svg/animations/svgboolean-animation-1.html [ Pass Failure ]
 

Modified: trunk/LayoutTests/http/tests/contentextensions/make-https-expected.txt (204126 => 204127)


--- trunk/LayoutTests/http/tests/contentextensions/make-https-expected.txt	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/LayoutTests/http/tests/contentextensions/make-https-expected.txt	2016-08-04 18:07:45 UTC (rev 204127)
@@ -4,13 +4,13 @@
 http://127.0.0.1:8000/try_to_promote - didFinishLoading
 http://127.0.0.1/nope - willSendRequest <NSURLRequest URL http://127.0.0.1/nope, main document URL http://127.0.0.1:8000/contentextensions/make-https.html, http method GET> redirectResponse (null)
 http://127.0.0.1/nope - didFailLoadingWithError: <NSError domain NSURLErrorDomain, code -1004, failing URL "http://127.0.0.1/nope">
-CONSOLE MESSAGE: line 30: Content blocker promoted URL from http://127.0.0.1/promote to https://127.0.0.1/promote
+CONSOLE MESSAGE: line 30: Content blocker promoted URL from http://127.0.0.1/promote to https
 https://127.0.0.1/promote - willSendRequest <NSURLRequest URL https://127.0.0.1/promote, main document URL http://127.0.0.1:8000/contentextensions/make-https.html, http method GET> redirectResponse (null)
 https://127.0.0.1/promote - didFailLoadingWithError: <NSError domain NSURLErrorDomain, code -1004, failing URL "https://127.0.0.1/promote">
-CONSOLE MESSAGE: line 30: Content blocker promoted URL from http://127.0.0.1/promote to https://127.0.0.1/promote
+CONSOLE MESSAGE: line 30: Content blocker promoted URL from http://127.0.0.1/promote to https
 https://127.0.0.1/promote - willSendRequest <NSURLRequest URL https://127.0.0.1/promote, main document URL http://127.0.0.1:8000/contentextensions/make-https.html, http method GET> redirectResponse (null)
 https://127.0.0.1/promote - didFailLoadingWithError: <NSError domain NSURLErrorDomain, code -1004, failing URL "https://127.0.0.1/promote">
-CONSOLE MESSAGE: line 30: Content blocker promoted URL from http://127.0.0.1/promote to https://127.0.0.1/promote
+CONSOLE MESSAGE: line 30: Content blocker promoted URL from http://127.0.0.1/promote to https
 https://127.0.0.1/promote - willSendRequest <NSURLRequest URL https://127.0.0.1/promote, main document URL http://127.0.0.1:8000/contentextensions/make-https.html, http method GET> redirectResponse (null)
 https://127.0.0.1/promote - didFailLoadingWithError: <NSError domain NSURLErrorDomain, code -1004, failing URL "https://127.0.0.1/promote">
 http://127.0.0.1:443/try_to_promote - willSendRequest <NSURLRequest URL http://127.0.0.1:443/try_to_promote, main document URL http://127.0.0.1:8000/contentextensions/make-https.html, http method GET> redirectResponse (null)
@@ -17,7 +17,7 @@
 http://127.0.0.1:443/try_to_promote - didFailLoadingWithError: <NSError domain NSURLErrorDomain, code -1004, failing URL "http://127.0.0.1:443/try_to_promote">
 http://127.0.0.1:1443/try_to_promote - willSendRequest <NSURLRequest URL http://127.0.0.1:1443/try_to_promote, main document URL http://127.0.0.1:8000/contentextensions/make-https.html, http method GET> redirectResponse (null)
 http://127.0.0.1:1443/try_to_promote - didFailLoadingWithError: <NSError domain NSURLErrorDomain, code -1004, failing URL "http://127.0.0.1:1443/try_to_promote">
-CONSOLE MESSAGE: line 30: Content blocker promoted URL from http://promote/ to https://promote/
+CONSOLE MESSAGE: line 30: Content blocker promoted URL from http://promote/ to https
 https://promote/ - willSendRequest <NSURLRequest URL https://promote/, main document URL http://127.0.0.1:8000/contentextensions/make-https.html, http method GET> redirectResponse (null)
 Blocked access to external URL https://promote/
 https://promote/ - didFailLoadingWithError: <NSError domain NSURLErrorDomain, code -999>

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies-expected.txt (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies-expected.txt	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,10 @@
+Tests that WebSocket sends no cookies when they are blocked.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+WebSocket open
+WebSocket message (no cookies)
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies-worker-expected.txt (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies-worker-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies-worker-expected.txt	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,10 @@
+Tests that WebSocket sends no cookies when they are blocked.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+worker WebSocket open
+PASS worker WebSocket message (no cookies)
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies-worker.php (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies-worker.php	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies-worker.php	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,43 @@
+<?php
+if ( isset($_GET['clear'])) {
+    header("Content-Type: text/plain");
+    setcookie("WK-websocket-test", "0", time()-1);
+    setcookie("WK-websocket-test-httponly", "0", time()-1, "", "", false, true);
+    echo("Cookies are cleared.");
+    return;
+} else {
+    header("Content-Type: text/html");
+    setcookie("WK-websocket-test", "1");
+    setcookie("WK-websocket-test-httponly", "1", time()+3600, "", "", false, true);
+    header("Set-Cookie: WK-websocket-test=1");
+    header("Set-Cookie: WK-websocket-test-httponly=1; HttpOnly");
+}
+?>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<p>Tests that WebSocket sends no cookies when they are blocked.</p>
+<p>On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".</p>
+<div id="console"></div>
+<script>
+window.jsTestIsAsync = true;
+
+function startsWith(str, prefix) {
+    return str.indexOf(prefix) == 0;
+}
+
+var worker = new Worker("resources/block-cookies-worker.js");
+worker._onmessage_ = function (event)
+{
+    var message = event.data;
+    debug(message);
+    if (startsWith(message, "PASS") || startsWith(message, "FAIL"))
+		finishJSTest();
+};
+
+</script>
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies-worker.php.json (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies-worker.php.json	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies-worker.php.json	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,10 @@
+[
+    {
+        "action": {
+            "type": "block-cookies"
+        },
+        "trigger": {
+            "url-filter": "8880"
+        }
+    }
+]

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies.php (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies.php	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies.php	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,47 @@
+<?php
+if ( isset($_GET['clear'])) {
+    header("Content-Type: text/plain");
+    setcookie("WK-websocket-test", "0", time()-1);
+    setcookie("WK-websocket-test-httponly", "0", time()-1, "", "", false, true);
+    echo("Cookies are cleared.");
+    return;
+} else {
+    header("Content-Type: text/html");
+    setcookie("WK-websocket-test", "1");
+    setcookie("WK-websocket-test-httponly", "1", time()+3600, "", "", false, true);
+    header("Set-Cookie: WK-websocket-test=1");
+    header("Set-Cookie: WK-websocket-test-httponly=1; HttpOnly");
+}
+?>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<p>Tests that WebSocket sends no cookies when they are blocked.</p>
+<p>On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".</p>
+<div id="console"></div>
+<script>
+window.jsTestIsAsync = true;
+
+function clearCookies()
+{
+    var xhr = new XMLHttpRequest();
+    xhr.open("GET", "block-cookies.php?clear=1", false);
+    xhr.send(null);
+}
+
+var ws = new WebSocket("ws://127.0.0.1:8880/websocket/tests/hybi/contentextensions/resources/echo-cookie");
+ws._onopen_ = function() {
+    debug("WebSocket open");
+};
+ws._onmessage_ = function(evt) {
+    debug("WebSocket message (" + evt.data + ")");
+    clearCookies();
+    finishJSTest();
+};
+
+</script>
+<script src=""
+</body>
+</html>
Property changes on: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies.php
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies.php.json (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies.php.json	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-cookies.php.json	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,10 @@
+[
+    {
+        "action": {
+            "type": "block-cookies"
+        },
+        "trigger": {
+            "url-filter": "8880"
+        }
+    }
+]

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-expected.txt (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-expected.txt	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,3 @@
+CONSOLE MESSAGE: line 13: Content blocker prevented frame displaying http://127.0.0.1:8000/websocket/tests/hybi/contentextensions/block.html from loading a resource from ws://localhost:8880/websocket/tests/hybi/contentextensions/resources/echo
+CONSOLE MESSAGE: line 27: onerror
+

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-worker-expected.txt (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-worker-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-worker-expected.txt	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,3 @@
+CONSOLE MESSAGE: Content blocker prevented frame displaying http://127.0.0.1:8000/websocket/tests/hybi/contentextensions/block-worker.html from loading a resource from ws://localhost:8880/websocket/tests/hybi/contentextensions/resources/echo
+CONSOLE MESSAGE: line 21: PASS worker onerror
+

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-worker.html (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-worker.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-worker.html	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,25 @@
+<script>
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+function endTest() {
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+function startsWith(str, prefix) {
+    return str.indexOf(prefix) == 0;
+}
+
+var worker = new Worker("resources/block-worker.js");
+worker._onmessage_ = function (event)
+{
+    var message = event.data;
+    console.log(message);
+    if (startsWith(message, "PASS") || startsWith(message, "FAIL"))
+		endTest();
+};
+</script>

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-worker.html.json (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-worker.html.json	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block-worker.html.json	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,10 @@
+[
+    {
+        "action": {
+            "type": "block"
+        },
+        "trigger": {
+            "url-filter": "8880"
+        }
+    }
+]

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block.html (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block.html	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,36 @@
+<script>
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+function endTest() {
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+var ws = new WebSocket("ws://localhost:8880/websocket/tests/hybi/contentextensions/resources/echo");
+
+ws._onopen_ = function() { 
+    console.log("onopen");
+    ws.send("sent"); 
+}
+ws._onmessage_ = function(message) { 
+    console.log("onmessage " + message.data);
+}
+ws._onclose_ = function() {
+    console.log("onclose");
+    endTest();
+}
+ws._onerror_ = function(ev) { 
+    console.log("onerror"); 
+    endTest(); 
+}
+
+setTimeout(function() { 
+    console.log("timeout"); 
+    endTest();
+}, 3000);
+
+</script>

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block.html.json (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block.html.json	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/block.html.json	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,10 @@
+[
+    {
+        "action": {
+            "type": "block"
+        },
+        "trigger": {
+            "url-filter": "8880"
+        }
+    }
+]

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/display-none-expected.txt (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/display-none-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/display-none-expected.txt	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,4 @@
+CONSOLE MESSAGE: line 18: onopen
+CONSOLE MESSAGE: line 22: onmessage reply sent
+CONSOLE MESSAGE: line 25: onclose
+This should not be hidden.

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/display-none-worker-expected.txt (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/display-none-worker-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/display-none-worker-expected.txt	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,4 @@
+CONSOLE MESSAGE: line 23: worker onopen
+CONSOLE MESSAGE: line 23: worker onmessage reply sent
+CONSOLE MESSAGE: line 23: PASS worker onclose
+This should not be hidden.

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/display-none-worker.html (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/display-none-worker.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/display-none-worker.html	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,27 @@
+<div id="should_be_hidden">This should be hidden by a css selector from the content extension.</div>
+<div id="should_not_be_hidden">This should not be hidden.</div>
+<script>
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+function endTest() {
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+function startsWith(str, prefix) {
+    return str.indexOf(prefix) == 0;
+}
+
+var worker = new Worker("resources/display-none-worker.js");
+worker._onmessage_ = function (event)
+{
+    var message = event.data;
+    console.log(message);
+    if (startsWith(message, "PASS") || startsWith(message, "FAIL"))
+		endTest();
+};
+</script>

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/display-none-worker.html.json (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/display-none-worker.html.json	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/display-none-worker.html.json	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,11 @@
+[
+    {
+        "action": {
+            "type": "css-display-none",
+            "selector": "#should_be_hidden"
+        },
+        "trigger": {
+            "url-filter": "8880"
+        }
+    }
+]

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/display-none.html (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/display-none.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/display-none.html	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,38 @@
+<div id="should_be_hidden">This should be hidden by a css selector from the content extension.</div>
+<div id="should_not_be_hidden">This should not be hidden.</div>
+<script>
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+function endTest() {
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+var ws = new WebSocket("ws://localhost:8880/websocket/tests/hybi/contentextensions/resources/echo");
+
+ws._onopen_ = function() { 
+    console.log("onopen");
+    ws.send("sent"); 
+}
+ws._onmessage_ = function(message) { 
+    console.log("onmessage " + message.data);
+}
+ws._onclose_ = function() {
+    console.log("onclose");
+    endTest();
+}
+ws._onerror_ = function() { 
+    console.log("onerror"); 
+    endTest(); 
+}
+
+setTimeout(function() { 
+    console.log("timeout"); 
+    endTest();
+}, 3000);
+
+</script>

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/display-none.html.json (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/display-none.html.json	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/display-none.html.json	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,11 @@
+[
+    {
+        "action": {
+            "type": "css-display-none",
+            "selector": "#should_be_hidden"
+        },
+        "trigger": {
+            "url-filter": "8880"
+        }
+    }
+]

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/resources/block-cookies-worker.js (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/resources/block-cookies-worker.js	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/resources/block-cookies-worker.js	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,15 @@
+function clearCookies()
+{
+    var xhr = new XMLHttpRequest();
+    xhr.open("GET", "block-cookies-worker.php?clear=1", false);
+    xhr.send(null);
+}
+
+var ws = new WebSocket("ws://127.0.0.1:8880/websocket/tests/hybi/contentextensions/resources/echo-cookie");
+ws._onopen_ = function() {
+    postMessage("worker WebSocket open");
+};
+ws._onmessage_ = function(evt) {
+    clearCookies();
+    postMessage("PASS worker WebSocket message (" + evt.data + ")");
+};

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/resources/block-worker.js (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/resources/block-worker.js	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/resources/block-worker.js	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,18 @@
+var ws = new WebSocket("ws://localhost:8880/websocket/tests/hybi/contentextensions/resources/echo");
+
+ws._onopen_ = function() { 
+    postMessage("FAIL worker onopen");
+}
+ws._onmessage_ = function(message) { 
+    postMessage("FAIL worker onmessage " + message.data);
+}
+ws._onclose_ = function() {
+    postMessage("FAIL worker onclose");
+}
+ws._onerror_ = function() { 
+    postMessage("PASS worker onerror");
+}
+
+setTimeout(function() { 
+    postMessage("FAIL worker timeout"); 
+}, 3000);

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/resources/display-none-worker.js (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/resources/display-none-worker.js	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/resources/display-none-worker.js	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,19 @@
+var ws = new WebSocket("ws://localhost:8880/websocket/tests/hybi/contentextensions/resources/echo");
+
+ws._onopen_ = function() { 
+    postMessage("worker onopen");
+    ws.send("sent"); 
+}
+ws._onmessage_ = function(message) { 
+    postMessage("worker onmessage " + message.data);
+}
+ws._onclose_ = function() {
+    postMessage("PASS worker onclose");
+}
+ws._onerror_ = function() { 
+    postMessage("FAIL worker onerror");
+}
+
+setTimeout(function() { 
+    postMessage("FAIL worker timeout"); 
+}, 3000);

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/resources/echo-cookie_wsh.py (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/resources/echo-cookie_wsh.py	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/resources/echo-cookie_wsh.py	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,41 @@
+# Copyright (C) 2010 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * 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.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+# OWNER OR 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.
+
+
+from mod_pywebsocket import msgutil
+
+
+def web_socket_do_extra_handshake(request):
+    pass
+
+
+def web_socket_transfer_data(request):
+    try:
+        msgutil.send_message(request,  "cookie:" + request.headers_in['Cookie'])
+    except:
+        msgutil.send_message(request,  "no cookies")
\ No newline at end of file

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/resources/echo_wsh.py (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/resources/echo_wsh.py	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/resources/echo_wsh.py	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,9 @@
+from mod_pywebsocket import msgutil
+
+def web_socket_do_extra_handshake(request):
+    pass
+
+def web_socket_transfer_data(request):
+    for unused in range(1):
+        message = msgutil.receive_message(request)
+        msgutil.send_message(request, "reply " + message)

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/resources/upgrade-worker.js (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/resources/upgrade-worker.js	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/resources/upgrade-worker.js	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,18 @@
+var ws = new WebSocket("ws://127.0.0.1/websocket/tests/hybi/simple");
+
+ws._onopen_ = function() { 
+    postMessage("FAIL worker onopen");
+}
+ws._onmessage_ = function(message) { 
+    postMessage("FAIL worker onmessage " + message.data);
+}
+ws._onclose_ = function() {
+    postMessage("PASS worker onclose url " + ws.url);
+}
+ws._onerror_ = function() { 
+    postMessage("FAIL worker onerror");
+}
+
+setTimeout(function() { 
+    postMessage("FAIL worker timeout"); 
+}, 3000);

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/upgrade-expected.txt (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/upgrade-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/upgrade-expected.txt	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,5 @@
+CONSOLE MESSAGE: line 14: Content blocker promoted URL from ws://127.0.0.1/websocket/tests/hybi/simple to wss
+CONSOLE MESSAGE: WebSocket network error: The operation couldn’t be completed. Connection refused
+CONSOLE MESSAGE: line 24: onclose
+CONSOLE MESSAGE: line 9: new url: wss://127.0.0.1/websocket/tests/hybi/simple
+

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/upgrade-worker-expected.txt (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/upgrade-worker-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/upgrade-worker-expected.txt	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,4 @@
+CONSOLE MESSAGE: Content blocker promoted URL from ws://127.0.0.1/websocket/tests/hybi/simple to wss
+CONSOLE MESSAGE: WebSocket network error: The operation couldn’t be completed. Connection refused
+CONSOLE MESSAGE: line 21: PASS worker onclose url wss://127.0.0.1/websocket/tests/hybi/simple
+

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/upgrade-worker.html (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/upgrade-worker.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/upgrade-worker.html	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,25 @@
+<script>
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+function endTest() {
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+function startsWith(str, prefix) {
+    return str.indexOf(prefix) == 0;
+}
+
+var worker = new Worker("resources/upgrade-worker.js");
+worker._onmessage_ = function (event)
+{
+    var message = event.data;
+    console.log(message);
+    if (startsWith(message, "PASS") || startsWith(message, "FAIL"))
+		endTest();
+};
+</script>

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/upgrade-worker.html.json (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/upgrade-worker.html.json	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/upgrade-worker.html.json	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,10 @@
+[
+    {
+        "action": {
+            "type": "make-https"
+        },
+        "trigger": {
+            "url-filter": "simple"
+        }
+    }
+]

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/upgrade.html (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/upgrade.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/upgrade.html	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,37 @@
+<script>
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+function endTest() {
+    console.log("new url: " + ws.url);
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+var ws = new WebSocket("ws://127.0.0.1/websocket/tests/hybi/simple");
+
+ws._onopen_ = function() { 
+    console.log("onopen");
+    ws.send("sent"); 
+}
+ws._onmessage_ = function(message) { 
+    console.log("onmessage " + message.data);
+}
+ws._onclose_ = function() {
+    console.log("onclose");
+    endTest();
+}
+ws._onerror_ = function(ev) { 
+    console.log("onerror"); 
+    endTest(); 
+}
+
+setTimeout(function() { 
+    console.log("timeout");
+    endTest();
+}, 3000);
+
+</script>

Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/upgrade.html.json (0 => 204127)


--- trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/upgrade.html.json	                        (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/contentextensions/upgrade.html.json	2016-08-04 18:07:45 UTC (rev 204127)
@@ -0,0 +1,10 @@
+[
+    {
+        "action": {
+            "type": "make-https"
+        },
+        "trigger": {
+            "url-filter": "simple"
+        }
+    }
+]

Modified: trunk/LayoutTests/platform/mac-wk2/TestExpectations (204126 => 204127)


--- trunk/LayoutTests/platform/mac-wk2/TestExpectations	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/LayoutTests/platform/mac-wk2/TestExpectations	2016-08-04 18:07:45 UTC (rev 204127)
@@ -440,6 +440,7 @@
 
 # Content Extensions tests must be enabled explicitly on mac-wk2.
 http/tests/contentextensions [ Pass ]
+http/tests/websocket/tests/hybi/contentextensions [ Pass ]
 webkit.org/b/146400 http/tests/contentextensions/character-set-basic-support.html [ Pass Failure ]
 
 # WebKit1-only failure.

Modified: trunk/Source/WebCore/ChangeLog (204126 => 204127)


--- trunk/Source/WebCore/ChangeLog	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/ChangeLog	2016-08-04 18:07:45 UTC (rev 204127)
@@ -1,3 +1,122 @@
+2016-08-04  Alex Christensen  <achristen...@webkit.org>
+
+        Content Blocker cannot block WebSocket connections
+        https://bugs.webkit.org/show_bug.cgi?id=160159
+
+        Reviewed by Brady Eidson.
+
+        Tests: http/tests/websocket/tests/hybi/contentextensions/block-cookies-worker.php
+               http/tests/websocket/tests/hybi/contentextensions/block-cookies.php
+               http/tests/websocket/tests/hybi/contentextensions/block-worker.html
+               http/tests/websocket/tests/hybi/contentextensions/block.html
+               http/tests/websocket/tests/hybi/contentextensions/display-none-worker.html
+               http/tests/websocket/tests/hybi/contentextensions/display-none.html
+               http/tests/websocket/tests/hybi/contentextensions/upgrade-worker.html
+               http/tests/websocket/tests/hybi/contentextensions/upgrade.html
+
+        * Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp:
+        (WebCore::ThreadableWebSocketChannelClientWrapper::didReceiveMessageError):
+        (WebCore::ThreadableWebSocketChannelClientWrapper::didUpgradeURL):
+        (WebCore::ThreadableWebSocketChannelClientWrapper::suspend):
+        * Modules/websockets/ThreadableWebSocketChannelClientWrapper.h:
+        * Modules/websockets/WebSocket.cpp:
+        (WebCore::WebSocket::didClose):
+        (WebCore::WebSocket::didUpgradeURL):
+        (WebCore::WebSocket::getFramingOverhead):
+        * Modules/websockets/WebSocket.h:
+        
+        Added didUpgradeURL to WebSocketChannelClient so the WebSocketChannel can tell the WebSocket
+        that it has upgraded a ws: url to a wss: url.
+        
+        * Modules/websockets/WebSocketChannel.cpp:
+        (WebCore::WebSocketChannel::~WebSocketChannel):
+        (WebCore::WebSocketChannel::connect):
+        
+        If content extensions are being used, run the URL through the content extension and apply its actions
+        before connecting the WebSocket.  This is done in WebSocketChannel instead of WebSocket like the CSP checks
+        because we need access to the Document in order to get access to the main document's URL for if-domain and
+        unless-domain rules, and to apply any display:none css to the Document.
+        
+        (WebCore::WebSocketChannel::disconnect):
+        * Modules/websockets/WebSocketChannelClient.h:
+        (WebCore::WebSocketChannelClient::~WebSocketChannelClient):
+        (WebCore::WebSocketChannelClient::WebSocketChannelClient):
+        (WebCore::WebSocketChannelClient::didConnect):
+        (WebCore::WebSocketChannelClient::didReceiveMessage):
+        (WebCore::WebSocketChannelClient::didReceiveBinaryData):
+        (WebCore::WebSocketChannelClient::didReceiveMessageError):
+        (WebCore::WebSocketChannelClient::didUpdateBufferedAmount):
+        (WebCore::WebSocketChannelClient::didStartClosingHandshake):
+        (WebCore::WebSocketChannelClient::didClose):
+        
+        Made WebSocketChannelClient purely virtual to avoid accidentally making an implementation that is missing functionality.
+        
+        (WebCore::WebSocketChannelClient::didUpgradeURL): Added.
+        * Modules/websockets/WebSocketHandshake.cpp:
+        (WebCore::WebSocketHandshake::getExpectedWebSocketAccept):
+        (WebCore::WebSocketHandshake::WebSocketHandshake):
+        (WebCore::WebSocketHandshake::clientOrigin):
+        (WebCore::WebSocketHandshake::clientLocation):
+        (WebCore::WebSocketHandshake::clientHandshakeMessage):
+        
+        Only put cookies on the WebSocket's handshake if we are allowed to use cookies.
+        
+        (WebCore::WebSocketHandshake::clientHandshakeRequest):
+        
+        A WebSocketHandshake always has a Document* for its ScriptExecutionContext, so I replaced m_context with 
+        m_document and removed a suspicious-looking check for is<Document> that turned out to not be suspicious at all.
+        
+        (WebCore::WebSocketHandshake::reset):
+        (WebCore::WebSocketHandshake::clearDocument):
+        (WebCore::WebSocketHandshake::readServerHandshake):
+        (WebCore::WebSocketHandshake::clearScriptExecutionContext): Deleted.
+        * Modules/websockets/WebSocketHandshake.h:
+        * Modules/websockets/WorkerThreadableWebSocketChannel.cpp:
+        (WebCore::WorkerThreadableWebSocketChannel::Peer::didReceiveMessageError):
+        (WebCore::WorkerThreadableWebSocketChannel::Peer::didUpgradeURL):
+        (WebCore::WorkerThreadableWebSocketChannel::Bridge::Bridge):
+        * Modules/websockets/WorkerThreadableWebSocketChannel.h:
+        * contentextensions/ContentExtensionActions.h:
+        
+        Before this change we would pass a ResourceRequest as a parameter to the content extension engine.
+        The ResourceRequest would be used to get the URL, and it would be modified by possibly disabling cookies
+        or making the URL https.  Any display:none CSS rules added were put into the Document through the DocumentLoader.
+        The only information it needed to return was whether the load was blocked.
+        To make content extensions work with WebSockets, we need to pass a URL as a parameter instead of a ResourceRequest
+        because there is no ResourceRequest with WebSockets, only a URL.  We can still put CSS rules in through the DocumentLoader,
+        but the rest of the actions need to be returned through the return value, which is then processed by the callers.
+        BlockedStatus is now a struct containing a set of actions to apply, and applyBlockedStatusToRequest is a helper function
+        that applies the actions to the ResourceRequests we have at all previously existing call sites of processContentExtensionRulesForLoad.
+        
+        * contentextensions/ContentExtensionsBackend.cpp:
+        (WebCore::ContentExtensions::ContentExtensionsBackend::globalDisplayNoneStyleSheet):
+        (WebCore::ContentExtensions::ContentExtensionsBackend::processContentExtensionRulesForLoad):
+        (WebCore::ContentExtensions::ContentExtensionsBackend::displayNoneCSSRule):
+        (WebCore::ContentExtensions::applyBlockedStatusToRequest):
+        * contentextensions/ContentExtensionsBackend.h:
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::loadResource):
+        
+        Here, we also only had a URL.  Before, we were making a ResourceRequest from the URL just for the content extension engine,
+        but now we can just pass the URL.
+        
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::loadResourceSynchronously):
+        * loader/PingLoader.cpp:
+        (WebCore::processContentExtensionRulesForLoad):
+        (WebCore::PingLoader::loadImage):
+        (WebCore::PingLoader::sendPing):
+        (WebCore::PingLoader::sendViolationReport):
+        * loader/ResourceLoader.cpp:
+        (WebCore::ResourceLoader::willSendRequestInternal):
+        * loader/cache/CachedResourceLoader.cpp:
+        (WebCore::CachedResourceLoader::requestResource):
+        * page/UserContentProvider.cpp:
+        (WebCore::contentExtensionsEnabled):
+        (WebCore::UserContentProvider::processContentExtensionRulesForLoad):
+        (WebCore::UserContentProvider::actionsForResourceLoad):
+        * page/UserContentProvider.h:
+
 2016-08-04  Chris Dumez  <cdu...@apple.com>
 
         [[Prototype]] property of an interface object for a callback interface must be the Object.prototype object

Modified: trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp (204126 => 204127)


--- trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp	2016-08-04 18:07:45 UTC (rev 204127)
@@ -229,6 +229,17 @@
         processPendingTasks();
 }
 
+void ThreadableWebSocketChannelClientWrapper::didUpgradeURL()
+{
+    m_pendingTasks.append(std::make_unique<ScriptExecutionContext::Task>([this, protectedThis = makeRef(*this)] (ScriptExecutionContext&) {
+        if (m_client)
+            m_client->didUpgradeURL();
+    }));
+    
+    if (!m_suspended)
+        processPendingTasks();
+}
+
 void ThreadableWebSocketChannelClientWrapper::suspend()
 {
     m_suspended = true;

Modified: trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.h (204126 => 204127)


--- trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.h	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.h	2016-08-04 18:07:45 UTC (rev 204127)
@@ -83,6 +83,7 @@
     void didStartClosingHandshake();
     void didClose(unsigned unhandledBufferedAmount, WebSocketChannelClient::ClosingHandshakeCompletionStatus, unsigned short code, const String& reason);
     void didReceiveMessageError();
+    void didUpgradeURL();
 
     void suspend();
     void resume();

Modified: trunk/Source/WebCore/Modules/websockets/WebSocket.cpp (204126 => 204127)


--- trunk/Source/WebCore/Modules/websockets/WebSocket.cpp	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/Modules/websockets/WebSocket.cpp	2016-08-04 18:07:45 UTC (rev 204127)
@@ -635,6 +635,12 @@
         ActiveDOMObject::unsetPendingActivity(this);
 }
 
+void WebSocket::didUpgradeURL()
+{
+    ASSERT(m_url.protocolIs("ws"));
+    m_url.setProtocol("wss");
+}
+
 size_t WebSocket::getFramingOverhead(size_t payloadSize)
 {
     static const size_t hybiBaseFramingOverhead = 2; // Every frame has at least two-byte header.

Modified: trunk/Source/WebCore/Modules/websockets/WebSocket.h (204126 => 204127)


--- trunk/Source/WebCore/Modules/websockets/WebSocket.h	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/Modules/websockets/WebSocket.h	2016-08-04 18:07:45 UTC (rev 204127)
@@ -96,13 +96,14 @@
     using RefCounted<WebSocket>::deref;
 
     // WebSocketChannelClient functions.
-    void didConnect() override;
-    void didReceiveMessage(const String& message) override;
-    void didReceiveBinaryData(Vector<uint8_t>&&) override;
-    void didReceiveMessageError() override;
-    void didUpdateBufferedAmount(unsigned bufferedAmount) override;
-    void didStartClosingHandshake() override;
-    void didClose(unsigned unhandledBufferedAmount, ClosingHandshakeCompletionStatus, unsigned short code, const String& reason) override;
+    void didConnect() final;
+    void didReceiveMessage(const String& message) final;
+    void didReceiveBinaryData(Vector<uint8_t>&&) final;
+    void didReceiveMessageError() final;
+    void didUpdateBufferedAmount(unsigned bufferedAmount) final;
+    void didStartClosingHandshake() final;
+    void didClose(unsigned unhandledBufferedAmount, ClosingHandshakeCompletionStatus, unsigned short code, const String& reason) final;
+    void didUpgradeURL() final;
 
 private:
     explicit WebSocket(ScriptExecutionContext&);

Modified: trunk/Source/WebCore/Modules/websockets/WebSocketChannel.cpp (204126 => 204127)


--- trunk/Source/WebCore/Modules/websockets/WebSocketChannel.cpp	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/Modules/websockets/WebSocketChannel.cpp	2016-08-04 18:07:45 UTC (rev 204127)
@@ -51,6 +51,7 @@
 #include "SocketProvider.h"
 #include "SocketStreamError.h"
 #include "SocketStreamHandle.h"
+#include "UserContentProvider.h"
 #include "WebSocketChannelClient.h"
 #include "WebSocketHandshake.h"
 #include <runtime/ArrayBuffer.h>
@@ -83,12 +84,39 @@
     LOG(Network, "WebSocketChannel %p dtor", this);
 }
 
-void WebSocketChannel::connect(const URL& url, const String& protocol)
+void WebSocketChannel::connect(const URL& requestedURL, const String& protocol)
 {
     LOG(Network, "WebSocketChannel %p connect()", this);
+
+    URL url = ""
+    bool allowCookies = true;
+#if ENABLE(CONTENT_EXTENSIONS)
+    if (auto* page = m_document->page()) {
+        if (auto* documentLoader = m_document->loader()) {
+            auto blockedStatus = page->userContentProvider().processContentExtensionRulesForLoad(url, ResourceType::Raw, *documentLoader);
+            if (blockedStatus.blockedLoad) {
+                Ref<WebSocketChannel> protectedThis(*this);
+                callOnMainThread([protectedThis = WTFMove(protectedThis)] {
+                    if (protectedThis->m_client)
+                        protectedThis->m_client->didReceiveMessageError();
+                });
+                return;
+            }
+            if (blockedStatus.madeHTTPS) {
+                ASSERT(url.protocolIs("ws"));
+                url.setProtocol("wss");
+                if (m_client)
+                    m_client->didUpgradeURL();
+            }
+            if (blockedStatus.blockedCookies)
+                allowCookies = false;
+        }
+    }
+#endif
+    
     ASSERT(!m_handle);
     ASSERT(!m_suspended);
-    m_handshake = std::make_unique<WebSocketHandshake>(url, protocol, m_document);
+    m_handshake = std::make_unique<WebSocketHandshake>(url, protocol, m_document, allowCookies);
     m_handshake->reset();
     if (m_deflateFramer.canDeflate())
         m_handshake->addExtensionProcessor(m_deflateFramer.createExtensionProcessor());
@@ -226,7 +254,7 @@
     if (m_identifier && m_document)
         InspectorInstrumentation::didCloseWebSocket(m_document, m_identifier);
     if (m_handshake)
-        m_handshake->clearScriptExecutionContext();
+        m_handshake->clearDocument();
     m_client = nullptr;
     m_document = nullptr;
     if (m_handle)

Modified: trunk/Source/WebCore/Modules/websockets/WebSocketChannelClient.h (204126 => 204127)


--- trunk/Source/WebCore/Modules/websockets/WebSocketChannelClient.h	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/Modules/websockets/WebSocketChannelClient.h	2016-08-04 18:07:45 UTC (rev 204127)
@@ -40,17 +40,18 @@
 class WebSocketChannelClient {
 public:
     virtual ~WebSocketChannelClient() { }
-    virtual void didConnect() { }
-    virtual void didReceiveMessage(const String&) { }
-    virtual void didReceiveBinaryData(Vector<uint8_t>&&) { }
-    virtual void didReceiveMessageError() { }
-    virtual void didUpdateBufferedAmount(unsigned /* bufferedAmount */) { }
-    virtual void didStartClosingHandshake() { }
+    virtual void didConnect() = 0;
+    virtual void didReceiveMessage(const String&) = 0;
+    virtual void didReceiveBinaryData(Vector<uint8_t>&&) = 0;
+    virtual void didReceiveMessageError() = 0;
+    virtual void didUpdateBufferedAmount(unsigned bufferedAmount) = 0;
+    virtual void didStartClosingHandshake() = 0;
     enum ClosingHandshakeCompletionStatus {
         ClosingHandshakeIncomplete,
         ClosingHandshakeComplete
     };
-    virtual void didClose(unsigned /* unhandledBufferedAmount */, ClosingHandshakeCompletionStatus, unsigned short /* code */, const String& /* reason */) { }
+    virtual void didClose(unsigned unhandledBufferedAmount, ClosingHandshakeCompletionStatus, unsigned short code, const String& reason) = 0;
+    virtual void didUpgradeURL() = 0;
 
 protected:
     WebSocketChannelClient() { }

Modified: trunk/Source/WebCore/Modules/websockets/WebSocketHandshake.cpp (204126 => 204127)


--- trunk/Source/WebCore/Modules/websockets/WebSocketHandshake.cpp	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/Modules/websockets/WebSocketHandshake.cpp	2016-08-04 18:07:45 UTC (rev 204127)
@@ -121,12 +121,13 @@
     return base64Encode(hash.data(), SHA1::hashSize);
 }
 
-WebSocketHandshake::WebSocketHandshake(const URL& url, const String& protocol, ScriptExecutionContext* context)
+WebSocketHandshake::WebSocketHandshake(const URL& url, const String& protocol, Document* document, bool allowCookies)
     : m_url(url)
     , m_clientProtocol(protocol)
     , m_secure(m_url.protocolIs("wss"))
-    , m_context(context)
+    , m_document(document)
     , m_mode(Incomplete)
+    , m_allowCookies(allowCookies)
 {
     m_secWebSocketKey = generateSecWebSocketKey();
     m_expectedAccept = getExpectedWebSocketAccept(m_secWebSocketKey);
@@ -169,7 +170,7 @@
 
 String WebSocketHandshake::clientOrigin() const
 {
-    return m_context->securityOrigin()->toString();
+    return m_document->securityOrigin()->toString();
 }
 
 String WebSocketHandshake::clientLocation() const
@@ -200,12 +201,10 @@
         fields.append("Sec-WebSocket-Protocol: " + m_clientProtocol);
 
     URL url = ""
-    if (is<Document>(*m_context)) {
-        Document& document = downcast<Document>(*m_context);
-        String cookie = cookieRequestHeaderFieldValue(&document, url);
+    if (m_allowCookies) {
+        String cookie = cookieRequestHeaderFieldValue(m_document, url);
         if (!cookie.isEmpty())
             fields.append("Cookie: " + cookie);
-        // Set "Cookie2: <cookie>" if cookies 2 exists for url?
     }
 
     // Add no-cache headers to avoid compatibility issue.
@@ -222,7 +221,7 @@
         fields.append("Sec-WebSocket-Extensions: " + extensionValue);
 
     // Add a User-Agent header.
-    fields.append("User-Agent: " + m_context->userAgent(m_context->url()));
+    fields.append("User-Agent: " + m_document->userAgent(m_document->url()));
 
     // Fields in the handshake are sent by the client in a random order; the
     // order is not meaningful.  Thus, it's ok to send the order we constructed
@@ -251,12 +250,10 @@
         request.setHTTPHeaderField(HTTPHeaderName::SecWebSocketProtocol, m_clientProtocol);
 
     URL url = ""
-    if (is<Document>(*m_context)) {
-        Document& document = downcast<Document>(*m_context);
-        String cookie = cookieRequestHeaderFieldValue(&document, url);
+    if (m_allowCookies) {
+        String cookie = cookieRequestHeaderFieldValue(m_document, url);
         if (!cookie.isEmpty())
             request.setHTTPHeaderField(HTTPHeaderName::Cookie, cookie);
-        // Set "Cookie2: <cookie>" if cookies 2 exists for url?
     }
 
     request.setHTTPHeaderField(HTTPHeaderName::Pragma, "no-cache");
@@ -269,7 +266,7 @@
         request.setHTTPHeaderField(HTTPHeaderName::SecWebSocketExtensions, extensionValue);
 
     // Add a User-Agent header.
-    request.setHTTPHeaderField(HTTPHeaderName::UserAgent, m_context->userAgent(m_context->url()));
+    request.setHTTPHeaderField(HTTPHeaderName::UserAgent, m_document->userAgent(m_document->url()));
 
     return request;
 }
@@ -280,9 +277,9 @@
     m_extensionDispatcher.reset();
 }
 
-void WebSocketHandshake::clearScriptExecutionContext()
+void WebSocketHandshake::clearDocument()
 {
-    m_context = nullptr;
+    m_document = nullptr;
 }
 
 int WebSocketHandshake::readServerHandshake(const char* header, size_t len)
@@ -350,11 +347,6 @@
     return m_serverHandshakeResponse.httpHeaderFields().get(HTTPHeaderName::SetCookie);
 }
 
-String WebSocketHandshake::serverSetCookie2() const
-{
-    return m_serverHandshakeResponse.httpHeaderFields().get(HTTPHeaderName::SetCookie2);
-}
-
 String WebSocketHandshake::serverUpgrade() const
 {
     return m_serverHandshakeResponse.httpHeaderFields().get(HTTPHeaderName::Upgrade);

Modified: trunk/Source/WebCore/Modules/websockets/WebSocketHandshake.h (204126 => 204127)


--- trunk/Source/WebCore/Modules/websockets/WebSocketHandshake.h	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/Modules/websockets/WebSocketHandshake.h	2016-08-04 18:07:45 UTC (rev 204127)
@@ -41,8 +41,8 @@
 
 namespace WebCore {
 
+class Document;
 class ResourceRequest;
-class ScriptExecutionContext;
 
 class WebSocketHandshake {
     WTF_MAKE_NONCOPYABLE(WebSocketHandshake); WTF_MAKE_FAST_ALLOCATED;
@@ -50,7 +50,7 @@
     enum Mode {
         Incomplete, Normal, Failed, Connected
     };
-    WebSocketHandshake(const URL&, const String& protocol, ScriptExecutionContext*);
+    WebSocketHandshake(const URL&, const String& protocol, Document*, bool allowCookies);
     ~WebSocketHandshake();
 
     const URL& url() const;
@@ -69,7 +69,7 @@
     ResourceRequest clientHandshakeRequest() const;
 
     void reset();
-    void clearScriptExecutionContext();
+    void clearDocument();
 
     int readServerHandshake(const char* header, size_t len);
     Mode mode() const;
@@ -77,7 +77,6 @@
 
     String serverWebSocketProtocol() const;
     String serverSetCookie() const;
-    String serverSetCookie2() const;
     String serverUpgrade() const;
     String serverConnection() const;
     String serverWebSocketAccept() const;
@@ -102,9 +101,10 @@
     URL m_url;
     String m_clientProtocol;
     bool m_secure;
-    ScriptExecutionContext* m_context;
+    Document* m_document;
 
     Mode m_mode;
+    bool m_allowCookies;
 
     ResourceResponse m_serverHandshakeResponse;
 

Modified: trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp (204126 => 204127)


--- trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp	2016-08-04 18:07:45 UTC (rev 204127)
@@ -331,6 +331,16 @@
     }, m_taskMode);
 }
 
+void WorkerThreadableWebSocketChannel::Peer::didUpgradeURL()
+{
+    ASSERT(isMainThread());
+    
+    m_loaderProxy.postTaskForModeToWorkerGlobalScope([workerClientWrapper = m_workerClientWrapper.copyRef()](ScriptExecutionContext& context) mutable {
+        ASSERT_UNUSED(context, context.isWorkerGlobalScope());
+        workerClientWrapper->didUpgradeURL();
+    }, m_taskMode);
+}
+
 WorkerThreadableWebSocketChannel::Bridge::Bridge(Ref<ThreadableWebSocketChannelClientWrapper>&& workerClientWrapper, Ref<WorkerGlobalScope>&& workerGlobalScope, const String& taskMode, Ref<SocketProvider>&& socketProvider)
     : m_workerClientWrapper(WTFMove(workerClientWrapper))
     , m_workerGlobalScope(WTFMove(workerGlobalScope))

Modified: trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.h (204126 => 204127)


--- trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.h	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.h	2016-08-04 18:07:45 UTC (rev 204127)
@@ -93,13 +93,14 @@
         void resume();
 
         // WebSocketChannelClient functions.
-        void didConnect() override;
-        void didReceiveMessage(const String& message) override;
-        void didReceiveBinaryData(Vector<uint8_t>&&) override;
-        void didUpdateBufferedAmount(unsigned bufferedAmount) override;
-        void didStartClosingHandshake() override;
-        void didClose(unsigned unhandledBufferedAmount, ClosingHandshakeCompletionStatus, unsigned short code, const String& reason) override;
-        void didReceiveMessageError() override;
+        void didConnect() final;
+        void didReceiveMessage(const String& message) final;
+        void didReceiveBinaryData(Vector<uint8_t>&&) final;
+        void didUpdateBufferedAmount(unsigned bufferedAmount) final;
+        void didStartClosingHandshake() final;
+        void didClose(unsigned unhandledBufferedAmount, ClosingHandshakeCompletionStatus, unsigned short code, const String& reason) final;
+        void didReceiveMessageError() final;
+        void didUpgradeURL() final;
 
     private:
         Ref<ThreadableWebSocketChannelClientWrapper> m_workerClientWrapper;

Modified: trunk/Source/WebCore/contentextensions/ContentExtensionActions.h (204126 => 204127)


--- trunk/Source/WebCore/contentextensions/ContentExtensionActions.h	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/contentextensions/ContentExtensionActions.h	2016-08-04 18:07:45 UTC (rev 204127)
@@ -23,17 +23,18 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef ContentExtensionActions_h
-#define ContentExtensionActions_h
+#pragma once
 
 #if ENABLE(CONTENT_EXTENSIONS)
 
 namespace WebCore {
-    
+
+class ResourceRequest;
+
 namespace ContentExtensions {
 
 typedef uint8_t SerializedActionByte;
-    
+
 enum class ActionType : uint8_t {
     BlockLoad,
     BlockCookies,
@@ -44,15 +45,16 @@
     InvalidAction,
 };
 
-enum class BlockedStatus {
-    Blocked,
-    NotBlocked,
+struct BlockedStatus {
+    bool blockedLoad { false };
+    bool blockedCookies { false };
+    bool madeHTTPS { false };
 };
-    
+
+void applyBlockedStatusToRequest(const BlockedStatus&, ResourceRequest&);
+
 } // namespace ContentExtensions
-    
+
 } // namespace WebCore
 
 #endif // ENABLE(CONTENT_EXTENSIONS)
-
-#endif // ContentExtensionActions_h

Modified: trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp (204126 => 204127)


--- trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp	2016-08-04 18:07:45 UTC (rev 204127)
@@ -146,10 +146,10 @@
     return contentExtension ? contentExtension->globalDisplayNoneStyleSheet() : nullptr;
 }
 
-BlockedStatus ContentExtensionsBackend::processContentExtensionRulesForLoad(ResourceRequest& request, ResourceType resourceType, DocumentLoader& initiatingDocumentLoader)
+BlockedStatus ContentExtensionsBackend::processContentExtensionRulesForLoad(const URL& url, ResourceType resourceType, DocumentLoader& initiatingDocumentLoader)
 {
     if (m_contentExtensions.isEmpty())
-        return BlockedStatus::NotBlocked;
+        return { };
 
     Document* currentDocument = nullptr;
     URL mainDocumentURL;
@@ -160,15 +160,17 @@
         if (initiatingDocumentLoader.isLoadingMainResource()
             && frame->isMainFrame()
             && resourceType == ResourceType::Document)
-            mainDocumentURL = request.url();
+            mainDocumentURL = url;
         else if (Document* mainDocument = frame->mainFrame().document())
             mainDocumentURL = mainDocument->url();
     }
 
-    ResourceLoadInfo resourceLoadInfo = { request.url(), mainDocumentURL, resourceType };
+    ResourceLoadInfo resourceLoadInfo = { url, mainDocumentURL, resourceType };
     Vector<ContentExtensions::Action> actions = actionsForResourceLoad(resourceLoadInfo);
 
     bool willBlockLoad = false;
+    bool willBlockCookies = false;
+    bool willMakeHTTPS = false;
     for (const auto& action : actions) {
         switch (action.type()) {
         case ContentExtensions::ActionType::BlockLoad:
@@ -175,7 +177,7 @@
             willBlockLoad = true;
             break;
         case ContentExtensions::ActionType::BlockCookies:
-            request.setAllowCookies(false);
+            willBlockCookies = true;
             break;
         case ContentExtensions::ActionType::CSSDisplayNoneSelector:
             if (resourceType == ResourceType::Document)
@@ -194,22 +196,9 @@
             break;
         }
         case ContentExtensions::ActionType::MakeHTTPS: {
-            const URL originalURL = request.url();
-            if (originalURL.protocolIs("http") && (!originalURL.hasPort() || isDefaultPortForProtocol(originalURL.port(), originalURL.protocol()))) {
-                URL newURL = originalURL;
-                newURL.setProtocol("https");
-                if (originalURL.hasPort())
-                    newURL.setPort(defaultPortForProtocol("https"));
-                request.setURL(newURL);
-
-                if (resourceType == ResourceType::Document && initiatingDocumentLoader.isLoadingMainResource()) {
-                    // This is to make sure the correct 'new' URL shows in the location bar.
-                    initiatingDocumentLoader.request().setURL(newURL);
-                    initiatingDocumentLoader.frameLoader()->client().dispatchDidChangeProvisionalURL();
-                }
-                if (currentDocument)
-                    currentDocument->addConsoleMessage(MessageSource::ContentBlocker, MessageLevel::Info, makeString("Content blocker promoted URL from ", originalURL.string(), " to ", newURL.string()));
-            }
+            if ((url.protocolIs("http") || url.protocolIs("ws"))
+                && (!url.hasPort() || isDefaultPortForProtocol(url.port(), url.protocol())))
+                willMakeHTTPS = true;
             break;
         }
         case ContentExtensions::ActionType::IgnorePreviousRules:
@@ -218,12 +207,16 @@
         }
     }
 
-    if (willBlockLoad) {
-        if (currentDocument)
-            currentDocument->addConsoleMessage(MessageSource::ContentBlocker, MessageLevel::Info, makeString("Content blocker prevented frame displaying ", mainDocumentURL.string(), " from loading a resource from ", request.url().string()));
-        return BlockedStatus::Blocked;
+    if (currentDocument) {
+        if (willMakeHTTPS) {
+            ASSERT(url.protocolIs("http") || url.protocolIs("ws"));
+            String newProtocol = url.protocolIs("http") ? ASCIILiteral("https") : ASCIILiteral("wss");
+            currentDocument->addConsoleMessage(MessageSource::ContentBlocker, MessageLevel::Info, makeString("Content blocker promoted URL from ", url.string(), " to ", newProtocol));
+        }
+        if (willBlockLoad)
+            currentDocument->addConsoleMessage(MessageSource::ContentBlocker, MessageLevel::Info, makeString("Content blocker prevented frame displaying ", mainDocumentURL.string(), " from loading a resource from ", url.string()));
     }
-    return BlockedStatus::NotBlocked;
+    return { willBlockLoad, willBlockCookies, willMakeHTTPS };
 }
 
 const String& ContentExtensionsBackend::displayNoneCSSRule()
@@ -232,6 +225,24 @@
     return rule;
 }
 
+void applyBlockedStatusToRequest(const BlockedStatus& status, ResourceRequest& request)
+{
+    if (status.blockedCookies)
+        request.setAllowCookies(false);
+
+    if (status.madeHTTPS) {
+        const URL& originalURL = request.url();
+        ASSERT(originalURL.protocolIs("http"));
+        ASSERT(!originalURL.hasPort() || isDefaultPortForProtocol(originalURL.port(), originalURL.protocol()));
+
+        URL newURL = originalURL;
+        newURL.setProtocol("https");
+        if (originalURL.hasPort())
+            newURL.setPort(defaultPortForProtocol("https"));
+        request.setURL(newURL);
+    }
+}
+    
 } // namespace ContentExtensions
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.h (204126 => 204127)


--- trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.h	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.h	2016-08-04 18:07:45 UTC (rev 204127)
@@ -65,7 +65,7 @@
     WEBCORE_EXPORT Vector<Action> actionsForResourceLoad(const ResourceLoadInfo&) const;
     WEBCORE_EXPORT StyleSheetContents* globalDisplayNoneStyleSheet(const String& identifier) const;
 
-    BlockedStatus processContentExtensionRulesForLoad(ResourceRequest&, ResourceType, DocumentLoader& initiatingDocumentLoader);
+    BlockedStatus processContentExtensionRulesForLoad(const URL&, ResourceType, DocumentLoader& initiatingDocumentLoader);
 
     static const String& displayNoneCSSRule();
 

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (204126 => 204127)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2016-08-04 18:07:45 UTC (rev 204127)
@@ -1355,13 +1355,14 @@
     }
 
 #if ENABLE(CONTENT_EXTENSIONS)
-    ResourceRequest request(url);
     DocumentLoader* documentLoader = frame->loader().documentLoader();
 
-    if (documentLoader && page->userContentProvider().processContentExtensionRulesForLoad(request, ResourceType::Media, *documentLoader) == ContentExtensions::BlockedStatus::Blocked) {
-        request = { };
-        mediaLoadingFailed(MediaPlayer::FormatError);
-        return;
+    if (documentLoader) {
+        auto blockedStatus = page->userContentProvider().processContentExtensionRulesForLoad(url, ResourceType::Media, *documentLoader);
+        if (blockedStatus.blockedLoad) {
+            mediaLoadingFailed(MediaPlayer::FormatError);
+            return;
+        }
     }
 #endif
 

Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (204126 => 204127)


--- trunk/Source/WebCore/loader/FrameLoader.cpp	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp	2016-08-04 18:07:45 UTC (rev 204127)
@@ -2745,11 +2745,15 @@
 #if ENABLE(CONTENT_EXTENSIONS)
     if (error.isNull()) {
         if (auto* page = m_frame.page()) {
-            if (m_documentLoader && page->userContentProvider().processContentExtensionRulesForLoad(newRequest, ResourceType::Raw, *m_documentLoader) == ContentExtensions::BlockedStatus::Blocked) {
-                newRequest = { };
-                error = ResourceError(errorDomainWebKitInternal, 0, initialRequest.url(), emptyString());
-                response = { };
-                data = ""
+            if (m_documentLoader) {
+                auto blockedStatus = page->userContentProvider().processContentExtensionRulesForLoad(newRequest.url(), ResourceType::Raw, *m_documentLoader);
+                applyBlockedStatusToRequest(blockedStatus, newRequest);
+                if (blockedStatus.blockedLoad) {
+                    newRequest = { };
+                    error = ResourceError(errorDomainWebKitInternal, 0, initialRequest.url(), emptyString());
+                    response = { };
+                    data = ""
+                }
             }
         }
     }

Modified: trunk/Source/WebCore/loader/PingLoader.cpp (204126 => 204127)


--- trunk/Source/WebCore/loader/PingLoader.cpp	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/loader/PingLoader.cpp	2016-08-04 18:07:45 UTC (rev 204127)
@@ -58,13 +58,13 @@
 namespace WebCore {
 
 #if ENABLE(CONTENT_EXTENSIONS)
-static ContentExtensions::BlockedStatus processContentExtensionRulesForLoad(const Frame& frame, ResourceRequest& request, ResourceType resourceType)
+static ContentExtensions::BlockedStatus processContentExtensionRulesForLoad(const Frame& frame, const URL& url, ResourceType resourceType)
 {
     if (DocumentLoader* documentLoader = frame.loader().documentLoader()) {
         if (Page* page = frame.page())
-            return page->userContentProvider().processContentExtensionRulesForLoad(request, resourceType, *documentLoader);
+            return page->userContentProvider().processContentExtensionRulesForLoad(url, resourceType, *documentLoader);
     }
-    return ContentExtensions::BlockedStatus::NotBlocked;
+    return { };
 }
 #endif
 
@@ -78,7 +78,9 @@
     ResourceRequest request(url);
 
 #if ENABLE(CONTENT_EXTENSIONS)
-    if (processContentExtensionRulesForLoad(frame, request, ResourceType::Image) == ContentExtensions::BlockedStatus::Blocked)
+    auto blockedStatus = processContentExtensionRulesForLoad(frame, url, ResourceType::Image);
+    applyBlockedStatusToRequest(blockedStatus, request);
+    if (blockedStatus.blockedLoad)
         return;
 #endif
 
@@ -103,7 +105,9 @@
     ResourceRequest request(pingURL);
     
 #if ENABLE(CONTENT_EXTENSIONS)
-    if (processContentExtensionRulesForLoad(frame, request, ResourceType::Raw) == ContentExtensions::BlockedStatus::Blocked)
+    auto blockedStatus = processContentExtensionRulesForLoad(frame, pingURL, ResourceType::Raw);
+    applyBlockedStatusToRequest(blockedStatus, request);
+    if (blockedStatus.blockedLoad)
         return;
 #endif
 
@@ -136,7 +140,9 @@
     ResourceRequest request(reportURL);
 
 #if ENABLE(CONTENT_EXTENSIONS)
-    if (processContentExtensionRulesForLoad(frame, request, ResourceType::Raw) == ContentExtensions::BlockedStatus::Blocked)
+    auto blockedStatus = processContentExtensionRulesForLoad(frame, reportURL, ResourceType::Raw);
+    applyBlockedStatusToRequest(blockedStatus, request);
+    if (blockedStatus.blockedLoad)
         return;
 #endif
 

Modified: trunk/Source/WebCore/loader/ResourceLoader.cpp (204126 => 204127)


--- trunk/Source/WebCore/loader/ResourceLoader.cpp	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/loader/ResourceLoader.cpp	2016-08-04 18:07:45 UTC (rev 204127)
@@ -336,7 +336,9 @@
     if (frameLoader()) {
         Page* page = frameLoader()->frame().page();
         if (page && m_documentLoader) {
-            if (page->userContentProvider().processContentExtensionRulesForLoad(request, m_resourceType, *m_documentLoader) == ContentExtensions::BlockedStatus::Blocked) {
+            auto blockedStatus = page->userContentProvider().processContentExtensionRulesForLoad(request.url(), m_resourceType, *m_documentLoader);
+            applyBlockedStatusToRequest(blockedStatus, request);
+            if (blockedStatus.blockedLoad) {
                 request = { };
                 didFail(blockedByContentBlockerError());
                 return;

Modified: trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp (204126 => 204127)


--- trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp	2016-08-04 18:07:45 UTC (rev 204127)
@@ -571,7 +571,10 @@
 
 #if ENABLE(CONTENT_EXTENSIONS)
     if (frame() && frame()->mainFrame().page() && m_documentLoader) {
-        if (frame()->mainFrame().page()->userContentProvider().processContentExtensionRulesForLoad(request.mutableResourceRequest(), toResourceType(type), *m_documentLoader) == ContentExtensions::BlockedStatus::Blocked) {
+        auto& resourceRequest = request.mutableResourceRequest();
+        auto blockedStatus = frame()->mainFrame().page()->userContentProvider().processContentExtensionRulesForLoad(resourceRequest.url(), toResourceType(type), *m_documentLoader);
+        applyBlockedStatusToRequest(blockedStatus, resourceRequest);
+        if (blockedStatus.blockedLoad) {
             if (type == CachedResource::Type::MainResource) {
                 auto resource = createResource(type, request.mutableResourceRequest(), request.charset(), sessionID());
                 ASSERT(resource);
@@ -581,6 +584,12 @@
             }
             return nullptr;
         }
+        if (blockedStatus.madeHTTPS
+            && type == CachedResource::Type::MainResource
+            && m_documentLoader->isLoadingMainResource()) {
+            // This is to make sure the correct 'new' URL shows in the location bar.
+            m_documentLoader->frameLoader()->client().dispatchDidChangeProvisionalURL();
+        }
         url = "" // The content extension could have changed it from http to https.
         url = "" // Might need to remove fragment identifier again.
     }

Modified: trunk/Source/WebCore/page/UserContentProvider.cpp (204126 => 204127)


--- trunk/Source/WebCore/page/UserContentProvider.cpp	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/page/UserContentProvider.cpp	2016-08-04 18:07:45 UTC (rev 204127)
@@ -100,12 +100,12 @@
     return true;
 }
     
-ContentExtensions::BlockedStatus UserContentProvider::processContentExtensionRulesForLoad(ResourceRequest& request, ResourceType resourceType, DocumentLoader& initiatingDocumentLoader)
+ContentExtensions::BlockedStatus UserContentProvider::processContentExtensionRulesForLoad(const URL& url, ResourceType resourceType, DocumentLoader& initiatingDocumentLoader)
 {
     if (!contentExtensionsEnabled(initiatingDocumentLoader))
-        return ContentExtensions::BlockedStatus::NotBlocked;
+        return { };
 
-    return userContentExtensionBackend().processContentExtensionRulesForLoad(request, resourceType, initiatingDocumentLoader);
+    return userContentExtensionBackend().processContentExtensionRulesForLoad(url, resourceType, initiatingDocumentLoader);
 }
 
 Vector<ContentExtensions::Action> UserContentProvider::actionsForResourceLoad(const ResourceLoadInfo& resourceLoadInfo, DocumentLoader& initiatingDocumentLoader)

Modified: trunk/Source/WebCore/page/UserContentProvider.h (204126 => 204127)


--- trunk/Source/WebCore/page/UserContentProvider.h	2016-08-04 18:03:16 UTC (rev 204126)
+++ trunk/Source/WebCore/page/UserContentProvider.h	2016-08-04 18:07:45 UTC (rev 204127)
@@ -92,7 +92,7 @@
 #if ENABLE(CONTENT_EXTENSIONS)
     // FIXME: These don't really belong here. They should probably bundled up in the ContentExtensionsBackend
     // which should always exist.
-    ContentExtensions::BlockedStatus processContentExtensionRulesForLoad(ResourceRequest&, ResourceType, DocumentLoader& initiatingDocumentLoader);
+    ContentExtensions::BlockedStatus processContentExtensionRulesForLoad(const URL&, ResourceType, DocumentLoader& initiatingDocumentLoader);
     Vector<ContentExtensions::Action> actionsForResourceLoad(const ResourceLoadInfo&, DocumentLoader& initiatingDocumentLoader);
 #endif
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to