https://bugs.webkit.org/show_bug.cgi?id=196807
Reviewed by Alex Christensen.
LayoutTests/imported/w3c:
* web-platform-tests/beacon/headers/header-content-type-expected.txt:
Source/WebCore:
Make use of regular code path for ping loads and beacon.
This is done conditionally on KeepAlive flag.
The benefits are a single loading code path and service worker interception.
For that purpose, introduce a LoaderStrategy switch based on KeepAlive runtime flag.
This switch is used to use ping loads when keepAlive is set or regular loads.
In case of regular loads, the keepAlive flag should be used to extend the lifetime of the load.
Migrate ping loads to use CachedResourceLoader instead of PingLoad.
For that purpose, introduce a new Ping CachedResource type.
Covered by existing tests.
* Modules/beacon/NavigatorBeacon.cpp:
(WebCore::NavigatorBeacon::sendBeacon):
* inspector/agents/InspectorPageAgent.cpp:
(WebCore::InspectorPageAgent::inspectorResourceType):
* loader/LinkLoader.cpp:
(WebCore::createLinkPreloadResourceClient):
* loader/LoaderStrategy.h:
* loader/PingLoader.cpp:
(WebCore::PingLoader::loadImage):
(WebCore::PingLoader::sendPing):
(WebCore::PingLoader::sendViolationReport):
(WebCore::PingLoader::startPingLoad):
* loader/PingLoader.h:
* loader/ResourceLoadInfo.cpp:
(WebCore::toResourceType):
* loader/SubresourceLoader.cpp:
(WebCore::logResourceLoaded):
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource::defaultPriorityForResourceType):
(WebCore::CachedResource::load):
(WebCore::CachedResource::cancelLoad):
* loader/cache/CachedResource.h:
(WebCore::CachedResource::shouldUsePingLoad):
(WebCore::CachedResource::isMainOrMediaOrIconOrRawResource const):
* loader/cache/CachedResourceLoader.cpp:
(WebCore::createResource):
(WebCore::CachedResourceLoader::requestPingResource):
(WebCore::contentTypeFromResourceType):
(WebCore::CachedResourceLoader::checkInsecureContent const):
(WebCore::CachedResourceLoader::allowedByContentSecurityPolicy const):
(WebCore::CachedResourceLoader::canRequest):
(WebCore::isResourceSuitableForDirectReuse):
(WebCore::destinationForType):
* loader/cache/CachedResourceLoader.h:
Source/WebKit:
In case a NetworkResourceLoader has the keepAlive option we do the following:
- Always use NetworkLoadChecker as we might need it to do checks after the Web context is gone.
- In case of aborting a KeepAlive loader, remove it from NetworkConnectionToWebProcess map
and add it to a kept-alive NetworkSession load set. The loader is only kept alive if it
has not yet received a response. Mark the loader as kept-alive.
- In case loader is kept-alive, cancel the load as soon as a response is gathered.
* NetworkProcess/NetworkConnectionToWebProcess.cpp:
(WebKit::NetworkConnectionToWebProcess::transferKeptAliveLoad):
* NetworkProcess/NetworkConnectionToWebProcess.h:
* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::addKeptAliveLoad):
(WebKit::NetworkProcess::removeKeptAliveLoad):
* NetworkProcess/NetworkProcess.h:
* NetworkProcess/NetworkResourceLoadMap.cpp:
(WebKit::NetworkResourceLoadMap::remove):
(WebKit::NetworkResourceLoadMap::take):
* NetworkProcess/NetworkResourceLoadMap.h:
* NetworkProcess/NetworkResourceLoader.cpp:
(WebKit::m_shouldCaptureExtraNetworkLoadMetrics):
(WebKit::NetworkResourceLoader::cleanup):
(WebKit::NetworkResourceLoader::abort):
(WebKit::NetworkResourceLoader::didReceiveResponse):
(WebKit::NetworkResourceLoader::continueWillSendRedirectedRequest):
* NetworkProcess/NetworkResourceLoader.h:
* WebProcess/Network/WebLoaderStrategy.cpp:
(WebKit::maximumBufferingTime):
(WebKit::WebLoaderStrategy::usePingLoad const):
* WebProcess/Network/WebLoaderStrategy.h:
LayoutTests:
* TestExpectations:
* http/tests/blink/sendbeacon/beacon-cross-origin.https-expected.txt:
* http/tests/blink/sendbeacon/connect-src-beacon-allowed.html:
* http/tests/security/contentSecurityPolicy/connect-src-beacon-allowed.html:
* http/tests/security/contentSecurityPolicy/report-only-connect-src-beacon-redirect-blocked-expected.txt:
* http/tests/security/contentSecurityPolicy/report-only-connect-src-beacon-redirect-blocked.php:
* http/tests/security/contentSecurityPolicy/user-style-sheet-font-crasher-expected.txt:
* http/wpt/beacon/beacon-async-error-logging-expected.txt:
* http/wpt/beacon/beacon-async-error-logging.html:
* http/wpt/beacon/connect-src-beacon-redirect-blocked.sub-expected.txt:
* http/wpt/beacon/contentextensions/beacon-redirect-blocked-expected.txt:
* http/wpt/beacon/resources/beacon-preflight.py:
(respondToCORSPreflight):
(main):
* platform/wk2/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-css-in-iframe-report-only-expected.txt:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244700
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
2019-04-26 Youenn Fablet <youenn@apple.com>
+ Use normal loading path for ping loads
+ https://bugs.webkit.org/show_bug.cgi?id=196807
+
+ Reviewed by Alex Christensen.
+
+ * TestExpectations:
+ * http/tests/blink/sendbeacon/beacon-cross-origin.https-expected.txt:
+ * http/tests/blink/sendbeacon/connect-src-beacon-allowed.html:
+ * http/tests/security/contentSecurityPolicy/connect-src-beacon-allowed.html:
+ * http/tests/security/contentSecurityPolicy/report-only-connect-src-beacon-redirect-blocked-expected.txt:
+ * http/tests/security/contentSecurityPolicy/report-only-connect-src-beacon-redirect-blocked.php:
+ * http/tests/security/contentSecurityPolicy/user-style-sheet-font-crasher-expected.txt:
+ * http/wpt/beacon/beacon-async-error-logging-expected.txt:
+ * http/wpt/beacon/beacon-async-error-logging.html:
+ * http/wpt/beacon/connect-src-beacon-redirect-blocked.sub-expected.txt:
+ * http/wpt/beacon/contentextensions/beacon-redirect-blocked-expected.txt:
+ * http/wpt/beacon/resources/beacon-preflight.py:
+ (respondToCORSPreflight):
+ (main):
+ * platform/wk2/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-css-in-iframe-report-only-expected.txt:
+
+2019-04-26 Youenn Fablet <youenn@apple.com>
+
Mark some cache-storage as slow on iOS-simulator
https://bugs.webkit.org/show_bug.cgi?id=197316
imported/w3c/web-platform-tests/fetch/nosniff [ DumpJSConsoleLogInStdErr ]
imported/w3c/web-platform-tests/html/semantics/embedded-content/the-iframe-element/sandbox-ascii-case-insensitive.html [ DumpJSConsoleLogInStdErr ]
+http/wpt/beacon/cors/cors-preflight-blob-failure.html [ DumpJSConsoleLogInStdErr ]
+http/wpt/beacon/cors/cors-preflight-blob-success.html [ DumpJSConsoleLogInStdErr ]
+http/wpt/beacon/cors/cors-preflight-cookie.html [ DumpJSConsoleLogInStdErr ]
+http/wpt/beacon/cors/cors-preflight-redirect-failure.html [ DumpJSConsoleLogInStdErr ]
+http/wpt/beacon/cors/cors-preflight-redirect-from-crossorigin-to-sameorigin.html [ DumpJSConsoleLogInStdErr ]
+http/wpt/beacon/cors/cors-preflight-redirect-success.html [ DumpJSConsoleLogInStdErr ]
+http/wpt/beacon/cors/crossorigin-arraybufferview-no-preflight.html [ DumpJSConsoleLogInStdErr ]
+
+http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-css-in-iframe-report-only.html [ Pass Failure ]
+
# Imported css-text test suite from WPT
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/hanging-punctuation/hanging-punctuation-first-001.xht [ ImageOnlyFailure ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/hanging-punctuation/hanging-punctuation-force-end-001.xht [ ImageOnlyFailure ]
+Blocked access to external URL http://example.test:8000/blink/sendbeacon/resources/save-beacon.php?name=cross-origin
+CONSOLE MESSAGE: line 1: Beacon API cannot load http://example.test:8000/blink/sendbeacon/resources/save-beacon.php?name=cross-origin due to access control checks.
Verify navigator.sendBeacon() mixed content checking.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-FAIL navigator.sendBeacon("http://example.test:8000/blink/sendbeacon/resources/save-beacon.php?name=cross-origin", "CrossOrigin"); should be false. Was true.
+PASS navigator.sendBeacon("http://example.test:8000/blink/sendbeacon/resources/save-beacon.php?name=cross-origin", "CrossOrigin"); is false
PASS successfullyParsed is true
-Some tests failed.
TEST COMPLETE
CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/security/contentSecurityPolicy/example_font.woff because it does not appear in the font-src directive of the Content Security Policy.
+Blocked access to external URL http://webkit.org/report
CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/security/contentSecurityPolicy/example_font.woff because it does not appear in the font-src directive of the Content Security Policy.
+Blocked access to external URL http://webkit.org/report
The iframe below triggers a violation report creating the initial empty document. It should not crash the web process.
-CONSOLE MESSAGE: Beacon API cannot load http://invalid.localhost/. A server with the specified hostname could not be found.
+CONSOLE MESSAGE: Beacon API cannot load http://localhost:1/. Not allowed to use restricted network port
PASS Should log an error message in the console
} else {
setTimeout(function() { t.done(); }, 500);
}
- let invalidHost = "http://invalid.localhost";
- assert_true(navigator.sendBeacon(invalidHost, 'test'), "sendBeacon should return true");
+ let hostWithInvalidPort = "http://localhost:1";
+ assert_true(navigator.sendBeacon(hostWithInvalidPort, 'test'), "sendBeacon should return true");
}, "Should log an error message in the console");
</script>
</body>
+CONSOLE MESSAGE: Refused to connect to http://127.0.0.1:8800/WebKit/beacon/resources/beacon-preflight.py?allowCors=1&cmd=put&id=2539e883-7dfb-4dde-a227-a41c670d5fe1&redirect_status=307&location=http%3A%2F%2F127.0.0.1%3A8800%2FWebKit%2Fbeacon%2Fresources%2Fbeacon-preflight.py%3FallowCors%3D1%26cmd%3Dput%26id%3D2539e883-7dfb-4dde-a227-a41c670d5fe1&count=1 because it does not appear in the connect-src directive of the Content Security Policy.
+CONSOLE MESSAGE: Blocked by Content Security Policy.
CONSOLE MESSAGE: Beacon API cannot load http://127.0.0.1:8800/WebKit/beacon/resources/beacon-preflight.py?allowCors=1&cmd=put&id=2539e883-7dfb-4dde-a227-a41c670d5fe1&redirect_status=307&location=http%3A%2F%2F127.0.0.1%3A8800%2FWebKit%2Fbeacon%2Fresources%2Fbeacon-preflight.py%3FallowCors%3D1%26cmd%3Dput%26id%3D2539e883-7dfb-4dde-a227-a41c670d5fe1&count=1. Blocked by Content Security Policy.
PASS Redirect is blocked by CSP
-CONSOLE MESSAGE: Beacon API cannot load http://127.0.0.1:8800/WebKit/beacon/resources/beacon-preflight.py?allowCors=1&cmd=put&id=f470f43c-258c-4c82-b880-ace3bcdb211c&redirect_status=307&location=http%3A%2F%2F127.0.0.1%3A8800%2FWebKit%2Fbeacon%2Fresources%2Fbeacon-preflight.py%3FallowCors%3D1%26cmd%3Dput%26id%3Df470f43c-258c-4c82-b880-ace3bcdb211c&count=1. Blocked by content extension
+CONSOLE MESSAGE: Content blocker prevented frame displaying http://localhost:8800/WebKit/beacon/contentextensions/beacon-redirect-blocked.html from loading a resource from http://127.0.0.1:8800/WebKit/beacon/resources/beacon-preflight.py?allowCors=1&cmd=put&id=f470f43c-258c-4c82-b880-ace3bcdb211c&redirect_status=307&location=http%3A%2F%2F127.0.0.1%3A8800%2FWebKit%2Fbeacon%2Fresources%2Fbeacon-preflight.py%3FallowCors%3D1%26cmd%3Dput%26id%3Df470f43c-258c-4c82-b880-ace3bcdb211c&count=1
+CONSOLE MESSAGE: Beacon API cannot load http://localhost:8800/WebKit/beacon/resources/redirect.py?redirect_status=307&location=http%3A%2F%2F127.0.0.1%3A8800%2FWebKit%2Fbeacon%2Fresources%2Fbeacon-preflight.py%3FallowCors%3D1%26cmd%3Dput%26id%3Df470f43c-258c-4c82-b880-ace3bcdb211c. The URL was blocked by a content blocker
PASS Content extensions should be able to block beacon redirects
import json
def respondToCORSPreflight(request, response):
+ headers = [("Content-Type", "text/plain")]
allow_cors = int(request.GET.first("allowCors", 0)) != 0;
if not allow_cors:
response.set_error(400, "Not allowed")
- return "ERROR: Not allowed"
+ return headers, "ERROR: Not allowed"
if not "Access-Control-Request-Method" in request.headers:
response.set_error(400, "No Access-Control-Request-Method header")
- return "ERROR: No access-control-request-method in preflight!"
+ return headers, "ERROR: No access-control-request-method in preflight!"
- headers = [("Content-Type", "text/plain")]
headers.append(("Access-Control-Allow-Origin", request.headers.get("Origin", "*")))
headers.append(("Access-Control-Allow-Credentials", "true"))
requested_method = request.headers.get("Access-Control-Request-Method", None)
return [("Content-Type", "text/plain")], ""
response.set_error(400, "Bad Command")
- return "ERROR: Bad Command!"
+ return [("Content-Type", "text/plain")], "ERROR: Bad Command!"
2019-04-26 Youenn Fablet <youenn@apple.com>
+ Use normal loading path for ping loads
+ https://bugs.webkit.org/show_bug.cgi?id=196807
+
+ Reviewed by Alex Christensen.
+
+ * web-platform-tests/beacon/headers/header-content-type-expected.txt:
+
+2019-04-26 Youenn Fablet <youenn@apple.com>
+
[Mac WK2 iOS Sim] Layout Test imported/w3c/web-platform-tests/webrtc/RTCRtpReceiver-getSynchronizationSources.https.html is a flaky failure
https://bugs.webkit.org/show_bug.cgi?id=196633
<rdar://problem/49627667>
-Harness Error (TIMEOUT), message = null
-
-TIMEOUT Test content-type header for a body string Test timed out
-NOTRUN Test content-type header for a body ArrayBufferView
-NOTRUN Test content-type header for a body ArrayBuffer
-NOTRUN Test content-type header for a body Blob
-NOTRUN Test content-type header for a body FormData
-NOTRUN Test content-type header for a body URLSearchParams
+PASS Test content-type header for a body string
+PASS Test content-type header for a body ArrayBufferView
+PASS Test content-type header for a body ArrayBuffer
+PASS Test content-type header for a body Blob
+PASS Test content-type header for a body FormData
+PASS Test content-type header for a body URLSearchParams
--- /dev/null
+CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/security/contentSecurityPolicy/example_font.woff because it does not appear in the font-src directive of the Content Security Policy.
+CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/security/contentSecurityPolicy/example_font.woff because it does not appear in the font-src directive of the Content Security Policy.
+The iframe below triggers a violation report creating the initial empty document. It should not crash the web process.
+
--- /dev/null
+CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/security/contentSecurityPolicy/example_font.woff because it does not appear in the font-src directive of the Content Security Policy.
+CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/security/contentSecurityPolicy/example_font.woff because it does not appear in the font-src directive of the Content Security Policy.
+The iframe below triggers a violation report creating the initial empty document. It should not crash the web process.
+
frame "<!--frame1-->" - didFinishDocumentLoadForFrame
main frame - didHandleOnloadEventsForFrame
frame "<!--frame1-->" - didFinishLoadForFrame
-main frame - didFinishLoadForFrame
frame "<!--frame1-->" - didStartProvisionalLoadForFrame
frame "<!--frame1-->" - didCancelClientRedirectForFrame
frame "<!--frame1-->" - didCommitLoadForFrame
frame "<!--frame1-->" - didFinishDocumentLoadForFrame
frame "<!--frame1-->" - didHandleOnloadEventsForFrame
frame "<!--frame1-->" - didFinishLoadForFrame
+main frame - didFinishLoadForFrame
This test loads a secure iframe that loads an insecure stylesheet. We should trigger a mixed content block even though the child frame has a report only CSP block-all-mixed-content directive because an active network attacker can use CSS3 to breach the confidentiality of the HTTPS security origin.
+2019-04-26 Youenn Fablet <youenn@apple.com>
+
+ Use normal loading path for ping loads
+ https://bugs.webkit.org/show_bug.cgi?id=196807
+
+ Reviewed by Alex Christensen.
+
+ Make use of regular code path for ping loads and beacon.
+ This is done conditionally on KeepAlive flag.
+ The benefits are a single loading code path and service worker interception.
+
+ For that purpose, introduce a LoaderStrategy switch based on KeepAlive runtime flag.
+ This switch is used to use ping loads when keepAlive is set or regular loads.
+ In case of regular loads, the keepAlive flag should be used to extend the lifetime of the load.
+
+ Migrate ping loads to use CachedResourceLoader instead of PingLoad.
+ For that purpose, introduce a new Ping CachedResource type.
+
+ Covered by existing tests.
+
+ * Modules/beacon/NavigatorBeacon.cpp:
+ (WebCore::NavigatorBeacon::sendBeacon):
+ * inspector/agents/InspectorPageAgent.cpp:
+ (WebCore::InspectorPageAgent::inspectorResourceType):
+ * loader/LinkLoader.cpp:
+ (WebCore::createLinkPreloadResourceClient):
+ * loader/LoaderStrategy.h:
+ * loader/PingLoader.cpp:
+ (WebCore::PingLoader::loadImage):
+ (WebCore::PingLoader::sendPing):
+ (WebCore::PingLoader::sendViolationReport):
+ (WebCore::PingLoader::startPingLoad):
+ * loader/PingLoader.h:
+ * loader/ResourceLoadInfo.cpp:
+ (WebCore::toResourceType):
+ * loader/SubresourceLoader.cpp:
+ (WebCore::logResourceLoaded):
+ * loader/cache/CachedResource.cpp:
+ (WebCore::CachedResource::defaultPriorityForResourceType):
+ (WebCore::CachedResource::load):
+ (WebCore::CachedResource::cancelLoad):
+ * loader/cache/CachedResource.h:
+ (WebCore::CachedResource::shouldUsePingLoad):
+ (WebCore::CachedResource::isMainOrMediaOrIconOrRawResource const):
+ * loader/cache/CachedResourceLoader.cpp:
+ (WebCore::createResource):
+ (WebCore::CachedResourceLoader::requestPingResource):
+ (WebCore::contentTypeFromResourceType):
+ (WebCore::CachedResourceLoader::checkInsecureContent const):
+ (WebCore::CachedResourceLoader::allowedByContentSecurityPolicy const):
+ (WebCore::CachedResourceLoader::canRequest):
+ (WebCore::isResourceSuitableForDirectReuse):
+ (WebCore::destinationForType):
+ * loader/cache/CachedResourceLoader.h:
+
2019-04-26 Alex Christensen <achristensen@webkit.org>
Fix Windows build after r244695
ResourceRequest request(parsedUrl);
request.setHTTPMethod("POST"_s);
- FetchOptions options;
+ ResourceLoaderOptions options;
options.credentials = FetchOptions::Credentials::Include;
options.cache = FetchOptions::Cache::NoCache;
options.keepAlive = true;
+ options.sendLoadCallbacks = SendCallbackPolicy::SendCallbacks;
+
if (body) {
options.mode = FetchOptions::Mode::Cors;
String mimeType;
case CachedResource::Type::ApplicationManifest:
return InspectorPageAgent::ApplicationManifestResource;
#endif
+ case CachedResource::Type::Ping:
+ return InspectorPageAgent::PingResource;
case CachedResource::Type::MediaResource:
case CachedResource::Type::Icon:
case CachedResource::Type::RawResource:
case CachedResource::Type::XSLStyleSheet:
#endif
case CachedResource::Type::Beacon:
+ case CachedResource::Type::Ping:
case CachedResource::Type::LinkPrefetch:
#if ENABLE(APPLICATION_MANIFEST)
case CachedResource::Type::ApplicationManifest:
virtual void suspendPendingRequests() = 0;
virtual void resumePendingRequests() = 0;
+ virtual bool usePingLoad() const { return true; }
using PingLoadCompletionHandler = WTF::Function<void(const ResourceError&, const ResourceResponse&)>;
virtual void startPingLoad(Frame&, ResourceRequest&, const HTTPHeaderMap& originalRequestHeaders, const FetchOptions&, ContentSecurityPolicyImposition, PingLoadCompletionHandler&& = { }) = 0;
#include "config.h"
#include "PingLoader.h"
+#include "CachedResourceLoader.h"
+#include "CachedResourceRequest.h"
#include "ContentRuleListResults.h"
#include "ContentSecurityPolicy.h"
#include "Document.h"
request.setHTTPReferrer(referrer);
frame.loader().addExtraFieldsToSubresourceRequest(request);
- startPingLoad(frame, request, WTFMove(originalRequestHeader), ShouldFollowRedirects::Yes, ContentSecurityPolicyImposition::DoPolicyCheck);
+ startPingLoad(frame, request, WTFMove(originalRequestHeader), ShouldFollowRedirects::Yes, ContentSecurityPolicyImposition::DoPolicyCheck, ReferrerPolicy::EmptyString);
}
// http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#hyperlink-auditing
}
}
- startPingLoad(frame, request, WTFMove(originalRequestHeader), ShouldFollowRedirects::Yes, ContentSecurityPolicyImposition::DoPolicyCheck);
+ startPingLoad(frame, request, WTFMove(originalRequestHeader), ShouldFollowRedirects::Yes, ContentSecurityPolicyImposition::DoPolicyCheck, request.httpReferrer().isEmpty() ? ReferrerPolicy::NoReferrer : ReferrerPolicy::UnsafeUrl);
}
void PingLoader::sendViolationReport(Frame& frame, const URL& reportURL, Ref<FormData>&& report, ViolationReportType reportType)
if (!referrer.isEmpty())
request.setHTTPReferrer(referrer);
- startPingLoad(frame, request, WTFMove(originalRequestHeader), ShouldFollowRedirects::No, ContentSecurityPolicyImposition::SkipPolicyCheck);
+ startPingLoad(frame, request, WTFMove(originalRequestHeader), ShouldFollowRedirects::No, ContentSecurityPolicyImposition::SkipPolicyCheck, ReferrerPolicy::EmptyString);
}
-void PingLoader::startPingLoad(Frame& frame, ResourceRequest& request, HTTPHeaderMap&& originalRequestHeaders, ShouldFollowRedirects shouldFollowRedirects, ContentSecurityPolicyImposition policyCheck)
+void PingLoader::startPingLoad(Frame& frame, ResourceRequest& request, HTTPHeaderMap&& originalRequestHeaders, ShouldFollowRedirects shouldFollowRedirects, ContentSecurityPolicyImposition policyCheck, ReferrerPolicy referrerPolicy)
{
unsigned long identifier = frame.page()->progress().createUniqueIdentifier();
// FIXME: Why activeDocumentLoader? I would have expected documentLoader().
// with the provisional DocumentLoader if there is a provisional
// DocumentLoader.
bool shouldUseCredentialStorage = frame.loader().client().shouldUseCredentialStorage(frame.loader().activeDocumentLoader(), identifier);
- FetchOptions options;
+ ResourceLoaderOptions options;
options.credentials = shouldUseCredentialStorage ? FetchOptions::Credentials::Include : FetchOptions::Credentials::Omit;
options.redirect = shouldFollowRedirects == ShouldFollowRedirects::Yes ? FetchOptions::Redirect::Follow : FetchOptions::Redirect::Error;
+ options.keepAlive = true;
+ options.contentSecurityPolicyImposition = policyCheck;
+ options.referrerPolicy = referrerPolicy;
+ options.sendLoadCallbacks = SendCallbackPolicy::SendCallbacks;
+ options.cache = FetchOptions::Cache::NoCache;
+
+ // FIXME: Deprecate the ping load code path.
+ if (platformStrategies()->loaderStrategy()->usePingLoad()) {
+ InspectorInstrumentation::willSendRequestOfType(&frame, identifier, frame.loader().activeDocumentLoader(), request, InspectorInstrumentation::LoadType::Ping);
+
+ platformStrategies()->loaderStrategy()->startPingLoad(frame, request, WTFMove(originalRequestHeaders), options, policyCheck, [protectedFrame = makeRef(frame), identifier] (const ResourceError& error, const ResourceResponse& response) {
+ if (!response.isNull())
+ InspectorInstrumentation::didReceiveResourceResponse(protectedFrame, identifier, protectedFrame->loader().activeDocumentLoader(), response, nullptr);
+ if (!error.isNull()) {
+ InspectorInstrumentation::didFailLoading(protectedFrame.ptr(), protectedFrame->loader().activeDocumentLoader(), identifier, error);
+ return;
+ }
+ InspectorInstrumentation::didFinishLoading(protectedFrame.ptr(), protectedFrame->loader().activeDocumentLoader(), identifier, { }, nullptr);
+ });
+ return;
+ }
- // FIXME: Move ping loads to normal subresource loading to get normal inspector request instrumentation hooks.
- InspectorInstrumentation::willSendRequestOfType(&frame, identifier, frame.loader().activeDocumentLoader(), request, InspectorInstrumentation::LoadType::Ping);
-
- platformStrategies()->loaderStrategy()->startPingLoad(frame, request, WTFMove(originalRequestHeaders), options, policyCheck, [protectedFrame = makeRef(frame), identifier] (const ResourceError& error, const ResourceResponse& response) {
- if (!response.isNull())
- InspectorInstrumentation::didReceiveResourceResponse(protectedFrame, identifier, protectedFrame->loader().activeDocumentLoader(), response, nullptr);
- if (error.isNull()) {
- NetworkLoadMetrics emptyMetrics;
- InspectorInstrumentation::didFinishLoading(protectedFrame.ptr(), protectedFrame->loader().activeDocumentLoader(), identifier, emptyMetrics, nullptr);
- } else
- InspectorInstrumentation::didFailLoading(protectedFrame.ptr(), protectedFrame->loader().activeDocumentLoader(), identifier, error);
- });
+ CachedResourceRequest cachedResourceRequest { ResourceRequest { request }, options };
+ frame.document()->cachedResourceLoader().requestPingResource(WTFMove(cachedResourceRequest));
}
}
#pragma once
+#include "ReferrerPolicy.h"
#include <wtf/Forward.h>
#include <wtf/Ref.h>
private:
enum class ShouldFollowRedirects { No, Yes };
- static void startPingLoad(Frame&, ResourceRequest&, HTTPHeaderMap&& originalRequestHeaders, ShouldFollowRedirects, ContentSecurityPolicyImposition);
+ static void startPingLoad(Frame&, ResourceRequest&, HTTPHeaderMap&& originalRequestHeaders, ShouldFollowRedirects, ContentSecurityPolicyImposition, ReferrerPolicy);
};
} // namespace WebCore
return ResourceType::Media;
case CachedResource::Type::Beacon:
+ case CachedResource::Type::Ping:
case CachedResource::Type::Icon:
case CachedResource::Type::RawResource:
return ResourceType::Raw;
resourceType = DiagnosticLoggingKeys::fontKey();
break;
case CachedResource::Type::Beacon:
- ASSERT_NOT_REACHED();
- break;
+ case CachedResource::Type::Ping:
case CachedResource::Type::MediaResource:
case CachedResource::Type::Icon:
case CachedResource::Type::RawResource:
ASSERT(!reachedTerminalState());
LOG(ResourceLoading, "Failed to load '%s'.\n", m_resource->url().string().latin1().data());
- if (m_frame->document() && error.isAccessControl())
+ if (m_frame->document() && error.isAccessControl() && m_resource->type() != CachedResource::Type::Ping)
m_frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, error.localizedDescription());
-
Ref<SubresourceLoader> protectedThis(*this);
CachedResourceHandle<CachedResource> protectResource(m_resource);
m_state = Finishing;
case Type::SVGDocumentResource:
return ResourceLoadPriority::Low;
case Type::Beacon:
+ case Type::Ping:
return ResourceLoadPriority::VeryLow;
case Type::LinkPrefetch:
return ResourceLoadPriority::VeryLow;
m_fragmentIdentifierForRequest = String();
}
- if (m_options.keepAlive) {
- if (!cachedResourceLoader.keepaliveRequestTracker().tryRegisterRequest(*this)) {
- setResourceError({ errorDomainWebKitInternal, 0, request.url(), "Reached maximum amount of queued data of 64Kb for keepalive requests"_s, ResourceError::Type::AccessControl });
- failBeforeStarting();
- return;
- }
- // FIXME: We should not special-case Beacon here.
- if (shouldUsePingLoad(type())) {
- ASSERT(m_originalRequest);
- CachedResourceHandle<CachedResource> protectedThis(this);
-
- // FIXME: Move beacon loads to normal subresource loading to get normal inspector request instrumentation hooks.
- unsigned long identifier = frame.page()->progress().createUniqueIdentifier();
- InspectorInstrumentation::willSendRequestOfType(&frame, identifier, frameLoader.activeDocumentLoader(), request, InspectorInstrumentation::LoadType::Beacon);
-
- platformStrategies()->loaderStrategy()->startPingLoad(frame, request, m_originalRequest->httpHeaderFields(), m_options, m_options.contentSecurityPolicyImposition, [this, protectedThis = WTFMove(protectedThis), protectedFrame = makeRef(frame), identifier] (const ResourceError& error, const ResourceResponse& response) {
- if (!response.isNull())
- InspectorInstrumentation::didReceiveResourceResponse(protectedFrame, identifier, protectedFrame->loader().activeDocumentLoader(), response, nullptr);
- if (error.isNull()) {
- finishLoading(nullptr);
- NetworkLoadMetrics emptyMetrics;
- InspectorInstrumentation::didFinishLoading(protectedFrame.ptr(), protectedFrame->loader().activeDocumentLoader(), identifier, emptyMetrics, nullptr);
- } else {
- setResourceError(error);
- this->error(LoadError);
- InspectorInstrumentation::didFailLoading(protectedFrame.ptr(), protectedFrame->loader().activeDocumentLoader(), identifier, error);
- }
- });
- return;
- }
+ if (m_options.keepAlive && type() != Type::Ping && !cachedResourceLoader.keepaliveRequestTracker().tryRegisterRequest(*this)) {
+ setResourceError({ errorDomainWebKitInternal, 0, request.url(), "Reached maximum amount of queued data of 64Kb for keepalive requests"_s, ResourceError::Type::AccessControl });
+ failBeforeStarting();
+ return;
+ }
+
+ // FIXME: Deprecate that code path.
+ if (m_options.keepAlive && shouldUsePingLoad(type()) && platformStrategies()->loaderStrategy()->usePingLoad()) {
+ ASSERT(m_originalRequest);
+ CachedResourceHandle<CachedResource> protectedThis(this);
+
+ unsigned long identifier = frame.page()->progress().createUniqueIdentifier();
+ InspectorInstrumentation::willSendRequestOfType(&frame, identifier, frameLoader.activeDocumentLoader(), request, InspectorInstrumentation::LoadType::Beacon);
+
+ platformStrategies()->loaderStrategy()->startPingLoad(frame, request, m_originalRequest->httpHeaderFields(), m_options, m_options.contentSecurityPolicyImposition, [this, protectedThis = WTFMove(protectedThis), protectedFrame = makeRef(frame), identifier] (const ResourceError& error, const ResourceResponse& response) {
+ if (!response.isNull())
+ InspectorInstrumentation::didReceiveResourceResponse(protectedFrame, identifier, protectedFrame->loader().activeDocumentLoader(), response, nullptr);
+ if (!error.isNull()) {
+ setResourceError(error);
+ this->error(LoadError);
+ InspectorInstrumentation::didFailLoading(protectedFrame.ptr(), protectedFrame->loader().activeDocumentLoader(), identifier, error);
+ return;
+ }
+ finishLoading(nullptr);
+ NetworkLoadMetrics emptyMetrics;
+ InspectorInstrumentation::didFinishLoading(protectedFrame.ptr(), protectedFrame->loader().activeDocumentLoader(), identifier, emptyMetrics, nullptr);
+ });
+ return;
}
platformStrategies()->loaderStrategy()->loadResource(frame, *this, WTFMove(request), m_options, [this, protectedThis = CachedResourceHandle<CachedResource>(this), frame = makeRef(frame), loggingAllowed = cachedResourceLoader.isAlwaysOnLoggingAllowed()] (RefPtr<SubresourceLoader>&& loader) {
if (!isLoading() && !stillNeedsLoad())
return;
- setStatus(LoadError);
+ auto* documentLoader = (m_loader && m_loader->frame()) ? m_loader->frame()->loader().activeDocumentLoader() : nullptr;
+ if (m_options.keepAlive && (!documentLoader || documentLoader->isStopping()))
+ m_error = { };
+ else
+ setStatus(LoadError);
+
setLoading(false);
checkNotify();
}
RawResource,
Icon,
Beacon,
+ Ping,
SVGDocumentResource
#if ENABLE(XSLT)
, XSLStyleSheet
String mimeType() const { return m_response.mimeType(); }
long long expectedContentLength() const { return m_response.expectedContentLength(); }
- static bool shouldUsePingLoad(Type type) { return type == Type::Beacon; }
+ static bool shouldUsePingLoad(Type type) { return type == Type::Beacon || type == Type::Ping; }
ResourceLoadPriority loadPriority() const { return m_loadPriority; }
void setLoadPriority(const Optional<ResourceLoadPriority>&);
bool isImage() const { return type() == Type::ImageResource; }
// FIXME: CachedRawResource could be a main resource, an audio/video resource, or a raw XHR/icon resource.
- bool isMainOrMediaOrIconOrRawResource() const { return type() == Type::MainResource || type() == Type::MediaResource || type() == Type::Icon || type() == Type::RawResource || type() == Type::Beacon; }
+ bool isMainOrMediaOrIconOrRawResource() const { return type() == Type::MainResource || type() == Type::MediaResource || type() == Type::Icon || type() == Type::RawResource || type() == Type::Beacon || type() == Type::Ping; }
// Whether this request should impact request counting and delay window.onload.
bool ignoreForRequestCount() const
return m_ignoreForRequestCount
|| type() == Type::MainResource
|| type() == Type::LinkPrefetch
+ || type() == Type::Beacon
+ || type() == Type::Ping
|| type() == Type::Icon
|| type() == Type::RawResource;
}
case CachedResource::Type::FontResource:
return new CachedFont(WTFMove(request), sessionID, cookieJar);
case CachedResource::Type::Beacon:
+ case CachedResource::Type::Ping:
case CachedResource::Type::MediaResource:
case CachedResource::Type::RawResource:
case CachedResource::Type::Icon:
return castCachedResourceTo<CachedRawResource>(requestResource(CachedResource::Type::Beacon, WTFMove(request)));
}
+ResourceErrorOr<CachedResourceHandle<CachedRawResource>> CachedResourceLoader::requestPingResource(CachedResourceRequest&& request)
+{
+ ASSERT(request.options().destination == FetchOptions::Destination::EmptyString);
+ return castCachedResourceTo<CachedRawResource>(requestResource(CachedResource::Type::Ping, WTFMove(request)));
+}
+
ResourceErrorOr<CachedResourceHandle<CachedRawResource>> CachedResourceLoader::requestMainResource(CachedResourceRequest&& request)
{
return castCachedResourceTo<CachedRawResource>(requestResource(CachedResource::Type::MainResource, WTFMove(request)));
#endif
case CachedResource::Type::Beacon:
+ case CachedResource::Type::Ping:
case CachedResource::Type::RawResource:
case CachedResource::Type::Icon:
case CachedResource::Type::SVGDocumentResource:
}
case CachedResource::Type::MainResource:
case CachedResource::Type::Beacon:
+ case CachedResource::Type::Ping:
case CachedResource::Type::LinkPrefetch:
// Prefetch cannot affect the current document.
#if ENABLE(APPLICATION_MANIFEST)
return false;
break;
case CachedResource::Type::Beacon:
+ case CachedResource::Type::Ping:
case CachedResource::Type::RawResource:
return true;
#if ENABLE(APPLICATION_MANIFEST)
return false;
}
- if (options.mode == FetchOptions::Mode::NoCors && options.redirect != FetchOptions::Redirect::Follow) {
+ if (options.mode == FetchOptions::Mode::NoCors && options.redirect != FetchOptions::Redirect::Follow && type != CachedResource::Type::Ping) {
ASSERT(type != CachedResource::Type::MainResource);
frame()->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "No-Cors mode requires follow redirect mode"_s);
return false;
if (resource.type() == CachedResource::Type::RawResource || resource.type() == CachedResource::Type::MediaResource)
return false;
- if (resource.type() == CachedResource::Type::Beacon)
+ if (resource.type() == CachedResource::Type::Beacon || resource.type() == CachedResource::Type::Ping)
return false;
return true;
return FetchOptions::Destination::Manifest;
#endif
case CachedResource::Type::Beacon:
+ case CachedResource::Type::Ping:
case CachedResource::Type::LinkPrefetch:
case CachedResource::Type::RawResource:
case CachedResource::Type::MediaResource:
ResourceErrorOr<CachedResourceHandle<CachedRawResource>> requestMedia(CachedResourceRequest&&);
ResourceErrorOr<CachedResourceHandle<CachedRawResource>> requestIcon(CachedResourceRequest&&);
ResourceErrorOr<CachedResourceHandle<CachedRawResource>> requestBeaconResource(CachedResourceRequest&&);
+ ResourceErrorOr<CachedResourceHandle<CachedRawResource>> requestPingResource(CachedResourceRequest&&);
ResourceErrorOr<CachedResourceHandle<CachedRawResource>> requestMainResource(CachedResourceRequest&&);
ResourceErrorOr<CachedResourceHandle<CachedSVGDocument>> requestSVGDocument(CachedResourceRequest&&);
#if ENABLE(XSLT)
+2019-04-26 Youenn Fablet <youenn@apple.com>
+
+ Use normal loading path for ping loads
+ https://bugs.webkit.org/show_bug.cgi?id=196807
+
+ Reviewed by Alex Christensen.
+
+ In case a NetworkResourceLoader has the keepAlive option we do the following:
+ - Always use NetworkLoadChecker as we might need it to do checks after the Web context is gone.
+ - In case of aborting a KeepAlive loader, remove it from NetworkConnectionToWebProcess map
+ and add it to a kept-alive NetworkSession load set. The loader is only kept alive if it
+ has not yet received a response. Mark the loader as kept-alive.
+ - In case loader is kept-alive, cancel the load as soon as a response is gathered.
+
+ * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+ (WebKit::NetworkConnectionToWebProcess::transferKeptAliveLoad):
+ * NetworkProcess/NetworkConnectionToWebProcess.h:
+ * NetworkProcess/NetworkProcess.cpp:
+ (WebKit::NetworkProcess::addKeptAliveLoad):
+ (WebKit::NetworkProcess::removeKeptAliveLoad):
+ * NetworkProcess/NetworkProcess.h:
+ * NetworkProcess/NetworkResourceLoadMap.cpp:
+ (WebKit::NetworkResourceLoadMap::remove):
+ (WebKit::NetworkResourceLoadMap::take):
+ * NetworkProcess/NetworkResourceLoadMap.h:
+ * NetworkProcess/NetworkResourceLoader.cpp:
+ (WebKit::m_shouldCaptureExtraNetworkLoadMetrics):
+ (WebKit::NetworkResourceLoader::cleanup):
+ (WebKit::NetworkResourceLoader::abort):
+ (WebKit::NetworkResourceLoader::didReceiveResponse):
+ (WebKit::NetworkResourceLoader::continueWillSendRedirectedRequest):
+ * NetworkProcess/NetworkResourceLoader.h:
+ * WebProcess/Network/WebLoaderStrategy.cpp:
+ (WebKit::maximumBufferingTime):
+ (WebKit::WebLoaderStrategy::usePingLoad const):
+ * WebProcess/Network/WebLoaderStrategy.h:
+
2019-04-26 Alex Christensen <achristensen@webkit.org>
Fix internal High Sierra build after r244653
{
RELEASE_ASSERT(loader.identifier());
RELEASE_ASSERT(RunLoop::isMain());
- ASSERT(m_networkResourceLoaders.get(loader.identifier()) == &loader);
+ if (loader.isKeptAlive()) {
+ networkProcess().removeKeptAliveLoad(loader);
+ return;
+ }
+
+ ASSERT(m_networkResourceLoaders.get(loader.identifier()) == &loader);
m_networkResourceLoaders.remove(loader.identifier());
}
+void NetworkConnectionToWebProcess::transferKeptAliveLoad(NetworkResourceLoader& loader)
+{
+ RELEASE_ASSERT(RunLoop::isMain());
+ ASSERT(loader.isKeptAlive());
+ ASSERT(m_networkResourceLoaders.get(loader.identifier()) == &loader);
+ if (auto takenLoader = m_networkResourceLoaders.take(loader.identifier()))
+ m_networkProcess->addKeptAliveLoad(takenLoader.releaseNonNull());
+}
+
void NetworkConnectionToWebProcess::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
{
if (decoder.messageReceiverName() == Messages::NetworkConnectionToWebProcess::messageReceiverName()) {
NetworkProcess& networkProcess() { return m_networkProcess.get(); }
void didCleanupResourceLoader(NetworkResourceLoader&);
+ void transferKeptAliveLoad(NetworkResourceLoader&);
void setOnLineState(bool);
bool captureExtraNetworkLoadMetricsEnabled() const { return m_captureExtraNetworkLoadMetricsEnabled; }
completionHandler();
}
+void NetworkProcess::addKeptAliveLoad(Ref<NetworkResourceLoader>&& loader)
+{
+ if (auto session = m_networkSessions.get(loader->sessionID()))
+ session->addKeptAliveLoad(WTFMove(loader));
+}
+
+void NetworkProcess::removeKeptAliveLoad(NetworkResourceLoader& loader)
+{
+ if (auto session = m_networkSessions.get(loader.sessionID()))
+ session->removeKeptAliveLoad(loader);
+}
+
} // namespace WebKit
class NetworkConnectionToWebProcess;
class NetworkProcessSupplement;
class NetworkProximityManager;
+class NetworkResourceLoader;
class WebSWServerConnection;
class WebSWServerToContextConnection;
enum class ShouldGrandfatherStatistics : bool;
WebCore::StorageQuotaManager& storageQuotaManager(PAL::SessionID, const WebCore::ClientOrigin&);
+ void addKeptAliveLoad(Ref<NetworkResourceLoader>&&);
+ void removeKeptAliveLoad(NetworkResourceLoader&);
+
private:
void platformInitializeNetworkProcess(const NetworkProcessCreationParameters&);
std::unique_ptr<WebCore::NetworkStorageSession> platformCreateDefaultStorageSession() const;
bool NetworkResourceLoadMap::remove(ResourceLoadIdentifier identifier)
{
+ return !!take(identifier);
+}
+
+RefPtr<NetworkResourceLoader> NetworkResourceLoadMap::take(ResourceLoadIdentifier identifier)
+{
auto loader = m_loaders.take(identifier);
if (!loader)
- return false;
+ return nullptr;
if ((*loader)->originalRequest().hasUpload()) {
m_loadersWithUploads.remove(loader->ptr());
m_connectionToWebProcess.clearConnectionHasUploads();
}
- return true;
+ return WTFMove(*loader);
}
NetworkResourceLoader* NetworkResourceLoadMap::get(ResourceLoadIdentifier identifier) const
MapType::AddResult add(ResourceLoadIdentifier, Ref<NetworkResourceLoader>&&);
NetworkResourceLoader* get(ResourceLoadIdentifier) const;
bool remove(ResourceLoadIdentifier);
+ RefPtr<NetworkResourceLoader> take(ResourceLoadIdentifier);
private:
NetworkConnectionToWebProcess& m_connectionToWebProcess;
// Once bug 116233 is resolved, this ASSERT can just be "m_webPageID && m_webFrameID"
ASSERT((m_parameters.webPageID && m_parameters.webFrameID) || m_parameters.clientCredentialPolicy == ClientCredentialPolicy::CannotAskClientForCredentials);
- if (synchronousReply || parameters.shouldRestrictHTTPResponseAccess) {
+ if (synchronousReply || parameters.shouldRestrictHTTPResponseAccess || parameters.options.keepAlive) {
NetworkLoadChecker::LoadType requestLoadType = isMainFrameLoad() ? NetworkLoadChecker::LoadType::MainFrame : NetworkLoadChecker::LoadType::Other;
m_networkLoadChecker = std::make_unique<NetworkLoadChecker>(connection.networkProcess(), FetchOptions { m_parameters.options }, m_parameters.sessionID, m_parameters.webPageID, m_parameters.webFrameID, HTTPHeaderMap { m_parameters.originalRequestHeaders }, URL { m_parameters.request.url() }, m_parameters.sourceOrigin.copyRef(), m_parameters.preflightPolicy, originalRequest().httpReferrer(), m_parameters.isHTTPSUpgradeEnabled, shouldCaptureExtraNetworkLoadMetrics(), requestLoadType);
if (m_parameters.cspResponseHeaders)
RELEASE_LOG_IF_ALLOWED("abort: Canceling resource load (pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ")",
m_parameters.webPageID, m_parameters.webFrameID, m_parameters.identifier);
+ if (m_parameters.options.keepAlive && m_response.isNull() && !m_isKeptAlive) {
+ m_isKeptAlive = true;
+ m_connection->transferKeptAliveLoad(*this);
+ return;
+ }
+
if (m_networkLoad) {
if (canUseCache(m_networkLoad->currentRequest())) {
// We might already have used data from this incomplete load. Ensure older versions don't remain in the cache after cancel.
// a main resource because the embedding client must decide whether to allow the load.
bool willWaitForContinueDidReceiveResponse = isMainResource();
send(Messages::WebResourceLoader::DidReceiveResponse { response, willWaitForContinueDidReceiveResponse });
- if (willWaitForContinueDidReceiveResponse)
+
+ if (willWaitForContinueDidReceiveResponse) {
m_responseCompletionHandler = WTFMove(completionHandler);
- else
- completionHandler(PolicyAction::Use);
+ return;
+ }
+
+ if (m_isKeptAlive) {
+ m_responseCompletionHandler = WTFMove(completionHandler);
+ RunLoop::main().dispatch([protectedThis = makeRef(*this)] {
+ protectedThis->didFinishLoading(NetworkLoadMetrics { });
+ });
+ return;
+ }
+
+ completionHandler(PolicyAction::Use);
}
void NetworkResourceLoader::didReceiveBuffer(Ref<SharedBuffer>&& buffer, int reportedEncodedDataLength)
{
ASSERT(!isSynchronous());
+ if (m_isKeptAlive) {
+ continueWillSendRequest(WTFMove(request), false);
+ return;
+ }
+
if (adClickConversion)
handleAdClickAttributionConversion(WTFMove(*adClickConversion), request.url(), redirectRequest);
send(Messages::WebResourceLoader::WillSendRequest(redirectRequest, sanitizeResponseIfPossible(WTFMove(redirectResponse), ResourceResponse::SanitizationType::Redirection)));
void disableExtraNetworkLoadMetricsCapture() { m_shouldCaptureExtraNetworkLoadMetrics = false; }
+ bool isKeptAlive() const { return m_isKeptAlive; }
+
private:
NetworkResourceLoader(NetworkResourceLoadParameters&&, NetworkConnectionToWebProcess&, Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply&&);
bool m_shouldRestartLoad { false };
ResponseCompletionHandler m_responseCompletionHandler;
bool m_shouldCaptureExtraNetworkLoadMetrics { false };
+ bool m_isKeptAlive { false };
Optional<NetworkActivityTracker> m_networkActivityTracker;
};
#include "NetworkProcess.h"
#include "NetworkProcessProxyMessages.h"
#include "NetworkResourceLoadParameters.h"
+#include "NetworkResourceLoader.h"
#include "PingLoad.h"
#include "WebPageProxy.h"
#include "WebPageProxyMessages.h"
m_adClickAttribution->markAllUnconvertedAsExpiredForTesting();
}
+void NetworkSession::addKeptAliveLoad(Ref<NetworkResourceLoader>&& loader)
+{
+ ASSERT(m_sessionID == loader->sessionID());
+ ASSERT(!m_keptAliveLoads.contains(loader));
+ m_keptAliveLoads.add(WTFMove(loader));
+}
+
+void NetworkSession::removeKeptAliveLoad(NetworkResourceLoader& loader)
+{
+ ASSERT(m_sessionID == loader.sessionID());
+ ASSERT(m_keptAliveLoads.contains(loader));
+ m_keptAliveLoads.remove(loader);
+}
+
} // namespace WebKit
class AdClickAttributionManager;
class NetworkDataTask;
class NetworkProcess;
+class NetworkResourceLoader;
class WebResourceLoadStatisticsStore;
struct NetworkSessionCreationParameters;
void setAdClickAttributionConversionURLForTesting(URL&&);
void markAdClickAttributionsAsExpiredForTesting();
+ void addKeptAliveLoad(Ref<NetworkResourceLoader>&&);
+ void removeKeptAliveLoad(NetworkResourceLoader&);
+
protected:
NetworkSession(NetworkProcess&, PAL::SessionID);
WebCore::RegistrableDomain m_resourceLoadStatisticsManualPrevalentResource;
#endif
UniqueRef<AdClickAttributionManager> m_adClickAttribution;
+
+ HashSet<Ref<NetworkResourceLoader>> m_keptAliveLoads;
};
} // namespace WebKit
switch (resource->type()) {
case CachedResource::Type::Beacon:
+ case CachedResource::Type::Ping:
case CachedResource::Type::CSSStyleSheet:
case CachedResource::Type::Script:
#if ENABLE(SVG_FONTS)
auto* document = resourceLoader.frame() ? resourceLoader.frame()->document() : nullptr;
if (resourceLoader.options().cspResponseHeaders)
loadParameters.cspResponseHeaders = resourceLoader.options().cspResponseHeaders;
- else if (document && !document->shouldBypassMainWorldContentSecurityPolicy()) {
+ else if (document && !document->shouldBypassMainWorldContentSecurityPolicy() && resourceLoader.options().contentSecurityPolicyImposition == ContentSecurityPolicyImposition::DoPolicyCheck) {
if (auto* contentSecurityPolicy = document->contentSecurityPolicy())
loadParameters.cspResponseHeaders = contentSecurityPolicy->responseHeaders();
}
return ++identifier;
}
+bool WebLoaderStrategy::usePingLoad() const
+{
+ return !RuntimeEnabledFeatures::sharedFeatures().fetchAPIKeepAliveEnabled();
+}
+
void WebLoaderStrategy::startPingLoad(Frame& frame, ResourceRequest& request, const HTTPHeaderMap& originalRequestHeaders, const FetchOptions& options, ContentSecurityPolicyImposition policyCheck, PingLoadCompletionHandler&& completionHandler)
{
auto* document = frame.document();
void suspendPendingRequests() final;
void resumePendingRequests() final;
+ bool usePingLoad() const final;
void startPingLoad(WebCore::Frame&, WebCore::ResourceRequest&, const WebCore::HTTPHeaderMap& originalRequestHeaders, const WebCore::FetchOptions&, WebCore::ContentSecurityPolicyImposition, PingLoadCompletionHandler&&) final;
void didFinishPingLoad(uint64_t pingLoadIdentifier, WebCore::ResourceError&&, WebCore::ResourceResponse&&);