Diff
Modified: trunk/Source/WebCore/ChangeLog (290188 => 290189)
--- trunk/Source/WebCore/ChangeLog 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebCore/ChangeLog 2022-02-19 01:02:27 UTC (rev 290189)
@@ -1,3 +1,57 @@
+2022-02-18 Per Arne Vollan <pvol...@apple.com>
+
+ Move content filtering to Networking process
+ https://bugs.webkit.org/show_bug.cgi?id=233760
+ <rdar://problem/86150702>
+
+ Reviewed by Brent Fulgham.
+
+ Remove content filtering from DocumentLoader when the feature is enabled, since this takes place in the WebContent process.
+ Modify the ContentFilter class by removing use of the types CachedResoure and CachedRawResource, since objects of these
+ types are not available in the Networking process. Parameters with these types are replaced with URL parameters.
+ The new behavior is behind a feature flag, which is not enabled in this patch.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * loader/ContentFilter.cpp:
+ (WebCore::ContentFilter::startFilteringMainResource):
+ (WebCore::ContentFilter::stopFilteringMainResource):
+ (WebCore::ContentFilter::continueAfterResponseReceived):
+ (WebCore::ContentFilter::continueAfterDataReceived):
+ (WebCore::ContentFilter::continueAfterNotifyFinished):
+ (WebCore::ContentFilter::didDecide):
+ (WebCore::ContentFilter::deliverResourceData):
+ (WebCore::ContentFilter::url):
+ (WebCore::ContentFilter::deliverStoredResourceData):
+ * loader/ContentFilter.h:
+ (WebCore::ContentFilter::blockedError const):
+ (WebCore::ContentFilter::isAllowed const):
+ (WebCore::ContentFilter::responseReceived const):
+ * loader/ContentFilterClient.h:
+ * loader/DocumentLoader.cpp:
+ (WebCore::DocumentLoader::notifyFinished):
+ (WebCore::DocumentLoader::willSendRequest):
+ (WebCore::DocumentLoader::responseReceived):
+ (WebCore::DocumentLoader::dataReceived):
+ (WebCore::DocumentLoader::detachFromFrame):
+ (WebCore::DocumentLoader::startLoadingMainResource):
+ (WebCore::DocumentLoader::clearMainResource):
+ (WebCore::DocumentLoader::becomeMainResourceClient):
+ (WebCore::DocumentLoader::contentFilterDidBlock):
+ (WebCore::DocumentLoader::handleContentFilterDidBlock):
+ (WebCore::DocumentLoader::handleContentFilterProvisionalLoadFailure):
+ (WebCore::DocumentLoader::contentFilterWillHandleProvisionalLoadFailure):
+ (WebCore::DocumentLoader::contentFilterHandleProvisionalLoadFailure):
+ * loader/DocumentLoader.h:
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::dispatchDidFailProvisionalLoad):
+ * loader/PolicyChecker.cpp:
+ (WebCore::FrameLoader::PolicyChecker::checkNavigationPolicy):
+ * loader/SubstituteData.h:
+ (WebCore::SubstituteData::encode const):
+ (WebCore::SubstituteData::decode):
+ * platform/cocoa/ContentFilterUnblockHandlerCocoa.mm:
+ (WebCore::ContentFilterUnblockHandler::canHandleRequest const):
+
2022-02-18 Mark Lam <mark....@apple.com>
Provide a WebCore subspaceImplFor template to make code more readable.
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (290188 => 290189)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2022-02-19 01:02:27 UTC (rev 290189)
@@ -3368,7 +3368,7 @@
A14832CC187F67C400DA63A6 /* WebCoreThreadRun.h in Headers */ = {isa = PBXBuildFile; fileRef = A148329E187F508700DA63A6 /* WebCoreThreadRun.h */; settings = {ATTRIBUTES = (Private, ); }; };
A14832CF187F684700DA63A6 /* WebCoreThreadSystemInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = A14832A1187F508700DA63A6 /* WebCoreThreadSystemInterface.h */; settings = {ATTRIBUTES = (Private, ); }; };
A1491DA31F859D870095F5D4 /* PaymentSession.h in Headers */ = {isa = PBXBuildFile; fileRef = A1491DA21F859D870095F5D4 /* PaymentSession.h */; };
- A149786F1ABAF33800CEF7E4 /* ContentFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = A149786D1ABAF33800CEF7E4 /* ContentFilter.h */; };
+ A149786F1ABAF33800CEF7E4 /* ContentFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = A149786D1ABAF33800CEF7E4 /* ContentFilter.h */; settings = {ATTRIBUTES = (Private, ); }; };
A14978711ABAF3A500CEF7E4 /* PlatformContentFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = A14978701ABAF3A500CEF7E4 /* PlatformContentFilter.h */; settings = {ATTRIBUTES = (Private, ); }; };
A14BB0A01F9813B800605A35 /* MockPayment.h in Headers */ = {isa = PBXBuildFile; fileRef = A14BB09E1F9813B800605A35 /* MockPayment.h */; };
A15D75161E68F7C800A35FBC /* BlobCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = A15D75131E68F7B100A35FBC /* BlobCallback.h */; };
Modified: trunk/Source/WebCore/loader/ContentFilter.cpp (290188 => 290189)
--- trunk/Source/WebCore/loader/ContentFilter.cpp 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebCore/loader/ContentFilter.cpp 2022-02-19 01:02:27 UTC (rev 290189)
@@ -113,22 +113,39 @@
return !request.isNull();
}
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+void ContentFilter::startFilteringMainResource(const URL& url)
+{
+ if (m_state != State::Stopped)
+ return;
+
+ LOG(ContentFiltering, "ContentFilter will start filtering main resource at <%{sensitive}s>.\n", url.string().ascii().data());
+ m_state = State::Filtering;
+ ASSERT(m_mainResourceURL.isEmpty());
+ m_mainResourceURL = url;
+}
+#else
void ContentFilter::startFilteringMainResource(CachedRawResource& resource)
{
if (m_state != State::Stopped)
return;
- LOG(ContentFiltering, "ContentFilter will start filtering main resource at <%s>.\n", resource.url().string().ascii().data());
+ LOG(ContentFiltering, "ContentFilter will start filtering main resource at <%{sensitive}s>.\n", resource.url().string().ascii().data());
m_state = State::Filtering;
ASSERT(!m_mainResource);
m_mainResource = &resource;
}
+#endif
void ContentFilter::stopFilteringMainResource()
{
if (m_state != State::Blocked)
m_state = State::Stopped;
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ m_mainResourceURL = URL();
+#else
m_mainResource = nullptr;
+#endif
}
bool ContentFilter::continueAfterResponseReceived(const ResourceResponse& response)
@@ -142,21 +159,38 @@
});
}
+ m_responseReceived = true;
+
return m_state != State::Blocked;
}
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+bool ContentFilter::continueAfterDataReceived(const SharedBuffer& data, size_t encodedDataLength)
+#else
bool ContentFilter::continueAfterDataReceived(const SharedBuffer& data)
+#endif
{
Ref<ContentFilterClient> protectedClient { m_client };
if (m_state == State::Filtering) {
- LOG(ContentFiltering, "ContentFilter received %zu bytes of data from <%s>.\n", data.size(), m_mainResource->url().string().ascii().data());
+ LOG(ContentFiltering, "ContentFilter received %zu bytes of data from <%{sensitive}s>.\n", data.size(), url().string().ascii().data());
+
forEachContentFilterUntilBlocked([data = "" { data }](auto& contentFilter) {
contentFilter.addData(data);
});
-
- if (m_state == State::Allowed)
- deliverResourceData(*m_mainResource);
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ if (m_state == State::Allowed) {
+ deliverStoredResourceData();
+ deliverResourceData(data, encodedDataLength);
+ } else
+ m_buffers.append(ResourceDataItem { RefPtr { &data }, encodedDataLength });
+#else
+ if (m_state == State::Allowed) {
+ ASSERT(m_mainResource->dataBufferingPolicy() == DataBufferingPolicy::BufferData);
+ if (auto* buffer = m_mainResource->resourceBuffer())
+ deliverResourceData(buffer->makeContiguous());
+ }
+#endif
return false;
}
@@ -163,16 +197,23 @@
return m_state != State::Blocked;
}
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+bool ContentFilter::continueAfterNotifyFinished(const URL& resourceURL)
+#else
bool ContentFilter::continueAfterNotifyFinished(CachedResource& resource)
+#endif
{
+ Ref<ContentFilterClient> protectedClient { m_client };
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ ASSERT_UNUSED(resourceURL, resourceURL == m_mainResourceURL);
+#else
ASSERT_UNUSED(resource, &resource == m_mainResource);
- Ref<ContentFilterClient> protectedClient { m_client };
-
if (m_mainResource->errorOccurred())
return true;
+#endif
if (m_state == State::Filtering) {
- LOG(ContentFiltering, "ContentFilter will finish filtering main resource at <%s>.\n", m_mainResource->url().string().ascii().data());
+ LOG(ContentFiltering, "ContentFilter will finish filtering main resource at <%{sensitive}s>.\n", url().string().ascii().data());
forEachContentFilterUntilBlocked([](PlatformContentFilter& contentFilter) {
contentFilter.finishedAddingData();
});
@@ -179,7 +220,14 @@
if (m_state != State::Blocked) {
m_state = State::Allowed;
- deliverResourceData(*m_mainResource);
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ deliverStoredResourceData();
+#else
+ if (auto* buffer = m_mainResource->resourceBuffer()) {
+ ASSERT(m_mainResource->dataBufferingPolicy() == DataBufferingPolicy::BufferData);
+ deliverResourceData(buffer->makeContiguous());
+ }
+#endif
}
if (m_state == State::Stopped)
@@ -219,7 +267,9 @@
ASSERT(m_state != State::Allowed);
ASSERT(m_state != State::Blocked);
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() : "");
+#if !LOG_DISABLED
+ LOG(ContentFiltering, "ContentFilter decided load should be %s for main resource at <%{sensitive}s>.\n", state == State::Allowed ? "allowed" : "blocked", url().string().ascii().data());
+#endif // !LOG_DISABLED
m_state = state;
if (m_state != State::Blocked)
return;
@@ -228,14 +278,28 @@
m_client.cancelMainResourceLoadForContentFilter(m_blockedError);
}
-void ContentFilter::deliverResourceData(CachedResource& resource)
+void ContentFilter::deliverResourceData(const SharedBuffer& buffer, size_t encodedDataLength)
{
ASSERT(m_state == State::Allowed);
- ASSERT(resource.dataBufferingPolicy() == DataBufferingPolicy::BufferData);
- if (auto* resourceBuffer = resource.resourceBuffer())
- m_client.dataReceivedThroughContentFilter(resourceBuffer->makeContiguous());
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ m_client.dataReceivedThroughContentFilter(buffer, encodedDataLength);
+#else
+ UNUSED_PARAM(encodedDataLength);
+ m_client.dataReceivedThroughContentFilter(buffer);
+#endif
}
+URL ContentFilter::url()
+{
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ return m_mainResourceURL;
+#else
+ if (m_mainResource)
+ return m_mainResource->url();
+ return URL();
+#endif
+}
+
static const URL& blockedPageURL()
{
static NeverDestroyed blockedPageURL = [] () -> URL {
@@ -245,6 +309,7 @@
return blockedPageURL;
}
+#if !ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
bool ContentFilter::continueAfterSubstituteDataRequest(const DocumentLoader& activeLoader, const SubstituteData& substituteData)
{
if (auto contentFilter = activeLoader.contentFilter()) {
@@ -259,6 +324,7 @@
return true;
}
+#endif
bool ContentFilter::willHandleProvisionalLoadFailure(const ResourceError& error) const
{
@@ -283,6 +349,15 @@
m_client.handleProvisionalLoadFailureFromContentFilter(blockedPageURL(), substituteData);
}
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+void ContentFilter::deliverStoredResourceData()
+{
+ for (auto& buffer : m_buffers)
+ deliverResourceData(*buffer.buffer, buffer.encodedDataLength);
+ m_buffers.clear();
+}
+#endif
+
} // namespace WebCore
#endif // ENABLE(CONTENT_FILTERING)
Modified: trunk/Source/WebCore/loader/ContentFilter.h (290188 => 290189)
--- trunk/Source/WebCore/loader/ContentFilter.h 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebCore/loader/ContentFilter.h 2022-02-19 01:02:27 UTC (rev 290189)
@@ -50,23 +50,36 @@
public:
template <typename T> static void addType() { types().append(type<T>()); }
- static std::unique_ptr<ContentFilter> create(ContentFilterClient&);
- ~ContentFilter();
+ WEBCORE_EXPORT static std::unique_ptr<ContentFilter> create(ContentFilterClient&);
+ WEBCORE_EXPORT ~ContentFilter();
static const char* urlScheme() { return "x-apple-content-filter"; }
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ WEBCORE_EXPORT void startFilteringMainResource(const URL&);
+#else
void startFilteringMainResource(CachedRawResource&);
- void stopFilteringMainResource();
+#endif
+ WEBCORE_EXPORT void stopFilteringMainResource();
- bool continueAfterWillSendRequest(ResourceRequest&, const ResourceResponse&);
- bool continueAfterResponseReceived(const ResourceResponse&);
+ WEBCORE_EXPORT bool continueAfterWillSendRequest(ResourceRequest&, const ResourceResponse&);
+ WEBCORE_EXPORT bool continueAfterResponseReceived(const ResourceResponse&);
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ WEBCORE_EXPORT bool continueAfterDataReceived(const SharedBuffer&, size_t encodedDataLength);
+ WEBCORE_EXPORT bool continueAfterNotifyFinished(const URL& resourceURL);
+#else
bool continueAfterDataReceived(const SharedBuffer&);
bool continueAfterNotifyFinished(CachedResource&);
+#endif
static bool continueAfterSubstituteDataRequest(const DocumentLoader& activeLoader, const SubstituteData&);
bool willHandleProvisionalLoadFailure(const ResourceError&) const;
- void handleProvisionalLoadFailure(const ResourceError&);
+ WEBCORE_EXPORT void handleProvisionalLoadFailure(const ResourceError&);
+ const ResourceError& blockedError() const { return m_blockedError; }
+ bool isAllowed() const { return m_state == State::Allowed; }
+ bool responseReceived() const { return m_responseReceived; }
+
private:
using State = PlatformContentFilter::State;
@@ -82,15 +95,31 @@
template <typename Function> void forEachContentFilterUntilBlocked(Function&&);
void didDecide(State);
- void deliverResourceData(CachedResource&);
-
+ void deliverResourceData(const SharedBuffer&, size_t encodedDataLength = 0);
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ void deliverStoredResourceData();
+#endif
+
+ URL url();
+
Container m_contentFilters;
ContentFilterClient& m_client;
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ URL m_mainResourceURL;
+ struct ResourceDataItem {
+ RefPtr<const SharedBuffer> buffer;
+ size_t encodedDataLength;
+ };
+
+ Vector<ResourceDataItem> m_buffers;
+#else
CachedResourceHandle<CachedRawResource> m_mainResource;
+#endif
const PlatformContentFilter* m_blockingContentFilter { nullptr };
State m_state { State::Stopped };
ResourceError m_blockedError;
bool m_isLoadingBlockedPage { false };
+ bool m_responseReceived { false };
};
template <typename T>
Modified: trunk/Source/WebCore/loader/ContentFilterClient.h (290188 => 290189)
--- trunk/Source/WebCore/loader/ContentFilterClient.h 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebCore/loader/ContentFilterClient.h 2022-02-19 01:02:27 UTC (rev 290189)
@@ -42,7 +42,11 @@
virtual void ref() const = 0;
virtual void deref() const = 0;
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ virtual void dataReceivedThroughContentFilter(const SharedBuffer&, size_t) = 0;
+#else
virtual void dataReceivedThroughContentFilter(const SharedBuffer&) = 0;
+#endif
virtual ResourceError contentFilterDidBlock(ContentFilterUnblockHandler, String&& unblockRequestDeniedScript) = 0;
virtual void cancelMainResourceLoadForContentFilter(const ResourceError&) = 0;
virtual void handleProvisionalLoadFailureFromContentFilter(const URL& blockedPageURL, SubstituteData&) = 0;
Modified: trunk/Source/WebCore/loader/DocumentLoader.cpp (290188 => 290189)
--- trunk/Source/WebCore/loader/DocumentLoader.cpp 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebCore/loader/DocumentLoader.cpp 2022-02-19 01:02:27 UTC (rev 290189)
@@ -419,7 +419,7 @@
void DocumentLoader::notifyFinished(CachedResource& resource, const NetworkLoadMetrics& metrics)
{
ASSERT(isMainThread());
-#if ENABLE(CONTENT_FILTERING)
+#if ENABLE(CONTENT_FILTERING) && !ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
if (m_contentFilter && !m_contentFilter->continueAfterNotifyFinished(resource))
return;
#endif
@@ -710,7 +710,7 @@
newRequest.setURL(WTFMove(url));
}
-#if ENABLE(CONTENT_FILTERING)
+#if ENABLE(CONTENT_FILTERING) && !ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
if (m_contentFilter && !m_contentFilter->continueAfterWillSendRequest(newRequest, redirectResponse))
return completionHandler(WTFMove(newRequest));
#endif
@@ -902,7 +902,7 @@
ASSERT(response.certificateInfo());
CompletionHandlerCallingScope completionHandlerCaller(WTFMove(completionHandler));
-#if ENABLE(CONTENT_FILTERING)
+#if ENABLE(CONTENT_FILTERING) && !ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
if (m_contentFilter && !m_contentFilter->continueAfterResponseReceived(response))
return;
#endif
@@ -1322,7 +1322,7 @@
void DocumentLoader::dataReceived(const SharedBuffer& buffer)
{
-#if ENABLE(CONTENT_FILTERING)
+#if ENABLE(CONTENT_FILTERING) && !ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
if (m_contentFilter && !m_contentFilter->continueAfterDataReceived(buffer))
return;
#endif
@@ -1463,7 +1463,7 @@
stopLoading();
if (m_mainResource && m_mainResource->hasClient(*this))
m_mainResource->removeClient(*this);
-#if ENABLE(CONTENT_FILTERING)
+#if ENABLE(CONTENT_FILTERING) && !ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
if (m_contentFilter)
m_contentFilter->stopFilteringMainResource();
#endif
@@ -2025,7 +2025,7 @@
return;
}
-#if ENABLE(CONTENT_FILTERING)
+#if ENABLE(CONTENT_FILTERING) && !ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
m_contentFilter = !m_substituteData.isValid() ? ContentFilter::create(*this) : nullptr;
#endif
@@ -2230,7 +2230,7 @@
ASSERT(isMainThread());
if (m_mainResource && m_mainResource->hasClient(*this))
m_mainResource->removeClient(*this);
-#if ENABLE(CONTENT_FILTERING)
+#if ENABLE(CONTENT_FILTERING) && !ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
if (m_contentFilter)
m_contentFilter->stopFilteringMainResource();
#endif
@@ -2357,7 +2357,7 @@
void DocumentLoader::becomeMainResourceClient()
{
-#if ENABLE(CONTENT_FILTERING)
+#if ENABLE(CONTENT_FILTERING) && !ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
if (m_contentFilter)
m_contentFilter->startFilteringMainResource(*m_mainResource);
#endif
@@ -2414,7 +2414,7 @@
m_frame->document()->enqueueSecurityPolicyViolationEvent(WTFMove(eventInit));
}
-#if ENABLE(CONTENT_FILTERING)
+#if ENABLE(CONTENT_FILTERING) && !ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
void DocumentLoader::dataReceivedThroughContentFilter(const SharedBuffer& buffer)
{
dataReceived(buffer);
@@ -2425,12 +2425,19 @@
cancelMainResourceLoad(error);
}
+ResourceError DocumentLoader::contentFilterDidBlock(ContentFilterUnblockHandler unblockHandler, String&& unblockRequestDeniedScript)
+{
+ return handleContentFilterDidBlock(unblockHandler, WTFMove(unblockRequestDeniedScript));
+}
+
void DocumentLoader::handleProvisionalLoadFailureFromContentFilter(const URL& blockedPageURL, SubstituteData& substituteData)
{
frameLoader()->load(FrameLoadRequest(*frame(), blockedPageURL, substituteData));
}
+#endif // ENABLE(CONTENT_FILTERING) && !ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
-ResourceError DocumentLoader::contentFilterDidBlock(ContentFilterUnblockHandler unblockHandler, String&& unblockRequestDeniedScript)
+#if ENABLE(CONTENT_FILTERING)
+ResourceError DocumentLoader::handleContentFilterDidBlock(ContentFilterUnblockHandler unblockHandler, String&& unblockRequestDeniedScript)
{
unblockHandler.setUnreachableURL(documentURL());
if (!unblockRequestDeniedScript.isEmpty() && frame()) {
@@ -2440,8 +2447,40 @@
});
}
frameLoader()->client().contentFilterDidBlockLoad(WTFMove(unblockHandler));
- return frameLoader()->blockedByContentFilterError(request());
+ auto error = frameLoader()->blockedByContentFilterError(request());
+
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ m_blockedByContentFilter = true;
+ m_blockedError = error;
+#endif
+
+ return error;
}
+
+void DocumentLoader::handleContentFilterProvisionalLoadFailure(const URL& blockedPageURL, const SubstituteData& substituteData)
+{
+ frameLoader()->load(FrameLoadRequest(*frame(), blockedPageURL, substituteData));
+}
+
+bool DocumentLoader::contentFilterWillHandleProvisionalLoadFailure(const ResourceError& error)
+{
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ return m_blockedByContentFilter && m_blockedError.errorCode() == error.errorCode() && m_blockedError.domain() == error.domain();
+#else
+ return m_contentFilter && m_contentFilter->willHandleProvisionalLoadFailure(error);
+#endif
+}
+
+void DocumentLoader::contentFilterHandleProvisionalLoadFailure(const ResourceError& error)
+{
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ UNUSED_PARAM(error);
+#else
+ if (m_contentFilter)
+ m_contentFilter->handleProvisionalLoadFailure(error);
+#endif
+}
+
#endif // ENABLE(CONTENT_FILTERING)
void DocumentLoader::setActiveContentRuleListActionPatterns(const HashMap<String, Vector<String>>& patterns)
Modified: trunk/Source/WebCore/loader/DocumentLoader.h (290188 => 290189)
--- trunk/Source/WebCore/loader/DocumentLoader.h 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebCore/loader/DocumentLoader.h 2022-02-19 01:02:27 UTC (rev 290189)
@@ -159,7 +159,7 @@
: public RefCounted<DocumentLoader>
, public FrameDestructionObserver
, public ContentSecurityPolicyClient
-#if ENABLE(CONTENT_FILTERING)
+#if ENABLE(CONTENT_FILTERING) && !ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
, public ContentFilterClient
#endif
, private CachedRawResourceClient {
@@ -402,10 +402,14 @@
ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicyToPropagate() const;
#if ENABLE(CONTENT_FILTERING)
+#if !ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
ContentFilter* contentFilter() const { return m_contentFilter.get(); }
void ref() const final { RefCounted<DocumentLoader>::ref(); }
void deref() const final { RefCounted<DocumentLoader>::deref(); }
#endif
+ WEBCORE_EXPORT ResourceError handleContentFilterDidBlock(ContentFilterUnblockHandler, String&& unblockRequestDeniedScript);
+ WEBCORE_EXPORT void handleContentFilterProvisionalLoadFailure(const URL& blockedPageURL, const SubstituteData&);
+#endif
void startIconLoading();
WEBCORE_EXPORT void didGetLoadDecisionForIcon(bool decision, uint64_t loadIdentifier, CompletionHandler<void(FragmentedSharedBuffer*)>&&);
@@ -451,6 +455,11 @@
bool isContinuingLoadAfterProvisionalLoadStarted() const { return m_isContinuingLoadAfterProvisionalLoadStarted; }
void setIsContinuingLoadAfterProvisionalLoadStarted(bool isContinuingLoadAfterProvisionalLoadStarted) { m_isContinuingLoadAfterProvisionalLoadStarted = isContinuingLoadAfterProvisionalLoadStarted; }
+#if ENABLE(CONTENT_FILTERING)
+ bool contentFilterWillHandleProvisionalLoadFailure(const ResourceError&);
+ void contentFilterHandleProvisionalLoadFailure(const ResourceError&);
+#endif
+
protected:
WEBCORE_EXPORT DocumentLoader(const ResourceRequest&, const SubstituteData&);
@@ -503,7 +512,7 @@
void responseReceived(const ResourceResponse&, CompletionHandler<void()>&&);
-#if ENABLE(CONTENT_FILTERING)
+#if ENABLE(CONTENT_FILTERING) && !ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
// ContentFilterClient
WEBCORE_EXPORT void dataReceivedThroughContentFilter(const SharedBuffer&) final;
WEBCORE_EXPORT ResourceError contentFilterDidBlock(ContentFilterUnblockHandler, String&& unblockRequestDeniedScript) final;
@@ -655,8 +664,13 @@
std::unique_ptr<ContentSecurityPolicy> m_contentSecurityPolicy;
#if ENABLE(CONTENT_FILTERING)
+#if !ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
std::unique_ptr<ContentFilter> m_contentFilter;
+#else
+ bool m_blockedByContentFilter { false };
+ ResourceError m_blockedError;
#endif
+#endif
#if USE(QUICK_LOOK)
RefPtr<PreviewConverter> m_previewConverter;
Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (290188 => 290189)
--- trunk/Source/WebCore/loader/FrameLoader.cpp 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp 2022-02-19 01:02:27 UTC (rev 290189)
@@ -2453,7 +2453,6 @@
m_provisionalLoadErrorBeingHandledURL = provisionalDocumentLoader.url();
#if ENABLE(CONTENT_FILTERING)
- auto contentFilter = provisionalDocumentLoader.contentFilter();
auto contentFilterWillContinueLoading = false;
#endif
@@ -2461,7 +2460,7 @@
if (history().provisionalItem())
willContinueLoading = WillContinueLoading::Yes;
#if ENABLE(CONTENT_FILTERING)
- if (contentFilter && contentFilter->willHandleProvisionalLoadFailure(error)) {
+ if (provisionalDocumentLoader.contentFilterWillHandleProvisionalLoadFailure(error)) {
willContinueLoading = WillContinueLoading::Yes;
contentFilterWillContinueLoading = true;
}
@@ -2471,7 +2470,7 @@
#if ENABLE(CONTENT_FILTERING)
if (contentFilterWillContinueLoading)
- contentFilter->handleProvisionalLoadFailure(error);
+ provisionalDocumentLoader.contentFilterHandleProvisionalLoadFailure(error);
#endif
m_provisionalLoadErrorBeingHandledURL = { };
Modified: trunk/Source/WebCore/loader/PolicyChecker.cpp (290188 => 290189)
--- trunk/Source/WebCore/loader/PolicyChecker.cpp 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebCore/loader/PolicyChecker.cpp 2022-02-19 01:02:27 UTC (rev 290189)
@@ -141,7 +141,7 @@
auto& substituteData = loader->substituteData();
if (substituteData.isValid() && !substituteData.failingURL().isEmpty()) {
bool shouldContinue = true;
-#if ENABLE(CONTENT_FILTERING)
+#if ENABLE(CONTENT_FILTERING) && !ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
if (auto loader = m_frame.loader().activeDocumentLoader())
shouldContinue = ContentFilter::continueAfterSubstituteDataRequest(*loader, substituteData);
#endif
Modified: trunk/Source/WebCore/loader/SubstituteData.h (290188 => 290189)
--- trunk/Source/WebCore/loader/SubstituteData.h 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebCore/loader/SubstituteData.h 2022-02-19 01:02:27 UTC (rev 290189)
@@ -59,7 +59,10 @@
const String& textEncoding() const { return m_response.textEncodingName(); }
const URL& failingURL() const { return m_failingURL; }
const ResourceResponse& response() const { return m_response; }
-
+
+ template<class Encoder> void encode(Encoder&) const;
+ template<class Decoder> static std::optional<SubstituteData> decode(Decoder&);
+
private:
RefPtr<FragmentedSharedBuffer> m_content;
URL m_failingURL;
@@ -67,4 +70,36 @@
SessionHistoryVisibility m_shouldRevealToSessionHistory { SessionHistoryVisibility::Hidden };
};
+template<class Encoder>
+void SubstituteData::encode(Encoder& encoder) const
+{
+ encoder << m_content << m_failingURL << m_response << m_shouldRevealToSessionHistory;
+}
+
+template<class Decoder>
+std::optional<SubstituteData> SubstituteData::decode(Decoder& decoder)
+{
+ std::optional<RefPtr<FragmentedSharedBuffer>> content;
+ decoder >> content;
+ if (!content)
+ return std::nullopt;
+
+ std::optional<URL> failingURL;
+ decoder >> failingURL;
+ if (!failingURL)
+ return std::nullopt;
+
+ std::optional<ResourceResponse> response;
+ decoder >> response;
+ if (!response)
+ return std::nullopt;
+
+ std::optional<SessionHistoryVisibility> shouldRevealToSessionHistory;
+ decoder >> shouldRevealToSessionHistory;
+ if (!shouldRevealToSessionHistory)
+ return std::nullopt;
+
+ return { { WTFMove(*content), *failingURL, *response, *shouldRevealToSessionHistory } };
+}
+
} // namespace WebCore
Modified: trunk/Source/WebKit/ChangeLog (290188 => 290189)
--- trunk/Source/WebKit/ChangeLog 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebKit/ChangeLog 2022-02-19 01:02:27 UTC (rev 290189)
@@ -1,5 +1,47 @@
2022-02-18 Per Arne Vollan <pvol...@apple.com>
+ Move content filtering to Networking process
+ https://bugs.webkit.org/show_bug.cgi?id=233760
+ <rdar://problem/86150702>
+
+ Reviewed by Brent Fulgham.
+
+ Move content filtering from the DocumentLoader class in the WebProcess to the NetworkResourceLoader class in the
+ Networking process. The NetworkResourceLoader is now a client of the content filter, and will send messages
+ to the DocumentLoader in the WebProcess to cancel the load when the content filter decided to block the load.
+ If the content filter is providing replacement data, this will also be sent over IPC to the WebProcess.
+ Data is not being sent to the WebProcess until the content filter has decided to allow the load, if content
+ filtering is enabled.
+
+ * NetworkProcess/NetworkResourceLoader.cpp:
+ (WebKit::NetworkResourceLoader::start):
+ (WebKit::NetworkResourceLoader::startContentFiltering):
+ (WebKit::NetworkResourceLoader::didReceiveResponse):
+ (WebKit::NetworkResourceLoader::didFinishLoading):
+ (WebKit::NetworkResourceLoader::willSendRedirectedRequest):
+ (WebKit::NetworkResourceLoader::bufferingTimerFired):
+ (WebKit::NetworkResourceLoader::sendBuffer):
+ (WebKit::NetworkResourceLoader::didRetrieveCacheEntry):
+ (WebKit::NetworkResourceLoader::sendResultForCacheEntry):
+ (WebKit::NetworkResourceLoader::dataReceivedThroughContentFilter):
+ (WebKit::NetworkResourceLoader::contentFilterDidBlock):
+ (WebKit::NetworkResourceLoader::cancelMainResourceLoadForContentFilter):
+ (WebKit::NetworkResourceLoader::handleProvisionalLoadFailureFromContentFilter):
+ * NetworkProcess/NetworkResourceLoader.h:
+ * UIProcess/Network/NetworkProcessProxy.cpp:
+ (WebKit::NetworkProcessProxy::reloadAfterUnblockedContentFilter):
+ * UIProcess/Network/NetworkProcessProxy.h:
+ * UIProcess/Network/NetworkProcessProxy.messages.in:
+ * WebProcess/Network/WebResourceLoader.cpp:
+ (WebKit::WebResourceLoader::contentFilterDidBlockLoad):
+ (WebKit::WebResourceLoader::cancelMainResourceLoadForContentFilter):
+ (WebKit::WebResourceLoader::handleProvisionalLoadFailureFromContentFilter):
+ (WebKit::WebResourceLoader::reload):
+ * WebProcess/Network/WebResourceLoader.h:
+ * WebProcess/Network/WebResourceLoader.messages.in:
+
+2022-02-18 Per Arne Vollan <pvol...@apple.com>
+
[iOS] Add required Mach service to the sandbox of the GPU process
https://bugs.webkit.org/show_bug.cgi?id=236860
Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp (290188 => 290189)
--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp 2022-02-19 01:02:27 UTC (rev 290189)
@@ -67,6 +67,11 @@
#include <WebCore/PreviewConverter.h>
#endif
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+#include <WebCore/ContentFilter.h>
+#include <WebCore/ContentFilterUnblockHandler.h>
+#endif
+
#define LOADER_RELEASE_LOG(fmt, ...) RELEASE_LOG(Network, "%p - [pageProxyID=%" PRIu64 ", webPageID=%" PRIu64 ", frameID=%" PRIu64 ", resourceID=%" PRIu64 ", isMainResource=%d, destination=%u, isSynchronous=%d] NetworkResourceLoader::" fmt, this, m_parameters.webPageProxyID.toUInt64(), m_parameters.webPageID.toUInt64(), m_parameters.webFrameID.toUInt64(), m_parameters.identifier.toUInt64(), isMainResource(), static_cast<unsigned>(m_parameters.options.destination), isSynchronous(), ##__VA_ARGS__)
#define LOADER_RELEASE_LOG_ERROR(fmt, ...) RELEASE_LOG_ERROR(Network, "%p - [pageProxyID=%" PRIu64 ", webPageID=%" PRIu64 ", frameID=%" PRIu64 ", resourceID=%" PRIu64 ", isMainResource=%d, destination=%u, isSynchronous=%d] NetworkResourceLoader::" fmt, this, m_parameters.webPageProxyID.toUInt64(), m_parameters.webPageID.toUInt64(), m_parameters.webFrameID.toUInt64(), m_parameters.identifier.toUInt64(), isMainResource(), static_cast<unsigned>(m_parameters.options.destination), isSynchronous(), ##__VA_ARGS__)
@@ -187,8 +192,13 @@
ASSERT(!m_wasStarted);
m_wasStarted = true;
+ auto newRequest = ResourceRequest { originalRequest() };
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ startContentFiltering(newRequest);
+#endif
+
if (m_networkLoadChecker) {
- m_networkLoadChecker->check(ResourceRequest { originalRequest() }, this, [this, weakThis = WeakPtr { *this }] (auto&& result) {
+ m_networkLoadChecker->check(ResourceRequest { newRequest }, this, [this, weakThis = WeakPtr { *this }] (auto&& result) {
if (!weakThis)
return;
@@ -217,14 +227,26 @@
return;
}
// FIXME: Remove that code path once m_networkLoadChecker is used for all network loads.
- if (canUseCache(originalRequest())) {
+ if (canUseCache(newRequest)) {
retrieveCacheEntry(originalRequest());
return;
}
- startNetworkLoad(ResourceRequest { originalRequest() }, FirstLoad::Yes);
+ startNetworkLoad(ResourceRequest { newRequest }, FirstLoad::Yes);
}
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+void NetworkResourceLoader::startContentFiltering(ResourceRequest& request)
+{
+ if (!isMainResource())
+ return;
+ m_contentFilter = ContentFilter::create(*this);
+ if (!m_contentFilter->continueAfterWillSendRequest(request, ResourceResponse()))
+ return;
+ m_contentFilter->startFilteringMainResource(request.url());
+}
+#endif
+
void NetworkResourceLoader::retrieveCacheEntry(const ResourceRequest& request)
{
LOADER_RELEASE_LOG("retrieveCacheEntry: isMainFrameLoad=%d", isMainFrameLoad());
@@ -692,6 +714,11 @@
{
LOADER_RELEASE_LOG("didReceiveResponse: (httpStatusCode=%d, MIMEType=%" PUBLIC_LOG_STRING ", expectedContentLength=%" PRId64 ", hasCachedEntryForValidation=%d, hasNetworkLoadChecker=%d)", receivedResponse.httpStatusCode(), receivedResponse.mimeType().utf8().data(), receivedResponse.expectedContentLength(), !!m_cacheEntryForValidation, !!m_networkLoadChecker);
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ if (m_contentFilter && !m_contentFilter->continueAfterResponseReceived(receivedResponse))
+ return completionHandler(PolicyAction::Ignore);
+#endif
+
if (isMainResource())
didReceiveMainResourceResponse(receivedResponse);
@@ -904,6 +931,13 @@
// FIXME: Pass a real value or remove the encoded data size feature.
sendBuffer(*m_bufferedData.get(), -1);
}
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ if (m_contentFilter) {
+ m_contentFilter->continueAfterNotifyFinished(m_parameters.request.url());
+ m_contentFilter->stopFilteringMainResource();
+ }
+#endif
+
send(Messages::WebResourceLoader::DidFinishResourceLoad(networkLoadMetrics));
}
@@ -993,6 +1027,11 @@
if (!m_firstResponseURL.isValid())
m_firstResponseURL = redirectResponse.url();
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ if (m_contentFilter && !m_contentFilter->continueAfterWillSendRequest(request, redirectResponse))
+ return;
+#endif
+
std::optional<WebCore::PrivateClickMeasurement::AttributionTriggerData> privateClickMeasurementAttributionTriggerData;
if (!sessionID().isEphemeral()) {
if (auto result = WebCore::PrivateClickMeasurement::parseAttributionRequest(redirectRequest.url())) {
@@ -1251,8 +1290,14 @@
if (m_bufferedData.isEmpty())
return;
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ auto sharedBuffer = m_bufferedData.takeAsContiguous();
+ bool shouldFilter = m_contentFilter && !m_contentFilter->continueAfterDataReceived(sharedBuffer, m_bufferedDataEncodedDataLength);
+ if (!shouldFilter)
+ send(Messages::WebResourceLoader::DidReceiveData(IPC::SharedBufferCopy(sharedBuffer.get()), m_bufferedDataEncodedDataLength));
+#else
send(Messages::WebResourceLoader::DidReceiveData(IPC::SharedBufferCopy(*m_bufferedData.get()), m_bufferedDataEncodedDataLength));
-
+#endif
m_bufferedData.empty();
m_bufferedDataEncodedDataLength = 0;
}
@@ -1261,6 +1306,11 @@
{
ASSERT(!isSynchronous());
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ if (m_contentFilter && !m_contentFilter->continueAfterDataReceived(buffer.makeContiguous(), encodedDataLength))
+ return;
+#endif
+
send(Messages::WebResourceLoader::DidReceiveData(IPC::SharedBufferCopy(buffer), encodedDataLength));
}
@@ -1307,6 +1357,11 @@
LOADER_RELEASE_LOG("didRetrieveCacheEntry:");
auto response = entry->response();
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ if (m_contentFilter && !m_contentFilter->responseReceived() && !m_contentFilter->continueAfterResponseReceived(response))
+ return;
+#endif
+
if (isMainResource())
didReceiveMainResourceResponse(response);
@@ -1358,6 +1413,13 @@
LOADER_RELEASE_LOG("sendResultForCacheEntry:");
#if ENABLE(SHAREABLE_RESOURCE)
if (!entry->shareableResourceHandle().isNull()) {
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ if (m_contentFilter && !m_contentFilter->continueAfterDataReceived(entry->buffer()->makeContiguous(), entry->buffer()->size())) {
+ m_contentFilter->continueAfterNotifyFinished(m_parameters.request.url());
+ m_contentFilter->stopFilteringMainResource();
+ return;
+ }
+#endif
send(Messages::WebResourceLoader::DidReceiveResource(entry->shareableResourceHandle()));
return;
}
@@ -1381,6 +1443,12 @@
networkLoadMetrics.responseBodyDecodedSize = 0;
sendBuffer(*entry->buffer(), entry->buffer()->size());
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ if (m_contentFilter) {
+ m_contentFilter->continueAfterNotifyFinished(m_parameters.request.url());
+ m_contentFilter->stopFilteringMainResource();
+ }
+#endif
send(Messages::WebResourceLoader::DidFinishResourceLoad(networkLoadMetrics));
}
@@ -1697,6 +1765,43 @@
return m_parameters.request.isAppInitiated();
}
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+void NetworkResourceLoader::dataReceivedThroughContentFilter(const SharedBuffer& buffer, size_t encodedDataLength)
+{
+ send(Messages::WebResourceLoader::DidReceiveData(IPC::SharedBufferCopy(buffer), encodedDataLength));
+}
+
+WebCore::ResourceError NetworkResourceLoader::contentFilterDidBlock(WebCore::ContentFilterUnblockHandler unblockHandler, String&& unblockRequestDeniedScript)
+{
+ send(Messages::WebResourceLoader::ContentFilterDidBlockLoad(unblockHandler, unblockRequestDeniedScript));
+ if (!unblockHandler.needsUIProcess()) {
+ unblockHandler.requestUnblockAsync([this, protectedThis = Ref { *this }](bool unblocked) {
+ if (!unblocked)
+ return;
+ m_connection->networkProcess().parentProcessConnection()->send(Messages::NetworkProcessProxy::ReloadAfterUnblockedContentFilter(m_parameters.webPageProxyID), 0);
+ });
+ }
+ return WebKit::blockedByContentFilterError(m_parameters.request);
+}
+
+void NetworkResourceLoader::cancelMainResourceLoadForContentFilter(const WebCore::ResourceError& error)
+{
+ RELEASE_ASSERT(m_contentFilter);
+ m_contentFilter->handleProvisionalLoadFailure(error);
+}
+
+void NetworkResourceLoader::handleProvisionalLoadFailureFromContentFilter(const URL& blockedPageURL, WebCore::SubstituteData& substituteData)
+{
+ if (substituteData.isValid())
+ send(Messages::WebResourceLoader::HandleProvisionalLoadFailureFromContentFilter(blockedPageURL, substituteData));
+ else {
+ RELEASE_ASSERT(m_contentFilter);
+ auto& error = m_contentFilter->blockedError();
+ send(Messages::WebResourceLoader::CancelMainResourceLoadForContentFilter(error));
+ }
+}
+#endif // ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+
} // namespace WebKit
#undef LOADER_RELEASE_LOG
Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.h (290188 => 290189)
--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.h 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.h 2022-02-19 01:02:27 UTC (rev 290189)
@@ -34,6 +34,7 @@
#include "NetworkResourceLoadIdentifier.h"
#include "NetworkResourceLoadParameters.h"
#include "PrivateRelayed.h"
+#include <WebCore/ContentFilterClient.h>
#include <WebCore/ContentSecurityPolicyClient.h>
#include <WebCore/CrossOriginAccessControl.h>
#include <WebCore/PrivateClickMeasurement.h>
@@ -45,6 +46,7 @@
namespace WebCore {
class BlobDataFileReference;
+class ContentFilter;
class FormData;
class NetworkStorageSession;
class ResourceRequest;
@@ -72,6 +74,9 @@
, public IPC::MessageSender
, public WebCore::ContentSecurityPolicyClient
, public WebCore::CrossOriginAccessControlCheckDisabler
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ , public WebCore::ContentFilterClient
+#endif
, public CanMakeWeakPtr<NetworkResourceLoader> {
public:
static Ref<NetworkResourceLoader> create(NetworkResourceLoadParameters&& parameters, NetworkConnectionToWebProcess& connection, Messages::NetworkConnectionToWebProcess::PerformSynchronousLoadDelayedReply&& reply = nullptr)
@@ -92,7 +97,7 @@
// Message handlers.
void didReceiveNetworkResourceLoaderMessage(IPC::Connection&, IPC::Decoder&);
- void continueWillSendRequest(WebCore::ResourceRequest&& newRequest, bool isAllowedToAskUserForCredentials);
+ void continueWillSendRequest(WebCore::ResourceRequest&&, bool isAllowedToAskUserForCredentials);
void setResponse(WebCore::ResourceResponse&& response) { m_response = WTFMove(response); }
const WebCore::ResourceResponse& response() const { return m_response; }
@@ -155,6 +160,11 @@
bool isAppInitiated();
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ void ref() const final { RefCounted<NetworkResourceLoader>::ref(); }
+ void deref() const final { RefCounted<NetworkResourceLoader>::deref(); }
+#endif
+
private:
NetworkResourceLoader(NetworkResourceLoadParameters&&, NetworkConnectionToWebProcess&, Messages::NetworkConnectionToWebProcess::PerformSynchronousLoadDelayedReply&&);
@@ -162,6 +172,14 @@
IPC::Connection* messageSenderConnection() const override;
uint64_t messageSenderDestinationID() const override { return m_parameters.identifier.toUInt64(); }
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ // ContentFilterClient
+ void dataReceivedThroughContentFilter(const WebCore::SharedBuffer&, size_t) final;
+ WebCore::ResourceError contentFilterDidBlock(WebCore::ContentFilterUnblockHandler, String&& unblockRequestDeniedScript) final;
+ void cancelMainResourceLoadForContentFilter(const WebCore::ResourceError&) final;
+ void handleProvisionalLoadFailureFromContentFilter(const URL& blockedPageURL, WebCore::SubstituteData&) final;
+#endif
+
bool canUseCache(const WebCore::ResourceRequest&) const;
bool canUseCachedRedirect(const WebCore::ResourceRequest&) const;
@@ -220,6 +238,10 @@
ResourceLoadInfo resourceLoadInfo();
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ void startContentFiltering(WebCore::ResourceRequest&);
+#endif
+
const NetworkResourceLoadParameters m_parameters;
Ref<NetworkConnectionToWebProcess> m_connection;
@@ -264,6 +286,11 @@
WebCore::ResourceResponse m_redirectResponse;
URL m_firstResponseURL; // First URL in response's URL list (https://fetch.spec.whatwg.org/#concept-response-url-list).
std::optional<WebCore::CrossOriginOpenerPolicyEnforcementResult> m_currentCoopEnforcementResult;
+
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ std::unique_ptr<WebCore::ContentFilter> m_contentFilter;
+#endif
+
PrivateRelayed m_privateRelayed { PrivateRelayed::No };
};
Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (290188 => 290189)
--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp 2022-02-19 01:02:27 UTC (rev 290189)
@@ -28,6 +28,7 @@
#include "APIContentRuleList.h"
#include "APICustomProtocolManagerClient.h"
+#include "APINavigation.h"
#include "AuthenticationChallengeProxy.h"
#include "AuthenticationManager.h"
#include "DownloadProxyMap.h"
@@ -604,6 +605,14 @@
page->resourceLoadDidCompleteWithError(WTFMove(loadInfo), WTFMove(response), WTFMove(error));
}
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+void NetworkProcessProxy::reloadAfterUnblockedContentFilter(WebPageProxyIdentifier pageID)
+{
+ if (auto* page = WebProcessProxy::webPage(pageID))
+ page->reload({ });
+}
+#endif
+
#if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
void NetworkProcessProxy::dumpResourceLoadStatistics(PAL::SessionID sessionID, CompletionHandler<void(String)>&& completionHandler)
{
Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h (290188 => 290189)
--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h 2022-02-19 01:02:27 UTC (rev 290189)
@@ -254,6 +254,10 @@
void resourceLoadDidReceiveResponse(WebPageProxyIdentifier, ResourceLoadInfo&&, WebCore::ResourceResponse&&);
void resourceLoadDidCompleteWithError(WebPageProxyIdentifier, ResourceLoadInfo&&, WebCore::ResourceResponse&&, WebCore::ResourceError&&);
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ void reloadAfterUnblockedContentFilter(WebPageProxyIdentifier);
+#endif
+
#if ENABLE(APP_BOUND_DOMAINS)
void hasAppBoundSession(PAL::SessionID, CompletionHandler<void(bool)>&&);
void clearAppBoundSession(PAL::SessionID, CompletionHandler<void()>&&);
Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in (290188 => 290189)
--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in 2022-02-19 01:02:27 UTC (rev 290189)
@@ -76,6 +76,10 @@
ResourceLoadDidReceiveChallenge(WebKit::WebPageProxyIdentifier pageIdentifier, struct WebKit::ResourceLoadInfo resourceLoadInfo, WebCore::AuthenticationChallenge challenge)
ResourceLoadDidReceiveResponse(WebKit::WebPageProxyIdentifier pageIdentifier, struct WebKit::ResourceLoadInfo resourceLoadInfo, WebCore::ResourceResponse response)
ResourceLoadDidCompleteWithError(WebKit::WebPageProxyIdentifier pageIdentifier, struct WebKit::ResourceLoadInfo resourceLoadInfo, WebCore::ResourceResponse response, WebCore::ResourceError error)
+
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ ReloadAfterUnblockedContentFilter(WebKit::WebPageProxyIdentifier pageIdentifier)
+#endif
TriggerBrowsingContextGroupSwitchForNavigation(WebKit::WebPageProxyIdentifier pageIdentifier, uint64_t navigationID, enum:uint8_t WebCore::BrowsingContextGroupSwitchDecision browsingContextGroupSwitchDecision, WebCore::RegistrableDomain responseDomain, WebKit::NetworkResourceLoadIdentifier existingNetworkResourceLoadIdentifierToResume) -> (bool success) Async
Modified: trunk/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp (290188 => 290189)
--- trunk/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp 2022-02-19 01:02:27 UTC (rev 290189)
@@ -54,6 +54,7 @@
#include <WebCore/ResourceError.h>
#include <WebCore/ResourceLoader.h>
#include <WebCore/SubresourceLoader.h>
+#include <WebCore/SubstituteData.h>
#include <wtf/CompletionHandler.h>
#define WEBRESOURCELOADER_RELEASE_LOG(fmt, ...) RELEASE_LOG(Network, "%p - [webPageID=%" PRIu64 ", frameID=%" PRIu64 ", resourceID=%" PRIu64 "] WebResourceLoader::" fmt, this, m_trackingParameters.pageID.toUInt64(), m_trackingParameters.frameID.toUInt64(), m_trackingParameters.resourceID.toUInt64(), ##__VA_ARGS__)
@@ -349,6 +350,29 @@
}
#endif
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+void WebResourceLoader::contentFilterDidBlockLoad(const WebCore::ContentFilterUnblockHandler& unblockHandler, String&& unblockRequestDeniedScript)
+{
+ if (!m_coreLoader || !m_coreLoader->documentLoader())
+ return;
+ m_coreLoader->documentLoader()->handleContentFilterDidBlock(unblockHandler, WTFMove(unblockRequestDeniedScript));
+}
+
+void WebResourceLoader::cancelMainResourceLoadForContentFilter(const WebCore::ResourceError& error)
+{
+ if (!m_coreLoader || !m_coreLoader->documentLoader())
+ return;
+ m_coreLoader->documentLoader()->cancelMainResourceLoad(error);
+}
+
+void WebResourceLoader::handleProvisionalLoadFailureFromContentFilter(const URL& blockedPageURL, const WebCore::SubstituteData& substituteData)
+{
+ if (!m_coreLoader || !m_coreLoader->documentLoader() || !substituteData.isValid())
+ return;
+ m_coreLoader->documentLoader()->handleContentFilterProvisionalLoadFailure(blockedPageURL, substituteData);
+}
+#endif // ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+
} // namespace WebKit
#undef WEBRESOURCELOADER_RELEASE_LOG
Modified: trunk/Source/WebKit/WebProcess/Network/WebResourceLoader.h (290188 => 290189)
--- trunk/Source/WebKit/WebProcess/Network/WebResourceLoader.h 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebKit/WebProcess/Network/WebResourceLoader.h 2022-02-19 01:02:27 UTC (rev 290189)
@@ -43,11 +43,13 @@
}
namespace WebCore {
+class ContentFilterUnblockHandler;
class NetworkLoadMetrics;
class ResourceError;
class ResourceLoader;
class ResourceRequest;
class ResourceResponse;
+class SubstituteData;
enum class MainFrameMainResource : bool;
}
@@ -99,6 +101,12 @@
void didReceiveResource(const ShareableResource::Handle&);
#endif
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ void contentFilterDidBlockLoad(const WebCore::ContentFilterUnblockHandler&, String&& unblockRequestDeniedScript);
+ void cancelMainResourceLoadForContentFilter(const WebCore::ResourceError&);
+ void handleProvisionalLoadFailureFromContentFilter(const URL& blockedPageURL, const WebCore::SubstituteData&);
+#endif
+
RefPtr<WebCore::ResourceLoader> m_coreLoader;
TrackingParameters m_trackingParameters;
WebResourceInterceptController m_interceptController;
Modified: trunk/Source/WebKit/WebProcess/Network/WebResourceLoader.messages.in (290188 => 290189)
--- trunk/Source/WebKit/WebProcess/Network/WebResourceLoader.messages.in 2022-02-19 00:57:42 UTC (rev 290188)
+++ trunk/Source/WebKit/WebProcess/Network/WebResourceLoader.messages.in 2022-02-19 01:02:27 UTC (rev 290189)
@@ -37,4 +37,11 @@
// DidReceiveResource is for when we have the entire resource data available at once, such as when the resource is cached in memory
DidReceiveResource(WebKit::ShareableResource::Handle resource)
#endif
+
+#if ENABLE(CONTENT_FILTERING_IN_NETWORKING_PROCESS)
+ ContentFilterDidBlockLoad(WebCore::ContentFilterUnblockHandler unblockHandler, String unblockRequestDeniedScript)
+ CancelMainResourceLoadForContentFilter(WebCore::ResourceError error)
+ HandleProvisionalLoadFailureFromContentFilter(URL blockedPageURL, WebCore::SubstituteData substituteData)
+#endif
+
}