[Content Filtering] Load blocked pages more like other error pages are loaded
authoraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Jul 2016 23:26:28 +0000 (23:26 +0000)
committeraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Jul 2016 23:26:28 +0000 (23:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=159485
<rdar://problem/26014076>

Reviewed by Brady Eidson.

Source/WebCore:

Content filter blocked pages were being loaded by cancelling the provisional load of the
page that was blocked and then scheduling a navigation to the content filter error page.
Some clients would not expect a new, Web process-initiated provisional navigation to start
after a cancellation, though, and this would put them in a bad state.

This patch changes blocked page loading to behave more like loading other error pages.
Specifically:
1. didFailProvisionalLoad is dispatched with a new, non-cancellation error code.
2. The blocked page is loaded immediately after dispatching didFailProvisionalLoad, which
   prevents FrameLoader from creating a new back-forward list item for the substitute data load.
3. A substitute data load initiated by the client for the blocked URL is ignored if
   ContentFilter will display its own error page.
4. A file: URL is used instead of a custom scheme for the base URL of the blocked page,
   since some clients expect this.

Updated existing tests to capture frame load delegate callbacks and the back forward list.
Added new API tests: ContentFiltering.LoadAlternate*.

* English.lproj/Localizable.strings: Added a WebKitErrorFrameLoadBlockedByContentFilter description.
* Resources/ContentFilterBlockedPage.html: Added.
* WebCore.xcodeproj/project.pbxproj: Added ContentFilterBlockedPage.html as a frameowrk resource.
* loader/ContentFilter.cpp:
(WebCore::ContentFilter::stopFilteringMainResource): Only set m_state to Stopped if not
already Blocked, so that we don't forget this ContentFilter was blocked when calling
cancelMailResourceLoad() in didDecide().
(WebCore::ContentFilter::didDecide): Moved code from DocumentLoader::contentFilterDidBlock() to here.
Created a blockedByContentFilterError() and called cancelMainResourceLoad().
(WebCore::blockedPageURL): Returned a file: URL to ContentFilterBlockedPage.html in WebCore.framework.
(WebCore::ContentFilter::continueAfterSubstituteDataRequest): If the substitute data load
is for the same failingURL as the currently-displayed blocked page, ignore it.
(WebCore::ContentFilter::handleProvisionalLoadFailure): Load the blocked page if m_state is Blocked
and the ResourceError matches the error we used when previously calling cancelMainResourceLoad().
(WebCore::ContentFilter::unblockHandler): Deleted.
(WebCore::ContentFilter::replacementData): Deleted.
(WebCore::ContentFilter::unblockRequestDeniedScript): Deleted.
* loader/ContentFilter.h:
* loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::contentFilter): Returned m_contentFilter.
(WebCore::DocumentLoader::installContentFilterUnblockHandler): Deleted.
(WebCore::DocumentLoader::contentFilterDidBlock): Deleted.
* loader/DocumentLoader.h:
* loader/EmptyClients.h: Added a default implementation of blockedByContentFilterError().
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::load): If m_loadType was already RedirectWithLockedBackForwardList
and we are loading subsitute data for a failing URL, continue to use RedirectWithLockedBackForwardList.
This prevents a new back-forward list item from being created when loading a blocked page in a subframe.
(WebCore::FrameLoader::checkLoadCompleteForThisFrame):
Called ContentFilter::handleProvisionalLoadFailure() after dispatchDidFailProvisionalLoad().
(WebCore::FrameLoader::blockedByContentFilterError): Called FrameLoaderClient::blockedByContentFilterError().
* loader/FrameLoader.h:
* loader/FrameLoaderClient.h:
* loader/NavigationScheduler.cpp:
(WebCore::ScheduledSubstituteDataLoad::ScheduledSubstituteDataLoad): Deleted.
(WebCore::NavigationScheduler::scheduleSubstituteDataLoad): Deleted.
* loader/NavigationScheduler.h:
* loader/PolicyChecker.cpp:
(WebCore::PolicyChecker::checkNavigationPolicy): Ignored a substitute data load for a
failing URL if ContentFilter::continueAfterSubstituteDataRequest() returns false.

Source/WebKit/mac:

* Misc/WebKitErrors.h: Defined WebKitErrorFrameLoadBlockedByContentFilter.
* Misc/WebKitErrors.m:
(registerErrors): Registered WebKitErrorDescriptionFrameLoadBlockedByContentFilter.
* WebCoreSupport/WebFrameLoaderClient.h:
* WebCoreSupport/WebFrameLoaderClient.mm:
(WebFrameLoaderClient::blockedByContentFilterError): Returned a ResourceError for WebKitErrorFrameLoadBlockedByContentFilter.

Source/WebKit2:

* Shared/API/c/WKErrorRef.h: Defined kWKErrorCodeFrameLoadBlockedByContentFilter.
* UIProcess/Cocoa/WebProcessProxyCocoa.mm:
(WebKit::WebProcessProxy::platformPathsWithAssumedReadAccess): Added the resource directories
of WebCore.framework and WebKit.framework as paths with assumed read access.
* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::hasAssumedReadAccessToURL): Checked platformPathsWithAssumedReadAccess()
as well as m_localPathsWithAssumedReadAccess.
(WebKit::WebProcessProxy::platformPathsWithAssumedReadAccess): Added a non-Cocoa implementation.
* UIProcess/WebProcessProxy.h:
* WebProcess/WebCoreSupport/WebErrors.h:
* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::blockedByContentFilterError): Called WebKit::blockedByContentFilterError().
* WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
* WebProcess/WebCoreSupport/mac/WebErrorsMac.mm:
(WebKit::blockedByContentFilterError): Returned a ResourceError for kWKErrorCodeFrameLoadBlockedByContentFilter.

Tools:

Added API tests for WebView and WKWebView to verify that alternate HTML loaded in response
to a content filtering provisional navigation failure is ignored in preference of
ContentFilter's own error page.

* TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.mm:
(-[LoadAlternateNavigationDelegate webView:didFailProvisionalNavigation:withError:]):
(-[LoadAlternateNavigationDelegate webView:didFinishNavigation:]):
(loadAlternateTest):
(TEST):
* TestWebKitAPI/Tests/WebKit2Cocoa/ContentFilteringPlugIn.mm:
(-[MockContentFilterEnabler initWithCoder:]):
* TestWebKitAPI/Tests/mac/ContentFiltering.mm: Added.
(-[LoadAlternateFrameLoadDelegate webView:didFailProvisionalLoadWithError:forFrame:]):
(-[LoadAlternateFrameLoadDelegate webView:didFinishLoadForFrame:]):
(TestWebKitAPI::loadAlternateTest):
(TestWebKitAPI::TEST):

LayoutTests:

Changed allow-* and block-* tests from ref tests to text tests so that they can capture
frame load delegate callbacks and the back forward list.

* contentfiltering/allow-after-add-data-expected.html: Removed.
* contentfiltering/allow-after-add-data-expected.txt: Added.
* contentfiltering/allow-after-finished-adding-data-expected.html: Removed.
* contentfiltering/allow-after-finished-adding-data-expected.txt: Added.
* contentfiltering/allow-after-response-expected.html: Removed.
* contentfiltering/allow-after-response-expected.txt: Added.
* contentfiltering/allow-after-will-send-request-expected.html: Removed.
* contentfiltering/allow-after-will-send-request-expected.txt: Added.
* contentfiltering/allow-never-expected.html: Removed.
* contentfiltering/allow-never-expected.txt: Added.
* contentfiltering/block-after-add-data-expected.html: Removed.
* contentfiltering/block-after-add-data-expected.txt: Added.
* contentfiltering/block-after-add-data-then-allow-unblock-expected.html: Removed.
* contentfiltering/block-after-add-data-then-allow-unblock-expected.txt: Added.
* contentfiltering/block-after-add-data-then-deny-unblock-expected.html: Removed.
* contentfiltering/block-after-add-data-then-deny-unblock-expected.txt: Added.
* contentfiltering/block-after-finished-adding-data-expected.html: Removed.
* contentfiltering/block-after-finished-adding-data-expected.txt: Added.
* contentfiltering/block-after-finished-adding-data-then-allow-unblock-expected.html: Removed.
* contentfiltering/block-after-finished-adding-data-then-allow-unblock-expected.txt: Added.
* contentfiltering/block-after-finished-adding-data-then-deny-unblock-expected.html: Removed.
* contentfiltering/block-after-finished-adding-data-then-deny-unblock-expected.txt: Added.
* contentfiltering/block-after-response-expected.html: Removed.
* contentfiltering/block-after-response-expected.txt: Added.
* contentfiltering/block-after-response-then-allow-unblock-expected.html: Removed.
* contentfiltering/block-after-response-then-allow-unblock-expected.txt: Added.
* contentfiltering/block-after-response-then-deny-unblock-expected.html: Removed.
* contentfiltering/block-after-response-then-deny-unblock-expected.txt: Added.
* contentfiltering/block-after-will-send-request-expected.html: Removed.
* contentfiltering/block-after-will-send-request-expected.txt: Added.
* contentfiltering/block-after-will-send-request-then-allow-unblock-expected.html: Removed.
* contentfiltering/block-after-will-send-request-then-allow-unblock-expected.txt: Added.
* contentfiltering/block-after-will-send-request-then-deny-unblock-expected.html: Removed.
* contentfiltering/block-after-will-send-request-then-deny-unblock-expected.txt: Added.
* contentfiltering/block-never-expected.html: Removed.
* contentfiltering/block-never-expected.txt: Added.
* contentfiltering/resources/contentfiltering.js: Added testRunner calls to dump as text,
dump frame load callbacks, and dump the back forward list. Changed from loading data: URLs
to file: URLs in the test iframe.

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

