https://bugs.webkit.org/show_bug.cgi?id=175443
<rdar://problem/
33729002>
Reviewed by Youenn Fablet.
Source/WebCore:
LoaderStrategy::startPingLoad() now takes a completion handler parameter, allowing CachedResource::load()
to know when a Beacon load is complete. This was needed in order for the fetch in-flight keepalive request
quota limit to work properly for beacon loads as well. We need to know when the beacon load completes in
order to know if the beacon is in-flight or not and only free up its allocated quota once it is no longer
in-flight.
No new tests, updated existing test.
* loader/LoaderStrategy.h:
* loader/PingLoader.cpp:
(WebCore::PingLoader::startPingLoad):
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource::load):
* platform/network/PingHandle.h:
Source/WebKit:
WebLoaderStrategy now generates an identifier for ping loads and keep
the completion handler in a local HashMap. Once the ping load is done,
the network process sends an IPC message back to the WebContent process
so that WebLoaderStrategy can look up the completion handler for the
ping load and call it.
* NetworkProcess/NetworkConnectionToWebProcess.cpp:
(WebKit::NetworkConnectionToWebProcess::loadPing):
(WebKit::NetworkConnectionToWebProcess::didFinishPingLoad):
* NetworkProcess/NetworkConnectionToWebProcess.h:
* NetworkProcess/PingLoad.cpp:
(WebKit::PingLoad::PingLoad):
(WebKit::PingLoad::~PingLoad):
* NetworkProcess/PingLoad.h:
* WebProcess/Network/NetworkProcessConnection.cpp:
(WebKit::NetworkProcessConnection::didFinishPingLoad):
* WebProcess/Network/NetworkProcessConnection.h:
* WebProcess/Network/NetworkProcessConnection.messages.in:
* WebProcess/Network/WebLoaderStrategy.cpp:
(WebKit::generatePingLoadIdentifier):
(WebKit::WebLoaderStrategy::startPingLoad):
(WebKit::WebLoaderStrategy::didFinishPingLoad):
* WebProcess/Network/WebLoaderStrategy.h:
Source/WebKitLegacy:
* WebCoreSupport/WebResourceLoadScheduler.cpp:
(WebResourceLoadScheduler::startPingLoad):
* WebCoreSupport/WebResourceLoadScheduler.h:
LayoutTests:
Extend layout test coverage and rebaseline test.
* http/wpt/beacon/beacon-quota-expected.txt:
* http/wpt/beacon/beacon-quota.html:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@220922
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2017-08-18 Chris Dumez <cdumez@apple.com>
+
+ [Beacon] Add support for quota limitation
+ https://bugs.webkit.org/show_bug.cgi?id=175443
+ <rdar://problem/33729002>
+
+ Reviewed by Youenn Fablet.
+
+ Extend layout test coverage and rebaseline test.
+
+ * http/wpt/beacon/beacon-quota-expected.txt:
+ * http/wpt/beacon/beacon-quota.html:
+
2017-08-18 Ryan Haddad <ryanhaddad@apple.com>
Unreviewed, land TestExpectations for rdar://problem/33850189.
-CONSOLE MESSAGE: line 14: Reached maximum amount of queued data of 64Kb for keepalive requests
+CONSOLE MESSAGE: line 44: Reached maximum amount of queued data of 64Kb for keepalive requests
+CONSOLE MESSAGE: line 52: Reached maximum amount of queued data of 64Kb for keepalive requests
PASS Beacon with a body above the Quota Limit should fail.
-FAIL Multiple Beacons Quota Limit assert_false: Second beacon should not be sent because we reached the quota expected false got true
+PASS Multiple Beacons Quota Limit
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
<script>
+ const RESOURCES_DIR = "/WebKit/beacon/resources/";
+
// We should expect 64KiB of rolling quota for any type of keep-alive request sent.
var expectedQuota = 65536;
+ function checkBeaconReceived(id)
+ {
+ return new Promise(function(resolve, reject) {
+ var checkUrl = RESOURCES_DIR + "beacon-preflight.py?cmd=get&id=" + id;
+ fetch(checkUrl).then(response => {
+ response.json().then(result => {
+ resolve(result['beacon'] == 1);
+ });
+ }, reject);
+ });
+ }
+
+ function waitForBeacon(id)
+ {
+ return new Promise(function(resolve, reject) {
+ checkBeaconReceived(id).then(wasReceived => {
+ if (wasReceived) {
+ resolve();
+ return;
+ }
+ setTimeout(function() {
+ waitForBeacon(id).then(resolve, reject);
+ }, 10);
+ });
+ });
+ }
+
function createPayload(payloadSize)
{
return new Blob(["*".repeat(payloadSize)]);
assert_false(navigator.sendBeacon("/", createPayload(expectedQuota + 1)));
}, "Beacon with a body above the Quota Limit should fail.");
- test(function() {
- assert_true(navigator.sendBeacon("/", createPayload(expectedQuota)), "Beacon with a body at the Quota Limit should succeed.");
- assert_false(navigator.sendBeacon("/", createPayload(1)), "Second beacon should not be sent because we reached the quota");
+ promise_test(function() {
+ var id = self.token();
+ var target = RESOURCES_DIR + "beacon-preflight.py?allowCors=1&cmd=put&id=" + id;
+
+ assert_true(navigator.sendBeacon(target, createPayload(expectedQuota)), "Beacon with a body at the Quota Limit should succeed.");
+ assert_false(navigator.sendBeacon(target, createPayload(1)), "Second beacon should not be sent because we reached the quota");
+ return waitForBeacon(id).then(function() {
+ assert_true(navigator.sendBeacon(target, createPayload(1)), "Allocated quota should be returned once the beacon is no longer in flight");
+ });
}, "Multiple Beacons Quota Limit");
</script>
+2017-08-18 Chris Dumez <cdumez@apple.com>
+
+ [Beacon] Add support for quota limitation
+ https://bugs.webkit.org/show_bug.cgi?id=175443
+ <rdar://problem/33729002>
+
+ Reviewed by Youenn Fablet.
+
+ LoaderStrategy::startPingLoad() now takes a completion handler parameter, allowing CachedResource::load()
+ to know when a Beacon load is complete. This was needed in order for the fetch in-flight keepalive request
+ quota limit to work properly for beacon loads as well. We need to know when the beacon load completes in
+ order to know if the beacon is in-flight or not and only free up its allocated quota once it is no longer
+ in-flight.
+
+ No new tests, updated existing test.
+
+ * loader/LoaderStrategy.h:
+ * loader/PingLoader.cpp:
+ (WebCore::PingLoader::startPingLoad):
+ * loader/cache/CachedResource.cpp:
+ (WebCore::CachedResource::load):
+ * platform/network/PingHandle.h:
+
2017-08-18 Youenn Fablet <youenn@apple.com>
[Cache API] Add a WK2 implementation of CacheStorageConnection
virtual void suspendPendingRequests() = 0;
virtual void resumePendingRequests() = 0;
- virtual void createPingHandle(NetworkingContext*, ResourceRequest&, const HTTPHeaderMap& originalRequestHeaders, Ref<SecurityOrigin>&& sourceOrigin, ContentSecurityPolicy*, const FetchOptions&) = 0;
+ virtual void startPingLoad(NetworkingContext*, ResourceRequest&, const HTTPHeaderMap& originalRequestHeaders, Ref<SecurityOrigin>&& sourceOrigin, ContentSecurityPolicy*, const FetchOptions&, WTF::Function<void()>&& completionHandler = { }) = 0;
virtual void storeDerivedDataToCache(const SHA1::Digest& bodyKey, const String& type, const String& partition, WebCore::SharedBuffer&) = 0;
InspectorInstrumentation::continueAfterPingLoader(frame, identifier, frame.loader().activeDocumentLoader(), request, ResourceResponse());
auto* contentSecurityPolicy = document.shouldBypassMainWorldContentSecurityPolicy() ? nullptr : document.contentSecurityPolicy();
- platformStrategies()->loaderStrategy()->createPingHandle(frame.loader().networkingContext(), request, WTFMove(originalRequestHeaders), document.securityOrigin(), contentSecurityPolicy, options);
+ platformStrategies()->loaderStrategy()->startPingLoad(frame.loader().networkingContext(), request, WTFMove(originalRequestHeaders), document.securityOrigin(), contentSecurityPolicy, options);
}
}
}
// FIXME: We should not special-case Beacon here.
if (shouldUsePingLoad(type())) {
- ASSERT(m_origin);
+ ASSERT(m_origin);
// Beacon is not exposed to workers so it is safe to rely on the document here.
auto* document = cachedResourceLoader.document();
auto* contentSecurityPolicy = document && !document->shouldBypassMainWorldContentSecurityPolicy() ? document->contentSecurityPolicy() : nullptr;
ASSERT(m_originalRequestHeaders);
- platformStrategies()->loaderStrategy()->createPingHandle(frame.loader().networkingContext(), request, *m_originalRequestHeaders, *m_origin, contentSecurityPolicy, m_options);
- // FIXME: We currently do not get notified when ping loads finish so we treat them as finishing right away.
- finishLoading(nullptr);
+ CachedResourceHandle<CachedResource> protectedThis(this);
+ platformStrategies()->loaderStrategy()->startPingLoad(frame.loader().networkingContext(), request, *m_originalRequestHeaders, *m_origin, contentSecurityPolicy, m_options, [this, protectedThis = WTFMove(protectedThis)] {
+ finishLoading(nullptr);
+ });
return;
}
}
No,
};
- PingHandle(NetworkingContext* networkingContext, const ResourceRequest& request, bool shouldUseCredentialStorage, UsesAsyncCallbacks useAsyncCallbacks, bool shouldFollowRedirects)
+ PingHandle(NetworkingContext* networkingContext, const ResourceRequest& request, bool shouldUseCredentialStorage, UsesAsyncCallbacks useAsyncCallbacks, bool shouldFollowRedirects, WTF::Function<void()>&& completionHandler)
: m_timeoutTimer(*this, &PingHandle::timeoutTimerFired)
, m_shouldUseCredentialStorage(shouldUseCredentialStorage)
, m_shouldFollowRedirects(shouldFollowRedirects)
, m_usesAsyncCallbacks(useAsyncCallbacks)
+ , m_completionHandler(WTFMove(completionHandler))
{
m_handle = ResourceHandle::create(networkingContext, request, this, false, false);
virtual ~PingHandle()
{
+ if (m_completionHandler)
+ m_completionHandler();
+
if (m_handle) {
ASSERT(m_handle->client() == this);
m_handle->clearClient();
bool m_shouldUseCredentialStorage;
bool m_shouldFollowRedirects;
UsesAsyncCallbacks m_usesAsyncCallbacks;
+ WTF::Function<void()> m_completionHandler;
};
} // namespace WebCore
+2017-08-18 Chris Dumez <cdumez@apple.com>
+
+ [Beacon] Add support for quota limitation
+ https://bugs.webkit.org/show_bug.cgi?id=175443
+ <rdar://problem/33729002>
+
+ Reviewed by Youenn Fablet.
+
+ WebLoaderStrategy now generates an identifier for ping loads and keep
+ the completion handler in a local HashMap. Once the ping load is done,
+ the network process sends an IPC message back to the WebContent process
+ so that WebLoaderStrategy can look up the completion handler for the
+ ping load and call it.
+
+ * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+ (WebKit::NetworkConnectionToWebProcess::loadPing):
+ (WebKit::NetworkConnectionToWebProcess::didFinishPingLoad):
+ * NetworkProcess/NetworkConnectionToWebProcess.h:
+ * NetworkProcess/PingLoad.cpp:
+ (WebKit::PingLoad::PingLoad):
+ (WebKit::PingLoad::~PingLoad):
+ * NetworkProcess/PingLoad.h:
+ * WebProcess/Network/NetworkProcessConnection.cpp:
+ (WebKit::NetworkProcessConnection::didFinishPingLoad):
+ * WebProcess/Network/NetworkProcessConnection.h:
+ * WebProcess/Network/NetworkProcessConnection.messages.in:
+ * WebProcess/Network/WebLoaderStrategy.cpp:
+ (WebKit::generatePingLoadIdentifier):
+ (WebKit::WebLoaderStrategy::startPingLoad):
+ (WebKit::WebLoaderStrategy::didFinishPingLoad):
+ * WebProcess/Network/WebLoaderStrategy.h:
+
2017-08-18 Youenn Fablet <youenn@apple.com>
[Cache API] Add a WK2 implementation of CacheStorageConnection
{
#if USE(NETWORK_SESSION)
// PingLoad manages its own lifetime, deleting itself when its purpose has been fulfilled.
- new PingLoad(WTFMove(loadParameters), WTFMove(originalRequestHeaders));
+ new PingLoad(WTFMove(loadParameters), WTFMove(originalRequestHeaders), *this);
#else
UNUSED_PARAM(originalRequestHeaders);
RefPtr<NetworkingContext> context = RemoteNetworkingContext::create(loadParameters.sessionID, loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect);
// PingHandle manages its own lifetime, deleting itself when its purpose has been fulfilled.
- new PingHandle(context.get(), loadParameters.request, loadParameters.allowStoredCredentials == AllowStoredCredentials, PingHandle::UsesAsyncCallbacks::Yes, loadParameters.shouldFollowRedirects);
+ new PingHandle(context.get(), loadParameters.request, loadParameters.allowStoredCredentials == AllowStoredCredentials, PingHandle::UsesAsyncCallbacks::Yes, loadParameters.shouldFollowRedirects, [this, protectedThis = makeRef(*this), identifier = loadParameters.identifier] {
+ didFinishPingLoad(identifier);
+ });
#endif
}
+void NetworkConnectionToWebProcess::didFinishPingLoad(uint64_t pingLoadIdentifier)
+{
+ if (!m_connection->isValid())
+ return;
+
+ m_connection->send(Messages::NetworkProcessConnection::DidFinishPingLoad(pingLoadIdentifier), 0);
+}
+
void NetworkConnectionToWebProcess::removeLoadIdentifier(ResourceLoadIdentifier identifier)
{
RefPtr<NetworkResourceLoader> loader = m_networkResourceLoaders.get(identifier);
IPC::Connection& connection() { return m_connection.get(); }
void didCleanupResourceLoader(NetworkResourceLoader&);
+ void didFinishPingLoad(uint64_t pingLoadIdentifier);
bool captureExtraNetworkLoadMetricsEnabled() const { return m_captureExtraNetworkLoadMetricsEnabled; }
#include "AuthenticationManager.h"
#include "Logging.h"
#include "NetworkCORSPreflightChecker.h"
+#include "NetworkConnectionToWebProcess.h"
#include "SessionTracker.h"
#include <WebCore/ContentSecurityPolicy.h>
#include <WebCore/CrossOriginAccessControl.h>
using namespace WebCore;
-PingLoad::PingLoad(NetworkResourceLoadParameters&& parameters, HTTPHeaderMap&& originalRequestHeaders)
+PingLoad::PingLoad(NetworkResourceLoadParameters&& parameters, HTTPHeaderMap&& originalRequestHeaders, Ref<NetworkConnectionToWebProcess>&& connection)
: m_parameters(WTFMove(parameters))
, m_originalRequestHeaders(WTFMove(originalRequestHeaders))
+ , m_connection(WTFMove(connection))
, m_timeoutTimer(*this, &PingLoad::timeoutTimerFired)
, m_isSameOriginRequest(securityOrigin().canRequest(m_parameters.request.url()))
{
PingLoad::~PingLoad()
{
+ m_connection->didFinishPingLoad(m_parameters.identifier);
+
if (m_redirectHandler)
m_redirectHandler({ });
namespace WebKit {
class NetworkCORSPreflightChecker;
+class NetworkConnectionToWebProcess;
class PingLoad final : private NetworkDataTaskClient {
public:
- PingLoad(NetworkResourceLoadParameters&&, WebCore::HTTPHeaderMap&& originalRequestHeaders);
+ PingLoad(NetworkResourceLoadParameters&&, WebCore::HTTPHeaderMap&& originalRequestHeaders, Ref<NetworkConnectionToWebProcess>&&);
private:
~PingLoad();
NetworkResourceLoadParameters m_parameters;
WebCore::HTTPHeaderMap m_originalRequestHeaders; // Needed for CORS checks.
+ Ref<NetworkConnectionToWebProcess> m_connection;
RefPtr<NetworkDataTask> m_task;
WebCore::Timer m_timeoutTimer;
std::unique_ptr<NetworkCORSPreflightChecker> m_corsPreflightChecker;
handler(filenames);
}
+void NetworkProcessConnection::didFinishPingLoad(uint64_t pingLoadIdentifier)
+{
+ WebProcess::singleton().webLoaderStrategy().didFinishPingLoad(pingLoadIdentifier);
+}
+
#if ENABLE(SHAREABLE_RESOURCE)
void NetworkProcessConnection::didCacheResource(const ResourceRequest& request, const ShareableResource::Handle& handle, PAL::SessionID sessionID)
{
void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override;
void didWriteBlobsToTemporaryFiles(uint64_t requestIdentifier, const Vector<String>& filenames);
+ void didFinishPingLoad(uint64_t pingLoadIdentifier);
#if ENABLE(SHAREABLE_RESOURCE)
// Message handlers.
#endif
DidWriteBlobsToTemporaryFiles(uint64_t requestIdentifier, Vector<String> filenames)
+ DidFinishPingLoad(uint64_t pingLoadIdentifier)
}
scheduleInternallyFailedLoad(*loader.value->resourceLoader());
m_webResourceLoaders.clear();
+
+ auto pingLoadCompletionHandlers = WTFMove(m_pingLoadCompletionHandlers);
+ for (auto& pingLoadCompletionHandler : pingLoadCompletionHandlers.values())
+ pingLoadCompletionHandler();
}
void WebLoaderStrategy::loadResourceSynchronously(NetworkingContext* context, unsigned long resourceLoadIdentifier, const ResourceRequest& request, StoredCredentials storedCredentials, ClientCredentialPolicy clientCredentialPolicy, ResourceError& error, ResourceResponse& response, Vector<char>& data)
}
}
-void WebLoaderStrategy::createPingHandle(NetworkingContext* networkingContext, ResourceRequest& request, const HTTPHeaderMap& originalRequestHeaders, Ref<SecurityOrigin>&& sourceOrigin, ContentSecurityPolicy* contentSecurityPolicy, const FetchOptions& options)
+static uint64_t generatePingLoadIdentifier()
+{
+ static uint64_t identifier = 0;
+ return ++identifier;
+}
+
+void WebLoaderStrategy::startPingLoad(NetworkingContext* networkingContext, ResourceRequest& request, const HTTPHeaderMap& originalRequestHeaders, Ref<SecurityOrigin>&& sourceOrigin, ContentSecurityPolicy* contentSecurityPolicy, const FetchOptions& options, WTF::Function<void()>&& completionHandler)
{
// It's possible that call to createPingHandle might be made during initial empty Document creation before a NetworkingContext exists.
// It is not clear that we should send ping loads during that process anyways.
- if (!networkingContext)
+ if (!networkingContext) {
+ if (completionHandler)
+ completionHandler();
return;
+ }
WebFrameNetworkingContext* webContext = static_cast<WebFrameNetworkingContext*>(networkingContext);
WebFrameLoaderClient* webFrameLoaderClient = webContext->webFrameLoaderClient();
WebPage* webPage = webFrame ? webFrame->page() : nullptr;
NetworkResourceLoadParameters loadParameters;
+ loadParameters.identifier = generatePingLoadIdentifier();
loadParameters.request = request;
loadParameters.sourceOrigin = WTFMove(sourceOrigin);
loadParameters.sessionID = webPage ? webPage->sessionID() : PAL::SessionID::defaultSessionID();
if (contentSecurityPolicy)
loadParameters.cspResponseHeaders = contentSecurityPolicy->responseHeaders();
+ if (completionHandler)
+ m_pingLoadCompletionHandlers.add(loadParameters.identifier, WTFMove(completionHandler));
+
WebProcess::singleton().networkConnection().connection().send(Messages::NetworkConnectionToWebProcess::LoadPing(WTFMove(loadParameters), originalRequestHeaders), 0);
}
+void WebLoaderStrategy::didFinishPingLoad(uint64_t pingLoadIdentifier)
+{
+ if (auto completionHandler = m_pingLoadCompletionHandlers.take(pingLoadIdentifier))
+ completionHandler();
+}
+
void WebLoaderStrategy::storeDerivedDataToCache(const SHA1::Digest& bodyHash, const String& type, const String& partition, WebCore::SharedBuffer& data)
{
NetworkCache::DataKey key { partition, type, bodyHash };
void suspendPendingRequests() final;
void resumePendingRequests() final;
- void createPingHandle(WebCore::NetworkingContext*, WebCore::ResourceRequest&, const WebCore::HTTPHeaderMap& originalRequestHeaders, Ref<WebCore::SecurityOrigin>&& sourceOrigin, WebCore::ContentSecurityPolicy*, const WebCore::FetchOptions&) final;
+ void startPingLoad(WebCore::NetworkingContext*, WebCore::ResourceRequest&, const WebCore::HTTPHeaderMap& originalRequestHeaders, Ref<WebCore::SecurityOrigin>&& sourceOrigin, WebCore::ContentSecurityPolicy*, const WebCore::FetchOptions&, WTF::Function<void()>&& completionHandler) final;
+ void didFinishPingLoad(uint64_t pingLoadIdentifier);
void storeDerivedDataToCache(const SHA1::Digest& bodyHash, const String& type, const String& partition, WebCore::SharedBuffer&) final;
HashMap<unsigned long, RefPtr<WebResourceLoader>> m_webResourceLoaders;
HashMap<unsigned long, WebURLSchemeTaskProxy*> m_urlSchemeTasks;
+ HashMap<unsigned long, WTF::Function<void()>> m_pingLoadCompletionHandlers;
};
} // namespace WebKit
+2017-08-18 Chris Dumez <cdumez@apple.com>
+
+ [Beacon] Add support for quota limitation
+ https://bugs.webkit.org/show_bug.cgi?id=175443
+ <rdar://problem/33729002>
+
+ Reviewed by Youenn Fablet.
+
+ * WebCoreSupport/WebResourceLoadScheduler.cpp:
+ (WebResourceLoadScheduler::startPingLoad):
+ * WebCoreSupport/WebResourceLoadScheduler.h:
+
2017-08-17 Chris Dumez <cdumez@apple.com>
Regression(r220817): We should only copy the original request headers for Ping loads
return m_requestsLoading.size() >= (webResourceLoadScheduler().isSerialLoadingEnabled() ? 1 : m_maxRequestsInFlight);
}
-void WebResourceLoadScheduler::createPingHandle(NetworkingContext* networkingContext, ResourceRequest& request, const HTTPHeaderMap&, Ref<SecurityOrigin>&&, WebCore::ContentSecurityPolicy*, const FetchOptions& options)
+void WebResourceLoadScheduler::startPingLoad(NetworkingContext* networkingContext, ResourceRequest& request, const HTTPHeaderMap&, Ref<SecurityOrigin>&&, WebCore::ContentSecurityPolicy*, const FetchOptions& options, WTF::Function<void()>&& completionHandler)
{
// PingHandle manages its own lifetime, deleting itself when its purpose has been fulfilled.
- new PingHandle(networkingContext, request, options.credentials != FetchOptions::Credentials::Omit, PingHandle::UsesAsyncCallbacks::No, options.redirect == FetchOptions::Redirect::Follow);
+ new PingHandle(networkingContext, request, options.credentials != FetchOptions::Credentials::Omit, PingHandle::UsesAsyncCallbacks::No, options.redirect == FetchOptions::Redirect::Follow, WTFMove(completionHandler));
}
WebResourceLoadScheduler& webResourceLoadScheduler();
-class WebResourceLoadScheduler : public WebCore::LoaderStrategy {
+class WebResourceLoadScheduler final : public WebCore::LoaderStrategy {
WTF_MAKE_NONCOPYABLE(WebResourceLoadScheduler); WTF_MAKE_FAST_ALLOCATED;
public:
WebResourceLoadScheduler();
- RefPtr<WebCore::SubresourceLoader> loadResource(WebCore::Frame&, WebCore::CachedResource&, const WebCore::ResourceRequest&, const WebCore::ResourceLoaderOptions&) override;
- void loadResourceSynchronously(WebCore::NetworkingContext*, unsigned long, const WebCore::ResourceRequest&, WebCore::StoredCredentials, WebCore::ClientCredentialPolicy, WebCore::ResourceError&, WebCore::ResourceResponse&, Vector<char>&) override;
- void remove(WebCore::ResourceLoader*) override;
- void setDefersLoading(WebCore::ResourceLoader*, bool) override;
- void crossOriginRedirectReceived(WebCore::ResourceLoader*, const WebCore::URL& redirectURL) override;
+ RefPtr<WebCore::SubresourceLoader> loadResource(WebCore::Frame&, WebCore::CachedResource&, const WebCore::ResourceRequest&, const WebCore::ResourceLoaderOptions&) final;
+ void loadResourceSynchronously(WebCore::NetworkingContext*, unsigned long, const WebCore::ResourceRequest&, WebCore::StoredCredentials, WebCore::ClientCredentialPolicy, WebCore::ResourceError&, WebCore::ResourceResponse&, Vector<char>&) final;
+ void remove(WebCore::ResourceLoader*) final;
+ void setDefersLoading(WebCore::ResourceLoader*, bool) final;
+ void crossOriginRedirectReceived(WebCore::ResourceLoader*, const WebCore::URL& redirectURL) final;
- void servePendingRequests(WebCore::ResourceLoadPriority minimumPriority = WebCore::ResourceLoadPriority::VeryLow) override;
- void suspendPendingRequests() override;
- void resumePendingRequests() override;
+ void servePendingRequests(WebCore::ResourceLoadPriority minimumPriority = WebCore::ResourceLoadPriority::VeryLow) final;
+ void suspendPendingRequests() final;
+ void resumePendingRequests() final;
- void createPingHandle(WebCore::NetworkingContext*, WebCore::ResourceRequest&, const WebCore::HTTPHeaderMap&, Ref<WebCore::SecurityOrigin>&& sourceOrigin, WebCore::ContentSecurityPolicy*, const WebCore::FetchOptions&) override;
+ void startPingLoad(WebCore::NetworkingContext*, WebCore::ResourceRequest&, const WebCore::HTTPHeaderMap&, Ref<WebCore::SecurityOrigin>&& sourceOrigin, WebCore::ContentSecurityPolicy*, const WebCore::FetchOptions&, WTF::Function<void()>&& completionHandler) final;
- void storeDerivedDataToCache(const SHA1::Digest&, const String&, const String&, WebCore::SharedBuffer&) override { }
+ void storeDerivedDataToCache(const SHA1::Digest&, const String&, const String&, WebCore::SharedBuffer&) final { }
- void setCaptureExtraNetworkLoadMetricsEnabled(bool) override { }
+ void setCaptureExtraNetworkLoadMetricsEnabled(bool) final { }
bool isSerialLoadingEnabled() const { return m_isSerialLoadingEnabled; }
void setSerialLoadingEnabled(bool b) { m_isSerialLoadingEnabled = b; }