73 files changed:
LayoutTests/ChangeLog
LayoutTests/contentfiltering/allow-after-add-data-expected.html [deleted file]
LayoutTests/contentfiltering/allow-after-add-data-expected.txt [new file with mode: 0644]
LayoutTests/contentfiltering/allow-after-finished-adding-data-expected.html [deleted file]
LayoutTests/contentfiltering/allow-after-finished-adding-data-expected.txt [new file with mode: 0644]
LayoutTests/contentfiltering/allow-after-response-expected.html [deleted file]
LayoutTests/contentfiltering/allow-after-response-expected.txt [new file with mode: 0644]
LayoutTests/contentfiltering/allow-after-will-send-request-expected.html [deleted file]
LayoutTests/contentfiltering/allow-after-will-send-request-expected.txt [new file with mode: 0644]
LayoutTests/contentfiltering/allow-never-expected.html [deleted file]
LayoutTests/contentfiltering/allow-never-expected.txt [new file with mode: 0644]
LayoutTests/contentfiltering/block-after-add-data-expected.html [deleted file]
LayoutTests/contentfiltering/block-after-add-data-expected.txt [new file with mode: 0644]
LayoutTests/contentfiltering/block-after-add-data-then-allow-unblock-expected.html [deleted file]
LayoutTests/contentfiltering/block-after-add-data-then-allow-unblock-expected.txt [new file with mode: 0644]
LayoutTests/contentfiltering/block-after-add-data-then-deny-unblock-expected.html [deleted file]
LayoutTests/contentfiltering/block-after-add-data-then-deny-unblock-expected.txt [new file with mode: 0644]
LayoutTests/contentfiltering/block-after-finished-adding-data-expected.html [deleted file]
LayoutTests/contentfiltering/block-after-finished-adding-data-expected.txt [new file with mode: 0644]
LayoutTests/contentfiltering/block-after-finished-adding-data-then-allow-unblock-expected.html [deleted file]
LayoutTests/contentfiltering/block-after-finished-adding-data-then-allow-unblock-expected.txt [new file with mode: 0644]
LayoutTests/contentfiltering/block-after-finished-adding-data-then-deny-unblock-expected.html [deleted file]
LayoutTests/contentfiltering/block-after-finished-adding-data-then-deny-unblock-expected.txt [new file with mode: 0644]
LayoutTests/contentfiltering/block-after-response-expected.html [deleted file]
LayoutTests/contentfiltering/block-after-response-expected.txt [new file with mode: 0644]
LayoutTests/contentfiltering/block-after-response-then-allow-unblock-expected.html [deleted file]
LayoutTests/contentfiltering/block-after-response-then-allow-unblock-expected.txt [new file with mode: 0644]
LayoutTests/contentfiltering/block-after-response-then-deny-unblock-expected.html [deleted file]
LayoutTests/contentfiltering/block-after-response-then-deny-unblock-expected.txt [new file with mode: 0644]
LayoutTests/contentfiltering/block-after-will-send-request-expected.html [deleted file]
LayoutTests/contentfiltering/block-after-will-send-request-expected.txt [new file with mode: 0644]
LayoutTests/contentfiltering/block-after-will-send-request-then-allow-unblock-expected.html [deleted file]
LayoutTests/contentfiltering/block-after-will-send-request-then-allow-unblock-expected.txt [new file with mode: 0644]
LayoutTests/contentfiltering/block-after-will-send-request-then-deny-unblock-expected.html [deleted file]
LayoutTests/contentfiltering/block-after-will-send-request-then-deny-unblock-expected.txt [new file with mode: 0644]
LayoutTests/contentfiltering/block-never-expected.html [deleted file]
LayoutTests/contentfiltering/block-never-expected.txt [new file with mode: 0644]
LayoutTests/contentfiltering/resources/contentfiltering.js
Source/WebCore/ChangeLog
Source/WebCore/English.lproj/Localizable.strings
Source/WebCore/Resources/ContentFilterBlockedPage.html [new file with mode: 0644]
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/loader/ContentFilter.cpp
Source/WebCore/loader/ContentFilter.h
Source/WebCore/loader/DocumentLoader.cpp
Source/WebCore/loader/DocumentLoader.h
Source/WebCore/loader/EmptyClients.h
Source/WebCore/loader/FrameLoader.cpp
Source/WebCore/loader/FrameLoader.h
Source/WebCore/loader/FrameLoaderClient.h
Source/WebCore/loader/NavigationScheduler.cpp
Source/WebCore/loader/NavigationScheduler.h
Source/WebCore/loader/PolicyChecker.cpp
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/Misc/WebKitErrors.h
Source/WebKit/mac/Misc/WebKitErrors.m
Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.h
Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/API/c/WKErrorRef.h
Source/WebKit2/UIProcess/Cocoa/WebProcessProxyCocoa.mm
Source/WebKit2/UIProcess/WebProcessProxy.cpp
Source/WebKit2/UIProcess/WebProcessProxy.h
Source/WebKit2/WebProcess/WebCoreSupport/WebErrors.h
Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h
Source/WebKit2/WebProcess/WebCoreSupport/mac/WebErrorsMac.mm
Tools/ChangeLog
Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.mm
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFilteringPlugIn.mm
Tools/TestWebKitAPI/Tests/mac/ContentFiltering.mm [new file with mode: 0644]

index 76835a1..2555831 100644 (file)
@@ -1,3 +1,54 @@
+2016-07-07  Andy Estes  <aestes@apple.com>
+
+        [Content Filtering] Load blocked pages more like other error pages are loaded
+        https://bugs.webkit.org/show_bug.cgi?id=159485
+        <rdar://problem/26014076>
+
+        Reviewed by Brady Eidson.
+
+        Changed allow-* and block-* tests from ref tests to text tests so that they can capture
+        frame load delegate callbacks and the back forward list.
+
+        * contentfiltering/allow-after-add-data-expected.html: Removed.
+        * contentfiltering/allow-after-add-data-expected.txt: Added.
+        * contentfiltering/allow-after-finished-adding-data-expected.html: Removed.
+        * contentfiltering/allow-after-finished-adding-data-expected.txt: Added.
+        * contentfiltering/allow-after-response-expected.html: Removed.
+        * contentfiltering/allow-after-response-expected.txt: Added.
+        * contentfiltering/allow-after-will-send-request-expected.html: Removed.
+        * contentfiltering/allow-after-will-send-request-expected.txt: Added.
+        * contentfiltering/allow-never-expected.html: Removed.
+        * contentfiltering/allow-never-expected.txt: Added.
+        * contentfiltering/block-after-add-data-expected.html: Removed.
+        * contentfiltering/block-after-add-data-expected.txt: Added.
+        * contentfiltering/block-after-add-data-then-allow-unblock-expected.html: Removed.
+        * contentfiltering/block-after-add-data-then-allow-unblock-expected.txt: Added.
+        * contentfiltering/block-after-add-data-then-deny-unblock-expected.html: Removed.
+        * contentfiltering/block-after-add-data-then-deny-unblock-expected.txt: Added.
+        * contentfiltering/block-after-finished-adding-data-expected.html: Removed.
+        * contentfiltering/block-after-finished-adding-data-expected.txt: Added.
+        * contentfiltering/block-after-finished-adding-data-then-allow-unblock-expected.html: Removed.
+        * contentfiltering/block-after-finished-adding-data-then-allow-unblock-expected.txt: Added.
+        * contentfiltering/block-after-finished-adding-data-then-deny-unblock-expected.html: Removed.
+        * contentfiltering/block-after-finished-adding-data-then-deny-unblock-expected.txt: Added.
+        * contentfiltering/block-after-response-expected.html: Removed.
+        * contentfiltering/block-after-response-expected.txt: Added.
+        * contentfiltering/block-after-response-then-allow-unblock-expected.html: Removed.
+        * contentfiltering/block-after-response-then-allow-unblock-expected.txt: Added.
+        * contentfiltering/block-after-response-then-deny-unblock-expected.html: Removed.
+        * contentfiltering/block-after-response-then-deny-unblock-expected.txt: Added.
+        * contentfiltering/block-after-will-send-request-expected.html: Removed.
+        * contentfiltering/block-after-will-send-request-expected.txt: Added.
+        * contentfiltering/block-after-will-send-request-then-allow-unblock-expected.html: Removed.
+        * contentfiltering/block-after-will-send-request-then-allow-unblock-expected.txt: Added.
+        * contentfiltering/block-after-will-send-request-then-deny-unblock-expected.html: Removed.
+        * contentfiltering/block-after-will-send-request-then-deny-unblock-expected.txt: Added.
+        * contentfiltering/block-never-expected.html: Removed.
+        * contentfiltering/block-never-expected.txt: Added.
+        * contentfiltering/resources/contentfiltering.js: Added testRunner calls to dump as text,
+        dump frame load callbacks, and dump the back forward list. Changed from loading data: URLs
+        to file: URLs in the test iframe.
+
 2016-07-07  Benjamin Poulain  <benjamin@webkit.org>
 
         [JSC] Array.prototype[Symbol.unscopables] should have the "includes" property
diff --git a/LayoutTests/contentfiltering/allow-after-add-data-expected.html b/LayoutTests/contentfiltering/allow-after-add-data-expected.html
deleted file mode 100644 (file)
index 645112f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<iframe src="resources/pass.html"></iframe>
diff --git a/LayoutTests/contentfiltering/allow-after-add-data-expected.txt b/LayoutTests/contentfiltering/allow-after-add-data-expected.txt
new file mode 100644 (file)
index 0000000..580d051
--- /dev/null
@@ -0,0 +1,26 @@
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: resources/pass.html 
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):contentfiltering/allow-after-add-data.html  **nav target**
+            (file test):contentfiltering/resources/pass.html (in frame "<!--framePath //<!--frame0-->-->")
+===============================================
diff --git a/LayoutTests/contentfiltering/allow-after-finished-adding-data-expected.html b/LayoutTests/contentfiltering/allow-after-finished-adding-data-expected.html
deleted file mode 100644 (file)
index 645112f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<iframe src="resources/pass.html"></iframe>
diff --git a/LayoutTests/contentfiltering/allow-after-finished-adding-data-expected.txt b/LayoutTests/contentfiltering/allow-after-finished-adding-data-expected.txt
new file mode 100644 (file)
index 0000000..90da90d
--- /dev/null
@@ -0,0 +1,26 @@
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: resources/pass.html 
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):contentfiltering/allow-after-finished-adding-data.html  **nav target**
+            (file test):contentfiltering/resources/pass.html (in frame "<!--framePath //<!--frame0-->-->")
+===============================================
diff --git a/LayoutTests/contentfiltering/allow-after-response-expected.html b/LayoutTests/contentfiltering/allow-after-response-expected.html
deleted file mode 100644 (file)
index 645112f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<iframe src="resources/pass.html"></iframe>
diff --git a/LayoutTests/contentfiltering/allow-after-response-expected.txt b/LayoutTests/contentfiltering/allow-after-response-expected.txt
new file mode 100644 (file)
index 0000000..0043fb4
--- /dev/null
@@ -0,0 +1,26 @@
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: resources/pass.html 
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):contentfiltering/allow-after-response.html  **nav target**
+            (file test):contentfiltering/resources/pass.html (in frame "<!--framePath //<!--frame0-->-->")
+===============================================
diff --git a/LayoutTests/contentfiltering/allow-after-will-send-request-expected.html b/LayoutTests/contentfiltering/allow-after-will-send-request-expected.html
deleted file mode 100644 (file)
index 645112f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<iframe src="resources/pass.html"></iframe>
diff --git a/LayoutTests/contentfiltering/allow-after-will-send-request-expected.txt b/LayoutTests/contentfiltering/allow-after-will-send-request-expected.txt
new file mode 100644 (file)
index 0000000..a566a4b
--- /dev/null
@@ -0,0 +1,26 @@
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: resources/pass.html 
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):contentfiltering/allow-after-will-send-request.html  **nav target**
+            (file test):contentfiltering/resources/pass.html (in frame "<!--framePath //<!--frame0-->-->")
+===============================================
diff --git a/LayoutTests/contentfiltering/allow-never-expected.html b/LayoutTests/contentfiltering/allow-never-expected.html
deleted file mode 100644 (file)
index 645112f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<iframe src="resources/pass.html"></iframe>
diff --git a/LayoutTests/contentfiltering/allow-never-expected.txt b/LayoutTests/contentfiltering/allow-never-expected.txt
new file mode 100644 (file)
index 0000000..39f7206
--- /dev/null
@@ -0,0 +1,26 @@
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: resources/pass.html 
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):contentfiltering/allow-never.html  **nav target**
+            (file test):contentfiltering/resources/pass.html (in frame "<!--framePath //<!--frame0-->-->")
+===============================================
diff --git a/LayoutTests/contentfiltering/block-after-add-data-expected.html b/LayoutTests/contentfiltering/block-after-add-data-expected.html
deleted file mode 100644 (file)
index 645112f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<iframe src="resources/pass.html"></iframe>
diff --git a/LayoutTests/contentfiltering/block-after-add-data-expected.txt b/LayoutTests/contentfiltering/block-after-add-data-expected.txt
new file mode 100644 (file)
index 0000000..876a994
--- /dev/null
@@ -0,0 +1,28 @@
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: resources/fail.html 
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFailProvisionalLoadWithError
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):contentfiltering/block-after-add-data.html  **nav target**
+            (file test):contentfiltering/resources/fail.html (in frame "<!--framePath //<!--frame0-->-->")
+===============================================
diff --git a/LayoutTests/contentfiltering/block-after-add-data-then-allow-unblock-expected.html b/LayoutTests/contentfiltering/block-after-add-data-then-allow-unblock-expected.html
deleted file mode 100644 (file)
index 645112f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<iframe src="resources/pass.html"></iframe>
diff --git a/LayoutTests/contentfiltering/block-after-add-data-then-allow-unblock-expected.txt b/LayoutTests/contentfiltering/block-after-add-data-then-allow-unblock-expected.txt
new file mode 100644 (file)
index 0000000..441c37e
--- /dev/null
@@ -0,0 +1,35 @@
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: resources/pass.html 
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFailProvisionalLoadWithError
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: x-apple-content-filter://mock-unblock 
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):contentfiltering/block-after-add-data-then-allow-unblock.html  **nav target**
+            (file test):contentfiltering/resources/pass.html (in frame "<!--framePath //<!--frame0-->-->")
+===============================================
diff --git a/LayoutTests/contentfiltering/block-after-add-data-then-deny-unblock-expected.html b/LayoutTests/contentfiltering/block-after-add-data-then-deny-unblock-expected.html
deleted file mode 100644 (file)
index 645112f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<iframe src="resources/pass.html"></iframe>
diff --git a/LayoutTests/contentfiltering/block-after-add-data-then-deny-unblock-expected.txt b/LayoutTests/contentfiltering/block-after-add-data-then-deny-unblock-expected.txt
new file mode 100644 (file)
index 0000000..a48ca11
--- /dev/null
@@ -0,0 +1,30 @@
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: resources/fail.html 
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFailProvisionalLoadWithError
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: x-apple-content-filter://mock-unblock 
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):contentfiltering/block-after-add-data-then-deny-unblock.html  **nav target**
+            (file test):contentfiltering/resources/fail.html (in frame "<!--framePath //<!--frame0-->-->")
+===============================================
diff --git a/LayoutTests/contentfiltering/block-after-finished-adding-data-expected.html b/LayoutTests/contentfiltering/block-after-finished-adding-data-expected.html
deleted file mode 100644 (file)
index 645112f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<iframe src="resources/pass.html"></iframe>
diff --git a/LayoutTests/contentfiltering/block-after-finished-adding-data-expected.txt b/LayoutTests/contentfiltering/block-after-finished-adding-data-expected.txt
new file mode 100644 (file)
index 0000000..0caf086
--- /dev/null
@@ -0,0 +1,28 @@
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: resources/fail.html 
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFailProvisionalLoadWithError
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):contentfiltering/block-after-finished-adding-data.html  **nav target**
+            (file test):contentfiltering/resources/fail.html (in frame "<!--framePath //<!--frame0-->-->")
+===============================================
diff --git a/LayoutTests/contentfiltering/block-after-finished-adding-data-then-allow-unblock-expected.html b/LayoutTests/contentfiltering/block-after-finished-adding-data-then-allow-unblock-expected.html
deleted file mode 100644 (file)
index 645112f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<iframe src="resources/pass.html"></iframe>
diff --git a/LayoutTests/contentfiltering/block-after-finished-adding-data-then-allow-unblock-expected.txt b/LayoutTests/contentfiltering/block-after-finished-adding-data-then-allow-unblock-expected.txt
new file mode 100644 (file)
index 0000000..26a80f2
--- /dev/null
@@ -0,0 +1,35 @@
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: resources/pass.html 
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFailProvisionalLoadWithError
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: x-apple-content-filter://mock-unblock 
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):contentfiltering/block-after-finished-adding-data-then-allow-unblock.html  **nav target**
+            (file test):contentfiltering/resources/pass.html (in frame "<!--framePath //<!--frame0-->-->")
+===============================================
diff --git a/LayoutTests/contentfiltering/block-after-finished-adding-data-then-deny-unblock-expected.html b/LayoutTests/contentfiltering/block-after-finished-adding-data-then-deny-unblock-expected.html
deleted file mode 100644 (file)
index 645112f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<iframe src="resources/pass.html"></iframe>
diff --git a/LayoutTests/contentfiltering/block-after-finished-adding-data-then-deny-unblock-expected.txt b/LayoutTests/contentfiltering/block-after-finished-adding-data-then-deny-unblock-expected.txt
new file mode 100644 (file)
index 0000000..eedb252
--- /dev/null
@@ -0,0 +1,30 @@
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: resources/fail.html 
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFailProvisionalLoadWithError
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: x-apple-content-filter://mock-unblock 
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):contentfiltering/block-after-finished-adding-data-then-deny-unblock.html  **nav target**
+            (file test):contentfiltering/resources/fail.html (in frame "<!--framePath //<!--frame0-->-->")
+===============================================
diff --git a/LayoutTests/contentfiltering/block-after-response-expected.html b/LayoutTests/contentfiltering/block-after-response-expected.html
deleted file mode 100644 (file)
index 645112f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<iframe src="resources/pass.html"></iframe>
diff --git a/LayoutTests/contentfiltering/block-after-response-expected.txt b/LayoutTests/contentfiltering/block-after-response-expected.txt
new file mode 100644 (file)
index 0000000..dc419f4
--- /dev/null
@@ -0,0 +1,28 @@
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: resources/fail.html 
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFailProvisionalLoadWithError
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):contentfiltering/block-after-response.html  **nav target**
+            (file test):contentfiltering/resources/fail.html (in frame "<!--framePath //<!--frame0-->-->")
+===============================================
diff --git a/LayoutTests/contentfiltering/block-after-response-then-allow-unblock-expected.html b/LayoutTests/contentfiltering/block-after-response-then-allow-unblock-expected.html
deleted file mode 100644 (file)
index 645112f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<iframe src="resources/pass.html"></iframe>
diff --git a/LayoutTests/contentfiltering/block-after-response-then-allow-unblock-expected.txt b/LayoutTests/contentfiltering/block-after-response-then-allow-unblock-expected.txt
new file mode 100644 (file)
index 0000000..4b9ff9e
--- /dev/null
@@ -0,0 +1,35 @@
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: resources/pass.html 
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFailProvisionalLoadWithError
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: x-apple-content-filter://mock-unblock 
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):contentfiltering/block-after-response-then-allow-unblock.html  **nav target**
+            (file test):contentfiltering/resources/pass.html (in frame "<!--framePath //<!--frame0-->-->")
+===============================================
diff --git a/LayoutTests/contentfiltering/block-after-response-then-deny-unblock-expected.html b/LayoutTests/contentfiltering/block-after-response-then-deny-unblock-expected.html
deleted file mode 100644 (file)
index 645112f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<iframe src="resources/pass.html"></iframe>
diff --git a/LayoutTests/contentfiltering/block-after-response-then-deny-unblock-expected.txt b/LayoutTests/contentfiltering/block-after-response-then-deny-unblock-expected.txt
new file mode 100644 (file)
index 0000000..8686bae
--- /dev/null
@@ -0,0 +1,30 @@
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: resources/fail.html 
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFailProvisionalLoadWithError
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: x-apple-content-filter://mock-unblock 
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):contentfiltering/block-after-response-then-deny-unblock.html  **nav target**
+            (file test):contentfiltering/resources/fail.html (in frame "<!--framePath //<!--frame0-->-->")
+===============================================
diff --git a/LayoutTests/contentfiltering/block-after-will-send-request-expected.html b/LayoutTests/contentfiltering/block-after-will-send-request-expected.html
deleted file mode 100644 (file)
index 645112f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<iframe src="resources/pass.html"></iframe>
diff --git a/LayoutTests/contentfiltering/block-after-will-send-request-expected.txt b/LayoutTests/contentfiltering/block-after-will-send-request-expected.txt
new file mode 100644 (file)
index 0000000..2d8c754
--- /dev/null
@@ -0,0 +1,28 @@
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: resources/fail.html 
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFailProvisionalLoadWithError
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):contentfiltering/block-after-will-send-request.html  **nav target**
+            about:blank (in frame "<!--framePath //<!--frame0-->-->")
+===============================================
diff --git a/LayoutTests/contentfiltering/block-after-will-send-request-then-allow-unblock-expected.html b/LayoutTests/contentfiltering/block-after-will-send-request-then-allow-unblock-expected.html
deleted file mode 100644 (file)
index 645112f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<iframe src="resources/pass.html"></iframe>
diff --git a/LayoutTests/contentfiltering/block-after-will-send-request-then-allow-unblock-expected.txt b/LayoutTests/contentfiltering/block-after-will-send-request-then-allow-unblock-expected.txt
new file mode 100644 (file)
index 0000000..d656c67
--- /dev/null
@@ -0,0 +1,35 @@
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: resources/pass.html 
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFailProvisionalLoadWithError
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: x-apple-content-filter://mock-unblock 
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):contentfiltering/block-after-will-send-request-then-allow-unblock.html  **nav target**
+            (file test):contentfiltering/resources/pass.html (in frame "<!--framePath //<!--frame0-->-->")
+===============================================
diff --git a/LayoutTests/contentfiltering/block-after-will-send-request-then-deny-unblock-expected.html b/LayoutTests/contentfiltering/block-after-will-send-request-then-deny-unblock-expected.html
deleted file mode 100644 (file)
index 645112f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<iframe src="resources/pass.html"></iframe>
diff --git a/LayoutTests/contentfiltering/block-after-will-send-request-then-deny-unblock-expected.txt b/LayoutTests/contentfiltering/block-after-will-send-request-then-deny-unblock-expected.txt
new file mode 100644 (file)
index 0000000..ad1bde0
--- /dev/null
@@ -0,0 +1,30 @@
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: resources/fail.html 
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFailProvisionalLoadWithError
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: x-apple-content-filter://mock-unblock 
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):contentfiltering/block-after-will-send-request-then-deny-unblock.html  **nav target**
+            about:blank (in frame "<!--framePath //<!--frame0-->-->")
+===============================================
diff --git a/LayoutTests/contentfiltering/block-never-expected.html b/LayoutTests/contentfiltering/block-never-expected.html
deleted file mode 100644 (file)
index 645112f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<iframe src="resources/pass.html"></iframe>
diff --git a/LayoutTests/contentfiltering/block-never-expected.txt b/LayoutTests/contentfiltering/block-never-expected.txt
new file mode 100644 (file)
index 0000000..b140744
--- /dev/null
@@ -0,0 +1,26 @@
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - willPerformClientRedirectToURL: resources/pass.html 
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCancelClientRedirectForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):contentfiltering/block-never.html  **nav target**
+            (file test):contentfiltering/resources/pass.html (in frame "<!--framePath //<!--frame0-->-->")
+===============================================
index 9ae4fed..61bf457 100644 (file)
@@ -33,7 +33,11 @@ function _doTest(decisionPoint, decision, decideAfterUnblockRequest)
         }, false);
         iframe.contentDocument.location = settings.unblockRequestURL;
     }, false);
-    iframe.src = "data:text/html,<!DOCTYPE html><body>" + (blockedStringText === "FAIL" ? "PASS" : "FAIL");
+
+    if (blockedStringText === "FAIL")
+        iframe.src = "resources/pass.html";
+    else
+        iframe.src = "resources/fail.html";
 }
 
 function testContentFiltering(decisionPoint, decision, decideAfterUnblockRequest)
@@ -49,6 +53,10 @@ function testContentFiltering(decisionPoint, decision, decideAfterUnblockRequest
     }
 
     window.testRunner.waitUntilDone();
+    window.testRunner.dumpAsText();
+    window.testRunner.dumpChildFramesAsText();
+    window.testRunner.dumpBackForwardList();
+    window.testRunner.dumpFrameLoadCallbacks();
     window.addEventListener("load", function(event) {
         _doTest(decisionPoint, decision, decideAfterUnblockRequest);
     }, false);
index c5f9113..14cb04c 100644 (file)
@@ -1,3 +1,70 @@
+2016-07-07  Andy Estes  <aestes@apple.com>
+
+        [Content Filtering] Load blocked pages more like other error pages are loaded
+        https://bugs.webkit.org/show_bug.cgi?id=159485
+        <rdar://problem/26014076>
+
+        Reviewed by Brady Eidson.
+
+        Content filter blocked pages were being loaded by cancelling the provisional load of the
+        page that was blocked and then scheduling a navigation to the content filter error page.
+        Some clients would not expect a new, Web process-initiated provisional navigation to start
+        after a cancellation, though, and this would put them in a bad state.
+        
+        This patch changes blocked page loading to behave more like loading other error pages.
+        Specifically:
+        1. didFailProvisionalLoad is dispatched with a new, non-cancellation error code.
+        2. The blocked page is loaded immediately after dispatching didFailProvisionalLoad, which
+           prevents FrameLoader from creating a new back-forward list item for the substitute data load.
+        3. A substitute data load initiated by the client for the blocked URL is ignored if
+           ContentFilter will display its own error page.
+        4. A file: URL is used instead of a custom scheme for the base URL of the blocked page,
+           since some clients expect this.
+
+        Updated existing tests to capture frame load delegate callbacks and the back forward list.
+        Added new API tests: ContentFiltering.LoadAlternate*.
+
+        * English.lproj/Localizable.strings: Added a WebKitErrorFrameLoadBlockedByContentFilter description.
+        * Resources/ContentFilterBlockedPage.html: Added.
+        * WebCore.xcodeproj/project.pbxproj: Added ContentFilterBlockedPage.html as a frameowrk resource.
+        * loader/ContentFilter.cpp:
+        (WebCore::ContentFilter::stopFilteringMainResource): Only set m_state to Stopped if not
+        already Blocked, so that we don't forget this ContentFilter was blocked when calling
+        cancelMailResourceLoad() in didDecide().
+        (WebCore::ContentFilter::didDecide): Moved code from DocumentLoader::contentFilterDidBlock() to here.
+        Created a blockedByContentFilterError() and called cancelMainResourceLoad().
+        (WebCore::blockedPageURL): Returned a file: URL to ContentFilterBlockedPage.html in WebCore.framework.
+        (WebCore::ContentFilter::continueAfterSubstituteDataRequest): If the substitute data load
+        is for the same failingURL as the currently-displayed blocked page, ignore it.
+        (WebCore::ContentFilter::handleProvisionalLoadFailure): Load the blocked page if m_state is Blocked
+        and the ResourceError matches the error we used when previously calling cancelMainResourceLoad().
+        (WebCore::ContentFilter::unblockHandler): Deleted.
+        (WebCore::ContentFilter::replacementData): Deleted.
+        (WebCore::ContentFilter::unblockRequestDeniedScript): Deleted.
+        * loader/ContentFilter.h:
+        * loader/DocumentLoader.cpp:
+        (WebCore::DocumentLoader::contentFilter): Returned m_contentFilter.
+        (WebCore::DocumentLoader::installContentFilterUnblockHandler): Deleted.
+        (WebCore::DocumentLoader::contentFilterDidBlock): Deleted.
+        * loader/DocumentLoader.h:
+        * loader/EmptyClients.h: Added a default implementation of blockedByContentFilterError().
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::load): If m_loadType was already RedirectWithLockedBackForwardList
+        and we are loading subsitute data for a failing URL, continue to use RedirectWithLockedBackForwardList.
+        This prevents a new back-forward list item from being created when loading a blocked page in a subframe.
+        (WebCore::FrameLoader::checkLoadCompleteForThisFrame):
+        Called ContentFilter::handleProvisionalLoadFailure() after dispatchDidFailProvisionalLoad().
+        (WebCore::FrameLoader::blockedByContentFilterError): Called FrameLoaderClient::blockedByContentFilterError().
+        * loader/FrameLoader.h:
+        * loader/FrameLoaderClient.h:
+        * loader/NavigationScheduler.cpp:
+        (WebCore::ScheduledSubstituteDataLoad::ScheduledSubstituteDataLoad): Deleted.
+        (WebCore::NavigationScheduler::scheduleSubstituteDataLoad): Deleted.
+        * loader/NavigationScheduler.h:
+        * loader/PolicyChecker.cpp:
+        (WebCore::PolicyChecker::checkNavigationPolicy): Ignored a substitute data load for a
+        failing URL if ContentFilter::continueAfterSubstituteDataRequest() returns false.
+
 2016-07-07  Chris Dumez  <cdumez@apple.com>
 
         td / th should be exposed as HTMLTableCellElement objects
index 5eba43e..3a822c6 100644 (file)
 /* An ARIA accessibility group that acts as an dialog. */
 "web dialog" = "web dialog";
 
+/* WebKitErrorFrameLoadBlockedByContentFilter description */
+"The URL was blocked by a content filter" = "The URL was blocked by a content filter";
diff --git a/Source/WebCore/Resources/ContentFilterBlockedPage.html b/Source/WebCore/Resources/ContentFilterBlockedPage.html
new file mode 100644 (file)
index 0000000..c15f74f
--- /dev/null
@@ -0,0 +1 @@
+<!-- This file intentionally left blank -->
index 43f99e8..e400e96 100644 (file)
                A19D93471A9FEC7200B46C24 /* WebFilterEvaluatorSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = A19D93451A9FEC7200B46C24 /* WebFilterEvaluatorSPI.h */; };
                A19D934A1AA11B1E00B46C24 /* NetworkExtensionContentFilter.mm in Sources */ = {isa = PBXBuildFile; fileRef = A19D93481AA11B1E00B46C24 /* NetworkExtensionContentFilter.mm */; };
                A19D934B1AA11B1E00B46C24 /* NetworkExtensionContentFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = A19D93491AA11B1E00B46C24 /* NetworkExtensionContentFilter.h */; };
+               A1AA9AB91D23911500FEADB3 /* ContentFilterBlockedPage.html in Resources */ = {isa = PBXBuildFile; fileRef = A1AA9AB81D23911500FEADB3 /* ContentFilterBlockedPage.html */; };
                A1B5B29E1AAA846E008B6042 /* MockContentFilterSettings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1B5B29C1AAA846E008B6042 /* MockContentFilterSettings.cpp */; };
                A1B5B29F1AAA846F008B6042 /* MockContentFilterSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = A1B5B29D1AAA846E008B6042 /* MockContentFilterSettings.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A1BF6B821AA96C7D00AF4A8A /* MockContentFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1BF6B801AA96C7D00AF4A8A /* MockContentFilter.cpp */; };
                A19D93451A9FEC7200B46C24 /* WebFilterEvaluatorSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebFilterEvaluatorSPI.h; sourceTree = "<group>"; };
                A19D93481AA11B1E00B46C24 /* NetworkExtensionContentFilter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NetworkExtensionContentFilter.mm; sourceTree = "<group>"; };
                A19D93491AA11B1E00B46C24 /* NetworkExtensionContentFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkExtensionContentFilter.h; sourceTree = "<group>"; };
+               A1AA9AB81D23911500FEADB3 /* ContentFilterBlockedPage.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ContentFilterBlockedPage.html; sourceTree = "<group>"; };
                A1B5B29C1AAA846E008B6042 /* MockContentFilterSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MockContentFilterSettings.cpp; sourceTree = "<group>"; };
                A1B5B29D1AAA846E008B6042 /* MockContentFilterSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockContentFilterSettings.h; sourceTree = "<group>"; };
                A1BF6B801AA96C7D00AF4A8A /* MockContentFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MockContentFilter.cpp; sourceTree = "<group>"; };
                        children = (
                                CD0DBB3E142274E600280263 /* audio */,
                                65998A650E5F5FD3004E097A /* images */,
+                               A1AA9AB81D23911500FEADB3 /* ContentFilterBlockedPage.html */,
                                A11E8C001B1E28BE0003A7C7 /* copyCursor.png */,
                                7CC7E3D617208C0F003C5277 /* IDNScriptWhiteList.txt */,
                                2D9F0E1214FF1CBF00BA0FF7 /* linearSRGB.icc */,
                                93153BDA14181F7A00FCF5BE /* missingImage@2x.png in Resources */,
                                318891611AB7EEA100EA627B /* missingImage@3x.png in Resources */,
                                A11E8C061B1E28FA0003A7C7 /* moveCursor.png in Resources */,
+                               A1AA9AB91D23911500FEADB3 /* ContentFilterBlockedPage.html in Resources */,
                                A11E8C071B1E28FE0003A7C7 /* northEastSouthWestResizeCursor.png in Resources */,
                                A11E8C081B1E29020003A7C7 /* northSouthResizeCursor.png in Resources */,
                                A11E8C091B1E29070003A7C7 /* northWestSouthEastResizeCursor.png in Resources */,
index 25c69e4..eec68b5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "CachedRawResource.h"
 #include "ContentFilterUnblockHandler.h"
 #include "DocumentLoader.h"
+#include "Frame.h"
+#include "FrameLoadRequest.h"
+#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
 #include "Logging.h"
 #include "NetworkExtensionContentFilter.h"
 #include "ParentalControlsContentFilter.h"
+#include "ScriptController.h"
 #include "SharedBuffer.h"
 #include <wtf/NeverDestroyed.h>
+#include <wtf/TemporaryChange.h>
 #include <wtf/Vector.h>
 
 #if !LOG_DISABLED
@@ -119,34 +125,11 @@ void ContentFilter::startFilteringMainResource(CachedRawResource& resource)
 
 void ContentFilter::stopFilteringMainResource()
 {
-    m_state = State::Stopped;
+    if (m_state != State::Blocked)
+        m_state = State::Stopped;
     m_mainResource = nullptr;
 }
 
-ContentFilterUnblockHandler ContentFilter::unblockHandler() const
-{
-    ASSERT(m_state == State::Blocked);
-    ASSERT(m_blockingContentFilter);
-    ASSERT(m_blockingContentFilter->didBlockData());
-    return m_blockingContentFilter->unblockHandler();
-}
-
-Ref<SharedBuffer> ContentFilter::replacementData() const
-{
-    ASSERT(m_state == State::Blocked);
-    ASSERT(m_blockingContentFilter);
-    ASSERT(m_blockingContentFilter->didBlockData());
-    return m_blockingContentFilter->replacementData();
-}
-
-String ContentFilter::unblockRequestDeniedScript() const
-{
-    ASSERT(m_state == State::Blocked);
-    ASSERT(m_blockingContentFilter);
-    ASSERT(m_blockingContentFilter->didBlockData());
-    return m_blockingContentFilter->unblockRequestDeniedScript();
-}
-
 bool ContentFilter::continueAfterResponseReceived(CachedResource* resource, const ResourceResponse& response)
 {
     ASSERT_UNUSED(resource, resource == m_mainResource);
@@ -236,8 +219,24 @@ void ContentFilter::didDecide(State state)
     ASSERT(state == State::Allowed || state == State::Blocked);
     LOG(ContentFiltering, "ContentFilter decided load should be %s for main resource at <%s>.\n", state == State::Allowed ? "allowed" : "blocked", m_mainResource ? m_mainResource->url().string().ascii().data() : "");
     m_state = state;
-    if (m_state == State::Blocked)
-        m_documentLoader.contentFilterDidBlock();
+    if (m_state != State::Blocked)
+        return;
+
+    ContentFilterUnblockHandler unblockHandler { m_blockingContentFilter->unblockHandler() };
+    unblockHandler.setUnreachableURL(m_documentLoader.documentURL());
+    RefPtr<Frame> frame { m_documentLoader.frame() };
+    String unblockRequestDeniedScript { m_blockingContentFilter->unblockRequestDeniedScript() };
+    if (!unblockRequestDeniedScript.isEmpty() && frame) {
+        static_assert(std::is_base_of<ThreadSafeRefCounted<Frame>, Frame>::value, "Frame must be ThreadSafeRefCounted.");
+        unblockHandler.wrapWithDecisionHandler([frame = WTFMove(frame), script = unblockRequestDeniedScript.isolatedCopy()](bool unblocked) {
+            if (!unblocked)
+                frame->script().executeScript(script);
+        });
+    }
+    m_documentLoader.frameLoader()->client().contentFilterDidBlockLoad(WTFMove(unblockHandler));
+
+    m_blockedError = m_documentLoader.frameLoader()->blockedByContentFilterError(m_documentLoader.request());
+    m_documentLoader.cancelMainResourceLoad(m_blockedError);
 }
 
 void ContentFilter::deliverResourceData(CachedResource& resource)
@@ -248,6 +247,51 @@ void ContentFilter::deliverResourceData(CachedResource& resource)
         m_documentLoader.dataReceived(&resource, resourceBuffer->data(), resourceBuffer->size());
 }
 
+static const URL& blockedPageURL()
+{
+    static LazyNeverDestroyed<URL> blockedPageURL;
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        auto webCoreBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.WebCore"));
+        auto blockedPageCFURL = adoptCF(CFBundleCopyResourceURL(webCoreBundle, CFSTR("ContentFilterBlockedPage"), CFSTR("html"), nullptr));
+        blockedPageURL.construct(blockedPageCFURL.get());
+    });
+
+    return blockedPageURL;
+}
+
+bool ContentFilter::continueAfterSubstituteDataRequest(const DocumentLoader& activeLoader, const SubstituteData& substituteData)
+{
+    if (auto contentFilter = activeLoader.contentFilter()) {
+        if (contentFilter->m_state == State::Blocked && !contentFilter->m_isLoadingBlockedPage)
+            return contentFilter->m_blockedError.failingURL() != substituteData.failingURL();
+    }
+
+    if (activeLoader.request().url() == blockedPageURL()) {
+        ASSERT(activeLoader.substituteData().isValid());
+        return activeLoader.substituteData().failingURL() != substituteData.failingURL();
+    }
+
+    return true;
+}
+
+void ContentFilter::handleProvisionalLoadFailure(const ResourceError& error)
+{
+    if (m_state != State::Blocked)
+        return;
+
+    if (m_blockedError.errorCode() != error.errorCode() || m_blockedError.domain() != error.domain())
+        return;
+
+    ASSERT(m_blockedError.failingURL() == error.failingURL());
+
+    RefPtr<SharedBuffer> replacementData { m_blockingContentFilter->replacementData() };
+    ResourceResponse response { URL(), ASCIILiteral("text/html"), replacementData->size(), ASCIILiteral("UTF-8") };
+    SubstituteData substituteData { WTFMove(replacementData), error.failingURL(), response, SubstituteData::SessionHistoryVisibility::Hidden };
+    TemporaryChange<bool> loadingBlockedPage { m_isLoadingBlockedPage, true };
+    m_documentLoader.frameLoader()->load(FrameLoadRequest(m_documentLoader.frame(), blockedPageURL(), ShouldOpenExternalURLsPolicy::ShouldNotAllow, substituteData));
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(CONTENT_FILTERING)
index 0d20fc7..a850c1b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef ContentFilter_h
-#define ContentFilter_h
+#pragma once
 
 #if ENABLE(CONTENT_FILTERING)
 
 #include "CachedResourceHandle.h"
 #include "PlatformContentFilter.h"
+#include "ResourceError.h"
 #include <functional>
 #include <wtf/Vector.h>
 
 namespace WebCore {
 
 class CachedRawResource;
-class ContentFilterUnblockHandler;
 class DocumentLoader;
 class ResourceRequest;
 class ResourceResponse;
-class SharedBuffer;
+class SubstituteData;
 
 class ContentFilter {
     WTF_MAKE_FAST_ALLOCATED;
@@ -62,9 +61,8 @@ public:
     bool continueAfterDataReceived(CachedResource*, const char* data, int length);
     bool continueAfterNotifyFinished(CachedResource*);
 
-    ContentFilterUnblockHandler unblockHandler() const;
-    Ref<SharedBuffer> replacementData() const;
-    String unblockRequestDeniedScript() const;
+    static bool continueAfterSubstituteDataRequest(const DocumentLoader& activeLoader, const SubstituteData&);
+    void handleProvisionalLoadFailure(const ResourceError&);
 
 private:
     using State = PlatformContentFilter::State;
@@ -88,6 +86,8 @@ private:
     CachedResourceHandle<CachedRawResource> m_mainResource;
     PlatformContentFilter* m_blockingContentFilter { nullptr };
     State m_state { State::Stopped };
+    ResourceError m_blockedError;
+    bool m_isLoadingBlockedPage { false };
 };
 
 template <typename T>
@@ -100,5 +100,3 @@ ContentFilter::Type ContentFilter::type()
 } // namespace WebCore
 
 #endif // ENABLE(CONTENT_FILTERING)
-
-#endif // ContentFilter_h
index a535918..76c201c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2008, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
  * Copyright (C) 2011 Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -63,7 +63,6 @@
 #include "ResourceHandle.h"
 #include "ResourceLoadObserver.h"
 #include "SchemeRegistry.h"
-#include "ScriptController.h"
 #include "SecurityPolicy.h"
 #include "Settings.h"
 #include "SubresourceLoader.h"
@@ -1708,37 +1707,10 @@ void DocumentLoader::addPendingContentExtensionDisplayNoneSelector(const String&
 #endif
 
 #if ENABLE(CONTENT_FILTERING)
-void DocumentLoader::installContentFilterUnblockHandler(ContentFilter& contentFilter)
-{
-    ContentFilterUnblockHandler unblockHandler { contentFilter.unblockHandler() };
-    unblockHandler.setUnreachableURL(documentURL());
-    RefPtr<Frame> frame { this->frame() };
-    String unblockRequestDeniedScript { contentFilter.unblockRequestDeniedScript() };
-    if (!unblockRequestDeniedScript.isEmpty() && frame) {
-        static_assert(std::is_base_of<ThreadSafeRefCounted<Frame>, Frame>::value, "Frame must be ThreadSafeRefCounted.");
-        unblockHandler.wrapWithDecisionHandler([frame = WTFMove(frame), script = unblockRequestDeniedScript.isolatedCopy()](bool unblocked) {
-            if (!unblocked)
-                frame->script().executeScript(script);
-        });
-    }
-    frameLoader()->client().contentFilterDidBlockLoad(WTFMove(unblockHandler));
-}
-
-void DocumentLoader::contentFilterDidBlock()
+ContentFilter* DocumentLoader::contentFilter() const
 {
-    ASSERT(m_contentFilter);
-
-    installContentFilterUnblockHandler(*m_contentFilter);
-
-    URL blockedURL;
-    blockedURL.setProtocol(ContentFilter::urlScheme());
-    blockedURL.setHost(ASCIILiteral("blocked-page"));
-    auto replacementData = m_contentFilter->replacementData();
-    ResourceResponse response(URL(), ASCIILiteral("text/html"), replacementData->size(), ASCIILiteral("UTF-8"));
-    SubstituteData substituteData { adoptRef(&replacementData.leakRef()), documentURL(), response, SubstituteData::SessionHistoryVisibility::Hidden };
-    frame()->navigationScheduler().scheduleSubstituteDataLoad(blockedURL, substituteData);
+    return m_contentFilter.get();
 }
 #endif
 
-
 } // namespace WebCore
index e2685bb..dd9b04b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
  * Copyright (C) 2011 Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,8 +27,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef DocumentLoader_h
-#define DocumentLoader_h
+#pragma once
 
 #include "CachedRawResourceClient.h"
 #include "CachedResourceHandle.h"
@@ -68,6 +67,7 @@ namespace WebCore {
     class ArchiveResourceCollection;
     class CachedRawResource;
     class CachedResourceLoader;
+    class ContentFilter;
     class FormState;
     class Frame;
     class FrameLoader;
@@ -77,15 +77,12 @@ namespace WebCore {
     class SubresourceLoader;
     class SubstituteResource;
 
-#if ENABLE(CONTENT_FILTERING)
-    class ContentFilter;
-#endif
-
     typedef HashMap<unsigned long, RefPtr<ResourceLoader>> ResourceLoaderMap;
     typedef Vector<ResourceResponse> ResponseVector;
 
     class DocumentLoader : public RefCounted<DocumentLoader>, private CachedRawResourceClient {
         WTF_MAKE_FAST_ALLOCATED;
+        friend class ContentFilter;
     public:
         static Ref<DocumentLoader> create(const ResourceRequest& request, const SubstituteData& data)
         {
@@ -285,6 +282,10 @@ namespace WebCore {
         void setShouldOpenExternalURLsPolicy(ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy) { m_shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicy; }
         ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicyToPropagate() const;
 
+#if ENABLE(CONTENT_FILTERING)
+        ContentFilter* contentFilter() const;
+#endif
+
     protected:
         WEBCORE_EXPORT DocumentLoader(const ResourceRequest&, const SubstituteData&);
 
@@ -348,12 +349,6 @@ namespace WebCore {
         void cancelPolicyCheckIfNeeded();
         void becomeMainResourceClient();
 
-#if ENABLE(CONTENT_FILTERING)
-        friend class ContentFilter;
-        void installContentFilterUnblockHandler(ContentFilter&);
-        void contentFilterDidBlock();
-#endif
-
         Frame* m_frame;
         Ref<CachedResourceLoader> m_cachedResourceLoader;
 
@@ -479,5 +474,3 @@ namespace WebCore {
     }
 
 }
-
-#endif // DocumentLoader_h
index b078ff8..146a389 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2006 Eric Seidel (eric@webkit.org)
- * Copyright (C) 2008-2012, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2016 Apple Inc. All rights reserved.
  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
  * Copyright (C) 2012 Samsung Electronics. All rights reserved.
  *
@@ -336,6 +336,9 @@ public:
     ResourceError blockedByContentBlockerError(const ResourceRequest&) override { return { }; }
     ResourceError cannotShowURLError(const ResourceRequest&) override { return { }; }
     ResourceError interruptedForPolicyChangeError(const ResourceRequest&) override { return { }; }
+#if ENABLE(CONTENT_FILTERING)
+    ResourceError blockedByContentFilterError(const ResourceRequest&) override { return { }; }
+#endif
 
     ResourceError cannotShowMIMETypeError(const ResourceResponse&) override { return { }; }
     ResourceError fileDoesNotExistError(const ResourceResponse&) override { return { }; }
index b322742..7bd02d5 100644 (file)
@@ -43,6 +43,7 @@
 #include "CachedResourceLoader.h"
 #include "Chrome.h"
 #include "ChromeClient.h"
+#include "ContentFilter.h"
 #include "ContentSecurityPolicy.h"
 #include "DOMImplementation.h"
 #include "DOMWindow.h"
@@ -1339,6 +1340,8 @@ void FrameLoader::load(DocumentLoader* newDocumentLoader)
         type = FrameLoadType::Same;
     } else if (shouldTreatURLAsSameAsCurrent(newDocumentLoader->unreachableURL()) && m_loadType == FrameLoadType::Reload)
         type = FrameLoadType::Reload;
+    else if (m_loadType == FrameLoadType::RedirectWithLockedBackForwardList && !newDocumentLoader->unreachableURL().isEmpty() && newDocumentLoader->substituteData().isValid())
+        type = FrameLoadType::RedirectWithLockedBackForwardList;
     else
         type = FrameLoadType::Standard;
 
@@ -2241,6 +2244,10 @@ void FrameLoader::checkLoadCompleteForThisFrame()
             if (!pdl->isLoadingInAPISense() || pdl->isStopping()) {
                 m_provisionalLoadErrorBeingHandledURL = m_provisionalDocumentLoader->url();
                 m_client.dispatchDidFailProvisionalLoad(error);
+#if ENABLE(CONTENT_FILTERING)
+                if (auto contentFilter = pdl->contentFilter())
+                    contentFilter->handleProvisionalLoadFailure(error);
+#endif
                 m_provisionalLoadErrorBeingHandledURL = { };
 
                 ASSERT(!pdl->isLoading());
@@ -3441,6 +3448,15 @@ ResourceError FrameLoader::blockedError(const ResourceRequest& request) const
     return error;
 }
 
+#if ENABLE(CONTENT_FILTERING)
+ResourceError FrameLoader::blockedByContentFilterError(const ResourceRequest& request) const
+{
+    ResourceError error = m_client.blockedByContentFilterError(request);
+    error.setType(ResourceError::Type::General);
+    return error;
+}
+#endif
+
 #if PLATFORM(IOS)
 RetainPtr<CFDictionaryRef> FrameLoader::connectionProperties(ResourceLoader* loader)
 {
index 0f08e77..6c3a5b4 100644 (file)
@@ -171,6 +171,9 @@ public:
     WEBCORE_EXPORT ResourceError cancelledError(const ResourceRequest&) const;
     WEBCORE_EXPORT ResourceError blockedByContentBlockerError(const ResourceRequest&) const;
     ResourceError blockedError(const ResourceRequest&) const;
+#if ENABLE(CONTENT_FILTERING)
+    ResourceError blockedByContentFilterError(const ResourceRequest&) const;
+#endif
 
     bool isHostedByObjectElement() const;
 
index d86c648..785fbe3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
  * Copyright (C) 2012 Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,8 +27,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef FrameLoaderClient_h
-#define FrameLoaderClient_h
+#pragma once
 
 #include "FrameLoaderTypes.h"
 #include "LayoutMilestones.h"
@@ -232,6 +231,9 @@ namespace WebCore {
         virtual ResourceError blockedByContentBlockerError(const ResourceRequest&) = 0;
         virtual ResourceError cannotShowURLError(const ResourceRequest&) = 0;
         virtual ResourceError interruptedForPolicyChangeError(const ResourceRequest&) = 0;
+#if ENABLE(CONTENT_FILTERING)
+        virtual ResourceError blockedByContentFilterError(const ResourceRequest&) = 0;
+#endif
 
         virtual ResourceError cannotShowMIMETypeError(const ResourceResponse&) = 0;
         virtual ResourceError fileDoesNotExistError(const ResourceResponse&) = 0;
@@ -355,5 +357,3 @@ namespace WebCore {
     };
 
 } // namespace WebCore
-
-#endif // FrameLoaderClient_h
index 4f8d0cf..0441831 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2010, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
  * Copyright (C) 2009 Adam Barth. All rights reserved.
@@ -323,26 +323,6 @@ private:
     Document& m_originDocument;
 };
 
-class ScheduledSubstituteDataLoad : public ScheduledNavigation {
-public:
-    ScheduledSubstituteDataLoad(const URL& baseURL, const SubstituteData& substituteData)
-        : ScheduledNavigation { 0, LockHistory::No, LockBackForwardList::No, false, false }
-        , m_baseURL { baseURL }
-        , m_substituteData { substituteData }
-    {
-    }
-
-    void fire(Frame& frame) override
-    {
-        UserGestureIndicator gestureIndicator { wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture };
-        frame.loader().load(FrameLoadRequest { &frame, m_baseURL, m_shouldOpenExternalURLsPolicy, m_substituteData });
-    }
-
-private:
-    URL m_baseURL;
-    SubstituteData m_substituteData;
-};
-
 NavigationScheduler::NavigationScheduler(Frame& frame)
     : m_frame(frame)
     , m_timer(*this, &NavigationScheduler::timerFired)
@@ -499,12 +479,6 @@ void NavigationScheduler::scheduleHistoryNavigation(int steps)
     schedule(std::make_unique<ScheduledHistoryNavigation>(steps));
 }
 
-void NavigationScheduler::scheduleSubstituteDataLoad(const URL& baseURL, const SubstituteData& substituteData)
-{
-    if (shouldScheduleNavigation())
-        schedule(std::make_unique<ScheduledSubstituteDataLoad>(baseURL, substituteData));
-}
-
 void NavigationScheduler::schedulePageBlock(Document& originDocument)
 {
     if (shouldScheduleNavigation())
index b5cedf4..49c43be 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
  * Copyright (C) 2009 Adam Barth. All rights reserved.
  *
@@ -28,8 +28,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef NavigationScheduler_h
-#define NavigationScheduler_h
+#pragma once
 
 #include "FrameLoaderTypes.h"
 #include "Timer.h"
@@ -42,7 +41,6 @@ class FormSubmission;
 class Frame;
 class ScheduledNavigation;
 class SecurityOrigin;
-class SubstituteData;
 class URL;
 
 class NavigationDisablerForBeforeUnload {
@@ -75,7 +73,6 @@ public:
     void scheduleFormSubmission(PassRefPtr<FormSubmission>);
     void scheduleRefresh(Document* initiatingDocument);
     void scheduleHistoryNavigation(int steps);
-    void scheduleSubstituteDataLoad(const URL& baseURL, const SubstituteData&);
     void schedulePageBlock(Document& originDocument);
 
     void startTimer();
@@ -98,5 +95,3 @@ private:
 };
 
 } // namespace WebCore
-
-#endif // NavigationScheduler_h
index 5aadd9a..29c6507 100644 (file)
@@ -31,6 +31,7 @@
 #include "config.h"
 #include "PolicyChecker.h"
 
+#include "ContentFilter.h"
 #include "ContentSecurityPolicy.h"
 #include "DOMWindow.h"
 #include "DocumentLoader.h"
@@ -91,10 +92,15 @@ void PolicyChecker::checkNavigationPolicy(const ResourceRequest& request, bool d
 
     // We are always willing to show alternate content for unreachable URLs;
     // treat it like a reload so it maintains the right state for b/f list.
-    if (loader->substituteData().isValid() && !loader->substituteData().failingURL().isEmpty()) {
+    auto& substituteData = loader->substituteData();
+    if (substituteData.isValid() && !substituteData.failingURL().isEmpty()) {
+        bool shouldContinue = true;
+#if ENABLE(CONTENT_FILTERING)
+        shouldContinue = ContentFilter::continueAfterSubstituteDataRequest(*m_frame.loader().activeDocumentLoader(), substituteData);
+#endif
         if (isBackForwardLoadType(m_loadType))
             m_loadType = FrameLoadType::Reload;
-        function(request, 0, true);
+        function(request, 0, shouldContinue);
         return;
     }
 
index 88ef96b..bd1db75 100644 (file)
@@ -1,3 +1,18 @@
+2016-07-07  Andy Estes  <aestes@apple.com>
+
+        [Content Filtering] Load blocked pages more like other error pages are loaded
+        https://bugs.webkit.org/show_bug.cgi?id=159485
+        <rdar://problem/26014076>
+
+        Reviewed by Brady Eidson.
+
+        * Misc/WebKitErrors.h: Defined WebKitErrorFrameLoadBlockedByContentFilter.
+        * Misc/WebKitErrors.m:
+        (registerErrors): Registered WebKitErrorDescriptionFrameLoadBlockedByContentFilter.
+        * WebCoreSupport/WebFrameLoaderClient.h:
+        * WebCoreSupport/WebFrameLoaderClient.mm:
+        (WebFrameLoaderClient::blockedByContentFilterError): Returned a ResourceError for WebKitErrorFrameLoadBlockedByContentFilter.
+
 2016-07-07  Alex Christensen  <achristensen@webkit.org>
 
         Use SocketProvider to create WebSocketChannels
index 0c0a51a..da57f61 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 Apple Inc.  All rights reserved.
+ * Copyright (C) 2003-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -38,11 +38,13 @@ extern NSString * const WebKitErrorPlugInPageURLStringKey;
     @constant WebKitErrorCannotShowMIMEType
     @constant WebKitErrorCannotShowURL
     @constant WebKitErrorFrameLoadInterruptedByPolicyChange
+    @constant WebKitErrorFrameLoadBlockedByContentFilter
 */
 enum {
     WebKitErrorCannotShowMIMEType =                             100,
     WebKitErrorCannotShowURL =                                  101,
     WebKitErrorFrameLoadInterruptedByPolicyChange =             102,
+    WebKitErrorFrameLoadBlockedByContentFilter =                105,
 };
 
 /*!
index 9834413..ef38ebf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 Apple Inc.  All rights reserved.
+ * Copyright (C) 2005-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,6 +45,7 @@ NSString * const WebKitErrorPlugInPageURLStringKey =    @"WebKitErrorPlugInPageU
 #define WebKitErrorDescriptionCannotShowURL UI_STRING_INTERNAL("The URL can’t be shown", "WebKitErrorCannotShowURL description")
 #define WebKitErrorDescriptionFrameLoadInterruptedByPolicyChange UI_STRING_INTERNAL("Frame load interrupted", "WebKitErrorFrameLoadInterruptedByPolicyChange description")
 #define WebKitErrorDescriptionCannotUseRestrictedPort UI_STRING_INTERNAL("Not allowed to use restricted network port", "WebKitErrorCannotUseRestrictedPort description")
+#define WebKitErrorDescriptionFrameLoadBlockedByContentFilter UI_STRING_INTERNAL("The URL was blocked by a content filter", "WebKitErrorFrameLoadBlockedByContentFilter description")
 
 // Plug-in and java errors
 #define WebKitErrorDescriptionCannotFindPlugin UI_STRING_INTERNAL("The plug-in can’t be found", "WebKitErrorCannotFindPlugin description")
@@ -154,7 +155,8 @@ static void registerErrors()
         WebKitErrorDescriptionCannotShowURL,                        [NSNumber numberWithInt: WebKitErrorCannotShowURL],
         WebKitErrorDescriptionFrameLoadInterruptedByPolicyChange,   [NSNumber numberWithInt: WebKitErrorFrameLoadInterruptedByPolicyChange],
         WebKitErrorDescriptionCannotUseRestrictedPort,              [NSNumber numberWithInt: WebKitErrorCannotUseRestrictedPort],
-        
+        WebKitErrorDescriptionFrameLoadBlockedByContentFilter,      [NSNumber numberWithInt: WebKitErrorFrameLoadBlockedByContentFilter],
+
         // Plug-in and java errors
         WebKitErrorDescriptionCannotFindPlugin,                     [NSNumber numberWithInt: WebKitErrorCannotFindPlugIn],
         WebKitErrorDescriptionCannotLoadPlugin,                     [NSNumber numberWithInt: WebKitErrorCannotLoadPlugIn],
index d63b1ff..fecd772 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -162,6 +162,7 @@ private:
     WebCore::ResourceError blockedByContentBlockerError(const WebCore::ResourceRequest&) override;
     WebCore::ResourceError cannotShowURLError(const WebCore::ResourceRequest&) override;
     WebCore::ResourceError interruptedForPolicyChangeError(const WebCore::ResourceRequest&) override;
+    WebCore::ResourceError blockedByContentFilterError(const WebCore::ResourceRequest&) override;
 
     WebCore::ResourceError cannotShowMIMETypeError(const WebCore::ResourceResponse&) override;
     WebCore::ResourceError fileDoesNotExistError(const WebCore::ResourceResponse&) override;
index e795b60..412e2c9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -1145,6 +1145,11 @@ ResourceError WebFrameLoaderClient::interruptedForPolicyChangeError(const Resour
     return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorFrameLoadInterruptedByPolicyChange URL:request.url()];
 }
 
+ResourceError WebFrameLoaderClient::blockedByContentFilterError(const ResourceRequest& request)
+{
+    return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorFrameLoadBlockedByContentFilter URL:request.url()];
+}
+
 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
 {
     return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:WebKitErrorCannotShowMIMEType URL:response.url()];
index 87a2ff7..12a1711 100644 (file)
@@ -1,3 +1,27 @@
+2016-07-07  Andy Estes  <aestes@apple.com>
+
+        [Content Filtering] Load blocked pages more like other error pages are loaded
+        https://bugs.webkit.org/show_bug.cgi?id=159485
+        <rdar://problem/26014076>
+
+        Reviewed by Brady Eidson.
+
+        * Shared/API/c/WKErrorRef.h: Defined kWKErrorCodeFrameLoadBlockedByContentFilter.
+        * UIProcess/Cocoa/WebProcessProxyCocoa.mm:
+        (WebKit::WebProcessProxy::platformPathsWithAssumedReadAccess): Added the resource directories
+        of WebCore.framework and WebKit.framework as paths with assumed read access.
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::WebProcessProxy::hasAssumedReadAccessToURL): Checked platformPathsWithAssumedReadAccess()
+        as well as m_localPathsWithAssumedReadAccess.
+        (WebKit::WebProcessProxy::platformPathsWithAssumedReadAccess): Added a non-Cocoa implementation.
+        * UIProcess/WebProcessProxy.h:
+        * WebProcess/WebCoreSupport/WebErrors.h:
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::WebFrameLoaderClient::blockedByContentFilterError): Called WebKit::blockedByContentFilterError().
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
+        * WebProcess/WebCoreSupport/mac/WebErrorsMac.mm:
+        (WebKit::blockedByContentFilterError): Returned a ResourceError for kWKErrorCodeFrameLoadBlockedByContentFilter.
+
 2016-07-07  Alex Christensen  <achristensen@webkit.org>
 
         Followup to r202939.
index bc8e294..0d76384 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -38,6 +38,7 @@ enum {
     kWKErrorCodeFrameLoadInterruptedByPolicyChange =             102,
     kWKErrorCodeCannotUseRestrictedPort =                        103,
     kWKErrorCodeFrameLoadBlockedByContentBlocker =               104,
+    kWKErrorCodeFrameLoadBlockedByContentFilter =                105,
     kWKErrorCodeCannotFindPlugIn =                               200,
     kWKErrorCodeCannotLoadPlugIn =                               201,
     kWKErrorCodeJavaUnavailable =                                202,
index 9bb0700..67e66a0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #import "WKBrowsingContextControllerInternal.h"
 #import "WKBrowsingContextHandleInternal.h"
 #import "WKTypeRefWrapper.h"
+#import <wtf/NeverDestroyed.h>
 
 namespace WebKit {
 
+const HashSet<String>& WebProcessProxy::platformPathsWithAssumedReadAccess()
+{
+    static NeverDestroyed<HashSet<String>> platformPathsWithAssumedReadAccess(std::initializer_list<String> {
+        [NSBundle bundleWithIdentifier:@"com.apple.WebCore"].resourcePath.stringByStandardizingPath,
+        [NSBundle bundleWithIdentifier:@"com.apple.WebKit"].resourcePath.stringByStandardizingPath
+    });
+
+    return platformPathsWithAssumedReadAccess;
+}
+
 RefPtr<ObjCObjectGraph> WebProcessProxy::transformHandlesToObjects(ObjCObjectGraph& objectGraph)
 {
     struct Transformer final : ObjCObjectGraph::Transformer {
index 5af6d92..585ae44 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -322,11 +322,19 @@ bool WebProcessProxy::hasAssumedReadAccessToURL(const URL& url) const
         return false;
 
     String path = url.fileSystemPath();
-    for (const String& assumedAccessPath : m_localPathsWithAssumedReadAccess) {
+    auto startsWithURLPath = [&path](const String& assumedAccessPath) {
         // There are no ".." components, because URL removes those.
-        if (path.startsWith(assumedAccessPath))
-            return true;
-    }
+        return path.startsWith(assumedAccessPath);
+    };
+
+    auto& platformPaths = platformPathsWithAssumedReadAccess();
+    auto platformPathsEnd = platformPaths.end();
+    if (std::find_if(platformPaths.begin(), platformPathsEnd, startsWithURLPath) != platformPathsEnd)
+        return true;
+
+    auto localPathsEnd = m_localPathsWithAssumedReadAccess.end();
+    if (std::find_if(m_localPathsWithAssumedReadAccess.begin(), localPathsEnd, startsWithURLPath) != localPathsEnd)
+        return true;
 
     return false;
 }
@@ -1035,4 +1043,12 @@ void WebProcessProxy::didReceiveMainThreadPing()
         callback(isWebProcessResponsive);
 }
 
+#if !PLATFORM(COCOA)
+const HashSet<String>& WebProcessProxy::platformPathsWithAssumedReadAccess()
+{
+    static NeverDestroyed<HashSet<String>> platformPathsWithAssumedReadAccess;
+    return platformPathsWithAssumedReadAccess;
+}
+#endif
+
 } // namespace WebKit
index 52c2b70..01c21d2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,8 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef WebProcessProxy_h
-#define WebProcessProxy_h
+#pragma once
 
 #include "APISession.h"
 #include "ChildProcessProxy.h"
@@ -191,6 +190,8 @@ private:
     void releaseIconForPageURL(const String& pageURL);
     void releaseRemainingIconsForPageURLs();
 
+    static const HashSet<String>& platformPathsWithAssumedReadAccess();
+
     // IPC::Connection::Client
     friend class WebConnectionToWebProcess;
     void didReceiveMessage(IPC::Connection&, IPC::MessageDecoder&) override;
@@ -258,5 +259,3 @@ private:
 };
 
 } // namespace WebKit
-
-#endif // WebProcessProxy_h
index 70a228c..84dd73e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,8 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef WebErrors_h
-#define WebErrors_h
+#pragma once
 
 namespace WebCore {
     class URL;
@@ -40,11 +39,12 @@ WebCore::ResourceError blockedError(const WebCore::ResourceRequest&);
 WebCore::ResourceError blockedByContentBlockerError(const WebCore::ResourceRequest&);
 WebCore::ResourceError cannotShowURLError(const WebCore::ResourceRequest&);
 WebCore::ResourceError interruptedForPolicyChangeError(const WebCore::ResourceRequest&);
+#if ENABLE(CONTENT_FILTERING)
+WebCore::ResourceError blockedByContentFilterError(const WebCore::ResourceRequest&);
+#endif
 WebCore::ResourceError cannotShowMIMETypeError(const WebCore::ResourceResponse&);
 WebCore::ResourceError fileDoesNotExistError(const WebCore::ResourceResponse&);
 WebCore::ResourceError pluginWillHandleLoadError(const WebCore::ResourceResponse&);
 WebCore::ResourceError internalError(const WebCore::URL&);
 
 } // namespace WebKit
-
-#endif // WebErrors_h
index 6af076e..1aa3a53 100644 (file)
@@ -1112,6 +1112,13 @@ ResourceError WebFrameLoaderClient::interruptedForPolicyChangeError(const Resour
     return WebKit::interruptedForPolicyChangeError(request);
 }
 
+#if ENABLE(CONTENT_FILTERING)
+ResourceError WebFrameLoaderClient::blockedByContentFilterError(const ResourceRequest& request)
+{
+    return WebKit::blockedByContentFilterError(request);
+}
+#endif
+
 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
 {
     return WebKit::cannotShowMIMETypeError(response);
index ee6bebd..b9e39fe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,8 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef WebFrameLoaderClient_h
-#define WebFrameLoaderClient_h
+#pragma once
 
 #include <WebCore/FrameLoaderClient.h>
 
@@ -149,6 +148,9 @@ private:
     WebCore::ResourceError blockedByContentBlockerError(const WebCore::ResourceRequest&) override;
     WebCore::ResourceError cannotShowURLError(const WebCore::ResourceRequest&) override;
     WebCore::ResourceError interruptedForPolicyChangeError(const WebCore::ResourceRequest&) override;
+#if ENABLE(CONTENT_FILTERING)
+    WebCore::ResourceError blockedByContentFilterError(const WebCore::ResourceRequest&) override;
+#endif
     
     WebCore::ResourceError cannotShowMIMETypeError(const WebCore::ResourceResponse&) override;
     WebCore::ResourceError fileDoesNotExistError(const WebCore::ResourceResponse&) override;
@@ -268,5 +270,3 @@ inline WebFrameLoaderClient* toWebFrameLoaderClient(WebCore::FrameLoaderClient&
 }
 
 } // namespace WebKit
-
-#endif // WebFrameLoaderClient_h
index 94df564..d72d8a8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -82,6 +82,11 @@ ResourceError interruptedForPolicyChangeError(const ResourceRequest& request)
     return ResourceError(API::Error::webKitErrorDomain(), kWKErrorCodeFrameLoadInterruptedByPolicyChange, request.url(), WEB_UI_STRING("Frame load interrupted", "WebKitErrorFrameLoadInterruptedByPolicyChange description"));
 }
 
+ResourceError blockedByContentFilterError(const ResourceRequest& request)
+{
+    return ResourceError(API::Error::webKitErrorDomain(), kWKErrorCodeFrameLoadBlockedByContentFilter, request.url(), WEB_UI_STRING("The URL was blocked by a content filter", "WebKitErrorBlockedByContentFilter"));
+}
+
 ResourceError cannotShowMIMETypeError(const ResourceResponse& response)
 {
     return ResourceError(API::Error::webKitErrorDomain(), kWKErrorCodeCannotShowMIMEType, response.url(), WEB_UI_STRING("Content with specified MIME type can’t be shown", "WebKitErrorCannotShowMIMEType description"));
index 7efa22b..0b180f3 100644 (file)
@@ -1,3 +1,30 @@
+2016-07-07  Andy Estes  <aestes@apple.com>
+
+        [Content Filtering] Load blocked pages more like other error pages are loaded
+        https://bugs.webkit.org/show_bug.cgi?id=159485
+        <rdar://problem/26014076>
+
+        Reviewed by Brady Eidson.
+
+        Added API tests for WebView and WKWebView to verify that alternate HTML loaded in response
+        to a content filtering provisional navigation failure is ignored in preference of
+        ContentFilter's own error page.
+
+        * TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig:
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.mm:
+        (-[LoadAlternateNavigationDelegate webView:didFailProvisionalNavigation:withError:]):
+        (-[LoadAlternateNavigationDelegate webView:didFinishNavigation:]):
+        (loadAlternateTest):
+        (TEST):
+        * TestWebKitAPI/Tests/WebKit2Cocoa/ContentFilteringPlugIn.mm:
+        (-[MockContentFilterEnabler initWithCoder:]):
+        * TestWebKitAPI/Tests/mac/ContentFiltering.mm: Added.
+        (-[LoadAlternateFrameLoadDelegate webView:didFailProvisionalLoadWithError:forFrame:]):
+        (-[LoadAlternateFrameLoadDelegate webView:didFinishLoadForFrame:]):
+        (TestWebKitAPI::loadAlternateTest):
+        (TestWebKitAPI::TEST):
+
 2016-07-07  Per Arne Vollan  <pvollan@apple.com>
 
         Unreviewed: add myself to the reviewers list.
index 741d033..8218a37 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010, 2014 Apple Inc. All rights reserved.
+// Copyright (C) 2010-2016 Apple Inc. All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions
@@ -28,8 +28,10 @@ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
 
 UNEXPORTED_SYMBOL_LDFLAGS = -Wl,-unexported_symbol -Wl,__ZN7testing4Test16TearDownTestCaseEv -Wl,-unexported_symbol -Wl,__ZN7testing4Test13SetUpTestCaseEv
 
-OTHER_LDFLAGS = $(inherited) $(UNEXPORTED_SYMBOL_LDFLAGS) -lgtest -force_load $(BUILT_PRODUCTS_DIR)/libTestWebKitAPI.a -framework JavaScriptCore -framework WebKit $(OTHER_LDFLAGS_PLATFORM);
+OTHER_LDFLAGS = $(inherited) $(UNEXPORTED_SYMBOL_LDFLAGS) -lgtest -force_load $(BUILT_PRODUCTS_DIR)/libTestWebKitAPI.a -framework JavaScriptCore -framework WebKit -lWebCoreTestSupport $(OTHER_LDFLAGS_PLATFORM);
 OTHER_LDFLAGS_PLATFORM[sdk=macosx*] = -framework Cocoa -framework Carbon;
 
 // FIXME: This should not be built on iOS. Instead we should create and use a TestWebKitAPI application.
 OTHER_LDFLAGS_PLATFORM[sdk=iphone*] = -framework WebCore -framework CoreGraphics;
+
+LD_RUNPATH_SEARCH_PATHS = "@loader_path";
index ba45506..76b6b82 100644 (file)
                9B0786A51C5885C300D159E3 /* InjectedBundleMakeAllShadowRootOpen_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9B0786A41C5885C300D159E3 /* InjectedBundleMakeAllShadowRootOpen_Bundle.cpp */; };
                9B26FCCA159D16DE00CC3765 /* HTMLFormCollectionNamedItem.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B26FCB4159D15E700CC3765 /* HTMLFormCollectionNamedItem.html */; };
                9B4F8FA7159D52DD002D9F94 /* HTMLCollectionNamedItem.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */; };
+               A1146A8D1D2D7115000FE710 /* ContentFiltering.mm in Sources */ = {isa = PBXBuildFile; fileRef = A1146A8A1D2D704F000FE710 /* ContentFiltering.mm */; };
                A13EBBAA1B87428D00097110 /* WebProcessPlugIn.mm in Sources */ = {isa = PBXBuildFile; fileRef = A13EBBA91B87428D00097110 /* WebProcessPlugIn.mm */; };
                A13EBBAB1B87434600097110 /* PlatformUtilitiesCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0F139E721A423A2B00F590F5 /* PlatformUtilitiesCocoa.mm */; };
                A13EBBB01B87436F00097110 /* BundleParametersPlugIn.mm in Sources */ = {isa = PBXBuildFile; fileRef = A13EBBAE1B87436F00097110 /* BundleParametersPlugIn.mm */; };
                9B4F8FA3159D52B1002D9F94 /* HTMLCollectionNamedItem.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HTMLCollectionNamedItem.mm; sourceTree = "<group>"; };
                9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = HTMLCollectionNamedItem.html; sourceTree = "<group>"; };
                9B79164F1BD89D0D00D50B8F /* FirstResponderScrollingPosition.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FirstResponderScrollingPosition.mm; sourceTree = "<group>"; };
+               A1146A8A1D2D704F000FE710 /* ContentFiltering.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ContentFiltering.mm; sourceTree = "<group>"; };
                A13EBB491B87339E00097110 /* TestWebKitAPI.wkbundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestWebKitAPI.wkbundle; sourceTree = BUILT_PRODUCTS_DIR; };
                A13EBB521B87346600097110 /* WebProcessPlugIn.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = WebProcessPlugIn.xcconfig; sourceTree = "<group>"; };
                A13EBB541B8734E000097110 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
                                00CD9F6215BE312C002DA2CE /* BackForwardList.mm */,
                                26DF5A5D15A29BAA003689C2 /* CancelLoadFromResourceLoadDelegate.mm */,
                                290A9BB51735DE8A00D71BBC /* CloseNewWindowInNavigationPolicyDelegate.mm */,
+                               A1146A8A1D2D704F000FE710 /* ContentFiltering.mm */,
                                5142B2701517C88B00C32B19 /* ContextMenuCanCopyURL.mm */,
                                3776BC62150946BC0043A66D /* DeviceScaleFactorInDashboardRegions.mm */,
                                939BA91614103412001A01BD /* DeviceScaleFactorOnBack.mm */,
                                7C83E0B61D0A64B300FEBCF3 /* ModalAlertsSPI.cpp in Sources */,
                                7C83E04E1D0A641800FEBCF3 /* DFAMinimizer.cpp in Sources */,
                                7C83E0B81D0A64BD00FEBCF3 /* InjectedBundleMakeAllShadowRootsOpen.cpp in Sources */,
+                               A1146A8D1D2D7115000FE710 /* ContentFiltering.mm in Sources */,
                                7CCE7EF91A411AE600447C4C /* GetInjectedBundleInitializationUserDataCallback.cpp in Sources */,
                                536770341CC8022800D425B1 /* WebScriptObjectDescription.mm in Sources */,
                                7CCE7EE21A411A9A00447C4C /* GetPIDAfterAbortedProcessLaunch.cpp in Sources */,
index 7cbad3e..5c815bc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,6 +35,7 @@
 #import <WebKit/WKNavigationDelegatePrivate.h>
 #import <WebKit/WKProcessPoolPrivate.h>
 #import <WebKit/WKWebView.h>
+#import <WebKit/WKWebViewPrivate.h>
 #import <WebKit/_WKDownloadDelegate.h>
 #import <WebKit/_WKRemoteObjectInterface.h>
 #import <WebKit/_WKRemoteObjectRegistry.h>
@@ -256,6 +257,73 @@ TEST(ContentFiltering, BlockDownloadNever)
     downloadTest(Decision::Block, DecisionPoint::Never);
 }
 
+@interface LoadAlternateNavigationDelegate : NSObject <WKNavigationDelegate>
+@end
+
+@implementation LoadAlternateNavigationDelegate
+
+- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
+{
+    EXPECT_WK_STREQ(WebKitErrorDomain, error.domain);
+    EXPECT_EQ(WebKitErrorFrameLoadBlockedByContentFilter, error.code);
+    [webView _loadAlternateHTMLString:@"FAIL" baseURL:nil forUnreachableURL:[error.userInfo objectForKey:NSURLErrorFailingURLErrorKey]];
+}
+
+- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
+{
+    [webView evaluateJavaScript:@"document.body.innerText" completionHandler:^ (id result, NSError *error) {
+        EXPECT_TRUE([result isKindOfClass:[NSString class]]);
+        EXPECT_WK_STREQ(@"blocked", result);
+        isDone = true;
+    }];
+}
+
+@end
+
+static void loadAlternateTest(Decision decision, DecisionPoint decisionPoint)
+{
+    @autoreleasepool {
+        [TestProtocol registerWithScheme:@"http"];
+
+        auto configuration = configurationWithContentFilterSettings(decision, decisionPoint);
+        auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
+        auto navigationDelegate = adoptNS([[LoadAlternateNavigationDelegate alloc] init]);
+        [webView setNavigationDelegate:navigationDelegate.get()];
+        [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://redirect/?result"]]];
+
+        isDone = false;
+        TestWebKitAPI::Util::run(&isDone);
+
+        [TestProtocol unregister];
+    }
+}
+
+TEST(ContentFiltering, LoadAlternateAfterWillSendRequestWK2)
+{
+    loadAlternateTest(Decision::Block, DecisionPoint::AfterWillSendRequest);
+}
+
+TEST(ContentFiltering, LoadAlternateAfterRedirectWK2)
+{
+    loadAlternateTest(Decision::Block, DecisionPoint::AfterRedirect);
+}
+
+TEST(ContentFiltering, LoadAlternateAfterResponseWK2)
+{
+    loadAlternateTest(Decision::Block, DecisionPoint::AfterResponse);
+}
+
+TEST(ContentFiltering, LoadAlternateAfterAddDataWK2)
+{
+    loadAlternateTest(Decision::Block, DecisionPoint::AfterAddData);
+}
+
+TEST(ContentFiltering, LoadAlternateAfterFinishedAddingDataWK2)
+{
+    loadAlternateTest(Decision::Block, DecisionPoint::AfterFinishedAddingData);
+}
+
+
 @interface LazilyLoadPlatformFrameworksController : NSObject <WKNavigationDelegate>
 @property (nonatomic, readonly) WKWebView *webView;
 - (void)expectParentalControlsLoaded:(BOOL)parentalControlsShouldBeLoaded networkExtensionLoaded:(BOOL)networkExtensionShouldBeLoaded;
index fa31305..bed847e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -63,6 +63,7 @@ using DecisionPoint = MockContentFilterSettings::DecisionPoint;
     settings.setEnabled(true);
     settings.setDecision(static_cast<Decision>([decoder decodeIntForKey:@"Decision"]));
     settings.setDecisionPoint(static_cast<DecisionPoint>([decoder decodeIntForKey:@"DecisionPoint"]));
+    settings.setBlockedString(ASCIILiteral("blocked"));
     return self;
 }
 
diff --git a/Tools/TestWebKitAPI/Tests/mac/ContentFiltering.mm b/Tools/TestWebKitAPI/Tests/mac/ContentFiltering.mm
new file mode 100644 (file)
index 0000000..f6c69ab
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2016 Apple 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:
+ * 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 "config.h"
+
+#import "MockContentFilterSettings.h"
+#import "PlatformUtilities.h"
+#import "TestProtocol.h"
+#import <WebKit/WebKit.h>
+
+using Decision = WebCore::MockContentFilterSettings::Decision;
+using DecisionPoint = WebCore::MockContentFilterSettings::DecisionPoint;
+
+static bool isDone;
+
+@interface LoadAlternateFrameLoadDelegate : NSObject <WebFrameLoadDelegate>
+@end
+
+@implementation LoadAlternateFrameLoadDelegate
+
+- (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
+{
+    EXPECT_WK_STREQ(WebKitErrorDomain, error.domain);
+    EXPECT_EQ(WebKitErrorFrameLoadBlockedByContentFilter, error.code);
+    [frame loadAlternateHTMLString:@"FAIL" baseURL:nil forUnreachableURL:[error.userInfo objectForKey:NSURLErrorFailingURLErrorKey]];
+}
+
+- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
+{
+    EXPECT_WK_STREQ(@"blocked", frame.DOMDocument.body.innerText);
+    isDone = true;
+}
+
+@end
+
+namespace TestWebKitAPI {
+
+static void loadAlternateTest(Decision decision, DecisionPoint decisionPoint)
+{
+    @autoreleasepool {
+        auto& settings = WebCore::MockContentFilterSettings::singleton();
+        settings.setEnabled(true);
+        settings.setDecision(decision);
+        settings.setDecisionPoint(decisionPoint);
+        settings.setBlockedString(ASCIILiteral("blocked"));
+        [TestProtocol registerWithScheme:@"http"];
+
+        auto webView = adoptNS([[WebView alloc] initWithFrame:NSZeroRect]);
+        auto frameLoadDelegate = adoptNS([[LoadAlternateFrameLoadDelegate alloc] init]);
+        [webView setFrameLoadDelegate:frameLoadDelegate.get()];
+        [[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://redirect/?result"]]];
+
+        isDone = false;
+        TestWebKitAPI::Util::run(&isDone);
+
+        settings.setEnabled(false);
+        [TestProtocol unregister];
+    }
+}
+
+TEST(ContentFiltering, LoadAlternateAfterWillSendRequestWK1)
+{
+    loadAlternateTest(Decision::Block, DecisionPoint::AfterWillSendRequest);
+}
+
+TEST(ContentFiltering, LoadAlternateAfterRedirectWK1)
+{
+    loadAlternateTest(Decision::Block, DecisionPoint::AfterRedirect);
+}
+
+TEST(ContentFiltering, LoadAlternateAfterResponseWK1)
+{
+    loadAlternateTest(Decision::Block, DecisionPoint::AfterResponse);
+}
+
+TEST(ContentFiltering, LoadAlternateAfterAddDataWK1)
+{
+    loadAlternateTest(Decision::Block, DecisionPoint::AfterAddData);
+}
+
+TEST(ContentFiltering, LoadAlternateAfterFinishedAddingDataWK1)
+{
+    loadAlternateTest(Decision::Block, DecisionPoint::AfterFinishedAddingData);
+}
+
+} // namespace TestWebKitAPI