Make CachedResource::redirectReceived asynchronous
authorachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 Nov 2017 19:23:13 +0000 (19:23 +0000)
committerachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 Nov 2017 19:23:13 +0000 (19:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=179503

Reviewed by Antti Koivisto.

There were a few loops where we called redirectReceived many times in a row,
and these are replaced with a completion handler that recursively calls the next
redirectReceived or the code after the loop.

No change in behavior.

* loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::redirectReceived):
* loader/DocumentLoader.h:
(WebCore::DocumentLoader::setLastCheckedRequest):
* loader/DocumentThreadableLoader.cpp:
(WebCore::DocumentThreadableLoader::redirectReceived):
* loader/DocumentThreadableLoader.h:
* loader/MediaResourceLoader.cpp:
(WebCore::MediaResource::redirectReceived):
* loader/MediaResourceLoader.h:
* loader/PolicyChecker.cpp:
(WebCore::PolicyChecker::checkNavigationPolicy):
* loader/SubresourceLoader.cpp:
(WebCore::SubresourceLoader::willSendRequestInternal):
* loader/cache/CachedRawResource.cpp:
(WebCore::iterate):
(WebCore::CachedRawResource::didAddClient):
(WebCore::CachedRawResource::redirectReceived):
* loader/cache/CachedRawResource.h:
* loader/cache/CachedRawResourceClient.h:
(WebCore::CachedRawResourceClient::redirectReceived):
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource::redirectReceived):
* loader/cache/CachedResource.h:
* platform/graphics/PlatformMediaResourceLoader.h:
(WebCore::PlatformMediaResourceClient::redirectReceived):
* platform/network/cocoa/WebCoreNSURLSession.mm:
(WebCore::WebCoreNSURLSessionDataTaskClient::redirectReceived):

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

16 files changed:
Source/WebCore/ChangeLog
Source/WebCore/loader/DocumentLoader.cpp
Source/WebCore/loader/DocumentLoader.h
Source/WebCore/loader/DocumentThreadableLoader.cpp
Source/WebCore/loader/DocumentThreadableLoader.h
Source/WebCore/loader/MediaResourceLoader.cpp
Source/WebCore/loader/MediaResourceLoader.h
Source/WebCore/loader/PolicyChecker.cpp
Source/WebCore/loader/SubresourceLoader.cpp
Source/WebCore/loader/cache/CachedRawResource.cpp
Source/WebCore/loader/cache/CachedRawResource.h
Source/WebCore/loader/cache/CachedRawResourceClient.h
Source/WebCore/loader/cache/CachedResource.cpp
Source/WebCore/loader/cache/CachedResource.h
Source/WebCore/platform/graphics/PlatformMediaResourceLoader.h
Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm

index c8aa568..bffa6b0 100644 (file)
@@ -1,3 +1,45 @@
+2017-11-10  Alex Christensen  <achristensen@webkit.org>
+
+        Make CachedResource::redirectReceived asynchronous
+        https://bugs.webkit.org/show_bug.cgi?id=179503
+
+        Reviewed by Antti Koivisto.
+
+        There were a few loops where we called redirectReceived many times in a row,
+        and these are replaced with a completion handler that recursively calls the next
+        redirectReceived or the code after the loop.
+
+        No change in behavior.
+
+        * loader/DocumentLoader.cpp:
+        (WebCore::DocumentLoader::redirectReceived):
+        * loader/DocumentLoader.h:
+        (WebCore::DocumentLoader::setLastCheckedRequest):
+        * loader/DocumentThreadableLoader.cpp:
+        (WebCore::DocumentThreadableLoader::redirectReceived):
+        * loader/DocumentThreadableLoader.h:
+        * loader/MediaResourceLoader.cpp:
+        (WebCore::MediaResource::redirectReceived):
+        * loader/MediaResourceLoader.h:
+        * loader/PolicyChecker.cpp:
+        (WebCore::PolicyChecker::checkNavigationPolicy):
+        * loader/SubresourceLoader.cpp:
+        (WebCore::SubresourceLoader::willSendRequestInternal):
+        * loader/cache/CachedRawResource.cpp:
+        (WebCore::iterate):
+        (WebCore::CachedRawResource::didAddClient):
+        (WebCore::CachedRawResource::redirectReceived):
+        * loader/cache/CachedRawResource.h:
+        * loader/cache/CachedRawResourceClient.h:
+        (WebCore::CachedRawResourceClient::redirectReceived):
+        * loader/cache/CachedResource.cpp:
+        (WebCore::CachedResource::redirectReceived):
+        * loader/cache/CachedResource.h:
+        * platform/graphics/PlatformMediaResourceLoader.h:
+        (WebCore::PlatformMediaResourceClient::redirectReceived):
+        * platform/network/cocoa/WebCoreNSURLSession.mm:
+        (WebCore::WebCoreNSURLSessionDataTaskClient::redirectReceived):
+
 2017-11-10  John Wilander  <wilander@apple.com>
 
         Ignore HSTS for partitioned, cross-origin subresource requests
index af64e0b..9c0af0d 100644 (file)
@@ -467,10 +467,11 @@ void DocumentLoader::handleSubstituteDataLoadSoon()
         startDataLoadTimer();
 }
 
-void DocumentLoader::redirectReceived(CachedResource& resource, ResourceRequest& request, const ResourceResponse& redirectResponse)
+void DocumentLoader::redirectReceived(CachedResource& resource, ResourceRequest&& request, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
 {
     ASSERT_UNUSED(resource, &resource == m_mainResource);
     willSendRequest(request, redirectResponse);
+    completionHandler(WTFMove(request));
 }
 
 void DocumentLoader::willSendRequest(ResourceRequest& newRequest, const ResourceResponse& redirectResponse)
index 0f080e4..1ada667 100644 (file)
@@ -195,7 +195,7 @@ public:
     const NavigationAction& triggeringAction() const { return m_triggeringAction; }
     void setTriggeringAction(const NavigationAction&);
     void setOverrideEncoding(const String& encoding) { m_overrideEncoding = encoding; }
-    void setLastCheckedRequest(const ResourceRequest& request) { m_lastCheckedRequest = request; }
+    void setLastCheckedRequest(ResourceRequest&& request) { m_lastCheckedRequest = WTFMove(request); }
     const ResourceRequest& lastCheckedRequest()  { return m_lastCheckedRequest; }
 
     void stopRecordingResponses();
@@ -327,7 +327,7 @@ private:
     void willSendRequest(ResourceRequest&, const ResourceResponse&);
     void finishedLoading();
     void mainReceivedError(const ResourceError&);
-    WEBCORE_EXPORT void redirectReceived(CachedResource&, ResourceRequest&, const ResourceResponse&) override;
+    WEBCORE_EXPORT void redirectReceived(CachedResource&, ResourceRequest&&, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&&) override;
     WEBCORE_EXPORT void responseReceived(CachedResource&, const ResourceResponse&) override;
     WEBCORE_EXPORT void dataReceived(CachedResource&, const char* data, int length) override;
     WEBCORE_EXPORT void notifyFinished(CachedResource&) override;
index 65b7ae9..d50135f 100644 (file)
@@ -234,7 +234,7 @@ void DocumentThreadableLoader::clearResource()
         m_preflightChecker = std::nullopt;
 }
 
-void DocumentThreadableLoader::redirectReceived(CachedResource& resource, ResourceRequest& request, const ResourceResponse& redirectResponse)
+void DocumentThreadableLoader::redirectReceived(CachedResource& resource, ResourceRequest&& request, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
 {
     ASSERT(m_client);
     ASSERT_UNUSED(resource, &resource == m_resource);
@@ -248,18 +248,18 @@ void DocumentThreadableLoader::redirectReceived(CachedResource& resource, Resour
     if (!request.url().protocolIsInHTTPFamily() && m_options.initiator == cachedResourceRequestInitiators().fetch) {
         reportRedirectionWithBadScheme(request.url());
         clearResource();
-        return;
+        return completionHandler(WTFMove(request));
     }
 
     if (!isAllowedByContentSecurityPolicy(request.url(), redirectResponse.isNull() ? ContentSecurityPolicy::RedirectResponseReceived::No : ContentSecurityPolicy::RedirectResponseReceived::Yes)) {
         reportContentSecurityPolicyError(redirectResponse.url());
         clearResource();
-        return;
+        return completionHandler(WTFMove(request));
     }
 
     // Allow same origin requests to continue after allowing clients to audit the redirect.
     if (isAllowedRedirect(request.url()))
-        return;
+        return completionHandler(WTFMove(request));
 
     // Force any subsequent request to use these checks.
     m_sameOriginRequest = false;
@@ -276,7 +276,7 @@ void DocumentThreadableLoader::redirectReceived(CachedResource& resource, Resour
     // Except in case where preflight is needed, loading should be able to continue on its own.
     // But we also handle credentials here if it is restricted to SameOrigin.
     if (m_options.credentials != FetchOptions::Credentials::SameOrigin && m_simpleRequest && isSimpleCrossOriginAccessRequest(request.httpMethod(), *m_originalHeaders))
-        return;
+        return completionHandler(WTFMove(request));
 
     m_options.storedCredentialsPolicy = StoredCredentialsPolicy::DoNotUse;
 
@@ -289,6 +289,7 @@ void DocumentThreadableLoader::redirectReceived(CachedResource& resource, Resour
     request.setHTTPHeaderFields(*m_originalHeaders);
 
     makeCrossOriginAccessRequest(ResourceRequest(request));
+    completionHandler(WTFMove(request));
 }
 
 void DocumentThreadableLoader::dataSent(CachedResource& resource, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
index 10ef734..21c8ab6 100644 (file)
@@ -83,7 +83,7 @@ namespace WebCore {
         void dataSent(CachedResource&, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override;
         void responseReceived(CachedResource&, const ResourceResponse&) override;
         void dataReceived(CachedResource&, const char* data, int dataLength) override;
-        void redirectReceived(CachedResource&, ResourceRequest&, const ResourceResponse&) override;
+        void redirectReceived(CachedResource&, ResourceRequest&&, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&&) override;
         void finishedTimingForWorkerLoad(CachedResource&, const ResourceTiming&) override;
         void finishedTimingForWorkerLoad(const ResourceTiming&);
         void notifyFinished(CachedResource&) override;
index 906a4b6..841d8f1 100644 (file)
@@ -174,13 +174,15 @@ bool MediaResource::shouldCacheResponse(CachedResource& resource, const Resource
     return true;
 }
 
-void MediaResource::redirectReceived(CachedResource& resource, ResourceRequest& request, const ResourceResponse& response)
+void MediaResource::redirectReceived(CachedResource& resource, ResourceRequest&& request, const ResourceResponse& response, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
 {
     ASSERT_UNUSED(resource, &resource == m_resource);
 
     RefPtr<MediaResource> protectedThis(this);
     if (m_client)
-        m_client->redirectReceived(*this, request, response);
+        m_client->redirectReceived(*this, WTFMove(request), response, WTFMove(completionHandler));
+    else
+        completionHandler(WTFMove(request));
 }
 
 void MediaResource::dataSent(CachedResource& resource, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
index b004b7a..ea0e428 100644 (file)
@@ -83,7 +83,7 @@ public:
 
     // CachedRawResourceClient
     void responseReceived(CachedResource&, const ResourceResponse&) override;
-    void redirectReceived(CachedResource&, ResourceRequest&, const ResourceResponse&) override;
+    void redirectReceived(CachedResource&, ResourceRequest&&, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&&) override;
     bool shouldCacheResponse(CachedResource&, const ResourceResponse&) override;
     void dataSent(CachedResource&, unsigned long long, unsigned long long) override;
     void dataReceived(CachedResource&, const char*, int) override;
index e18a5c0..9537e26 100644 (file)
@@ -93,7 +93,7 @@ void PolicyChecker::checkNavigationPolicy(const ResourceRequest& request, bool d
     // This avoids confusion on the part of the client.
     if (equalIgnoringHeaderFields(request, loader->lastCheckedRequest()) || (!request.isNull() && request.url().isEmpty())) {
         function(request, nullptr, true);
-        loader->setLastCheckedRequest(request);
+        loader->setLastCheckedRequest(ResourceRequest(request));
         return;
     }
 
@@ -121,7 +121,7 @@ void PolicyChecker::checkNavigationPolicy(const ResourceRequest& request, bool d
         return;
     }
 
-    loader->setLastCheckedRequest(request);
+    loader->setLastCheckedRequest(ResourceRequest(request));
 
 #if USE(QUICK_LOOK)
     // Always allow QuickLook-generated URLs based on the protocol scheme.
index 2b63ca3..c1c8a53 100644 (file)
@@ -183,6 +183,25 @@ void SubresourceLoader::willSendRequestInternal(ResourceRequest&& newRequest, co
         ResourceLoadObserver::shared().logSubresourceLoading(m_frame.get(), newRequest, redirectResponse);
     }
 
+    auto continueWillSendRequest = [this, protectedThis = makeRef(*this), redirectResponse] (CompletionHandler<void(ResourceRequest&&)>&& completionHandler, ResourceRequest&& newRequest) mutable {
+        if (newRequest.isNull() || reachedTerminalState())
+            return completionHandler(WTFMove(newRequest));
+
+        ResourceLoader::willSendRequestInternal(WTFMove(newRequest), redirectResponse, [this, protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler), redirectResponse] (ResourceRequest&& request) mutable {
+            if (reachedTerminalState())
+                return completionHandler(WTFMove(request));
+
+            if (request.isNull()) {
+                cancel();
+                return completionHandler(WTFMove(request));
+            }
+
+            if (m_resource->type() == CachedResource::MainResource && !redirectResponse.isNull())
+                m_documentLoader->willContinueMainResourceLoadAfterRedirect(request);
+            completionHandler(WTFMove(request));
+        });
+    };
+
     ASSERT(!newRequest.isNull());
     if (!redirectResponse.isNull()) {
         if (options().redirect != FetchOptions::Redirect::Follow) {
@@ -234,25 +253,13 @@ void SubresourceLoader::willSendRequestInternal(ResourceRequest&& newRequest, co
             return completionHandler(WTFMove(newRequest));
         }
         m_loadTiming.addRedirect(redirectResponse.url(), newRequest.url());
-        m_resource->redirectReceived(newRequest, redirectResponse);
+        m_resource->redirectReceived(WTFMove(newRequest), redirectResponse, [completionHandler = WTFMove(completionHandler), continueWillSendRequest = WTFMove(continueWillSendRequest)] (ResourceRequest&& request) mutable {
+            continueWillSendRequest(WTFMove(completionHandler), WTFMove(request));
+        });
+        return;
     }
 
-    if (newRequest.isNull() || reachedTerminalState())
-        return completionHandler(WTFMove(newRequest));
-
-    ResourceLoader::willSendRequestInternal(WTFMove(newRequest), redirectResponse, [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler), redirectResponse] (ResourceRequest&& request) mutable {
-        if (reachedTerminalState())
-            return completionHandler(WTFMove(request));
-        
-        if (request.isNull()) {
-            cancel();
-            return completionHandler(WTFMove(request));
-        }
-        
-        if (m_resource->type() == CachedResource::MainResource && !redirectResponse.isNull())
-            m_documentLoader->willContinueMainResourceLoadAfterRedirect(request);
-        completionHandler(WTFMove(request));
-    });
+    continueWillSendRequest(WTFMove(completionHandler), WTFMove(newRequest));
 }
 
 void SubresourceLoader::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
index 892539f..98ef34d 100644 (file)
@@ -32,6 +32,7 @@
 #include "HTTPHeaderNames.h"
 #include "SharedBuffer.h"
 #include "SubresourceLoader.h"
+#include <wtf/CompletionHandler.h>
 #include <wtf/text/StringView.h>
 
 namespace WebCore {
@@ -115,42 +116,49 @@ void CachedRawResource::notifyClientsDataWasReceived(const char* data, unsigned
         c->dataReceived(*this, data, length);
 }
 
+static void iterateRedirects(CachedResourceHandle<CachedRawResource>&& handle, CachedRawResourceClient& client, Vector<std::pair<ResourceRequest, ResourceResponse>>&& redirectsInReverseOrder, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
+{
+    if (!handle->hasClient(client) || redirectsInReverseOrder.isEmpty())
+        return completionHandler({ });
+    auto redirectPair = redirectsInReverseOrder.takeLast();
+    client.redirectReceived(*handle, WTFMove(redirectPair.first), WTFMove(redirectPair.second), [handle = WTFMove(handle), client, redirectsInReverseOrder = WTFMove(redirectsInReverseOrder), completionHandler = WTFMove(completionHandler)] (ResourceRequest&&) mutable {
+        // Ignore the new request because we can't do anything with it.
+        // We're just replying a redirect chain that has already happened.
+        iterateRedirects(WTFMove(handle), client, WTFMove(redirectsInReverseOrder), WTFMove(completionHandler));
+    });
+}
+
 void CachedRawResource::didAddClient(CachedResourceClient& c)
 {
-    if (!hasClient(c))
-        return;
-    // The calls to the client can result in events running, potentially causing
-    // this resource to be evicted from the cache and all clients to be removed,
-    // so a protector is necessary.
-    CachedResourceHandle<CachedRawResource> protectedThis(this);
     CachedRawResourceClient& client = static_cast<CachedRawResourceClient&>(c);
     size_t redirectCount = m_redirectChain.size();
-    for (size_t i = 0; i < redirectCount; i++) {
-        RedirectPair redirect = m_redirectChain[i];
-        ResourceRequest request(redirect.m_request);
-        client.redirectReceived(*this, request, redirect.m_redirectResponse);
-        if (!hasClient(c))
-            return;
+    Vector<std::pair<ResourceRequest, ResourceResponse>> redirectsInReverseOrder;
+    redirectsInReverseOrder.reserveInitialCapacity(redirectCount);
+    for (size_t i = 0; i < redirectCount; ++i) {
+        const auto& pair = m_redirectChain[redirectCount - i - 1];
+        redirectsInReverseOrder.uncheckedAppend(std::make_pair(pair.m_request, pair.m_redirectResponse));
     }
-    ASSERT(redirectCount == m_redirectChain.size());
-
-    if (!m_response.isNull()) {
-        ResourceResponse response(m_response);
-        if (validationCompleting())
-            response.setSource(ResourceResponse::Source::MemoryCacheAfterValidation);
-        else {
-            ASSERT(!validationInProgress());
-            response.setSource(ResourceResponse::Source::MemoryCache);
+    iterateRedirects(CachedResourceHandle<CachedRawResource>(this), client, WTFMove(redirectsInReverseOrder), [this, protectedThis = CachedResourceHandle<CachedRawResource>(this), client = &client] (ResourceRequest&&) mutable {
+        if (!hasClient(*client))
+            return;
+        if (!m_response.isNull()) {
+            ResourceResponse response(m_response);
+            if (validationCompleting())
+                response.setSource(ResourceResponse::Source::MemoryCacheAfterValidation);
+            else {
+                ASSERT(!validationInProgress());
+                response.setSource(ResourceResponse::Source::MemoryCache);
+            }
+            client->responseReceived(*this, response);
         }
-        client.responseReceived(*this, response);
-    }
-    if (!hasClient(c))
-        return;
-    if (m_data)
-        client.dataReceived(*this, m_data->data(), m_data->size());
-    if (!hasClient(c))
-       return;
-    CachedResource::didAddClient(client);
+        if (!hasClient(*client))
+            return;
+        if (m_data)
+            client->dataReceived(*this, m_data->data(), m_data->size());
+        if (!hasClient(*client))
+            return;
+        CachedResource::didAddClient(*client);
+    });
 }
 
 void CachedRawResource::allClientsRemoved()
@@ -159,16 +167,27 @@ void CachedRawResource::allClientsRemoved()
         m_loader->cancelIfNotFinishing();
 }
 
-void CachedRawResource::redirectReceived(ResourceRequest& request, const ResourceResponse& response)
+static void iterateClients(CachedResourceClientWalker<CachedRawResourceClient>&& walker, CachedResourceHandle<CachedRawResource>&& handle, ResourceRequest&& request, std::unique_ptr<ResourceResponse>&& response, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
 {
-    CachedResourceHandle<CachedRawResource> protectedThis(this);
-    if (!response.isNull()) {
-        CachedResourceClientWalker<CachedRawResourceClient> w(m_clients);
-        while (CachedRawResourceClient* c = w.next())
-            c->redirectReceived(*this, request, response);
+    auto client = walker.next();
+    if (!client)
+        return completionHandler(WTFMove(request));
+    const ResourceResponse& responseReference = *response;
+    client->redirectReceived(*handle, WTFMove(request), responseReference, [walker = WTFMove(walker), handle = WTFMove(handle), response = WTFMove(response), completionHandler = WTFMove(completionHandler)] (ResourceRequest&& request) mutable {
+        iterateClients(WTFMove(walker), WTFMove(handle), WTFMove(request), WTFMove(response), WTFMove(completionHandler));
+    });
+}
+
+void CachedRawResource::redirectReceived(ResourceRequest&& request, const ResourceResponse& response, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
+{
+    if (response.isNull())
+        CachedResource::redirectReceived(WTFMove(request), response, WTFMove(completionHandler));
+    else {
         m_redirectChain.append(RedirectPair(request, response));
+        iterateClients(CachedResourceClientWalker<CachedRawResourceClient>(m_clients), CachedResourceHandle<CachedRawResource>(this), WTFMove(request), std::make_unique<ResourceResponse>(response), [this, protectedThis = CachedResourceHandle<CachedRawResource>(this), completionHandler = WTFMove(completionHandler), response] (ResourceRequest&& request) mutable {
+            CachedResource::redirectReceived(WTFMove(request), response, WTFMove(completionHandler));
+        });
     }
-    CachedResource::redirectReceived(request, response);
 }
 
 void CachedRawResource::responseReceived(const ResourceResponse& response)
index 548ff69..e4583ed 100644 (file)
@@ -62,7 +62,7 @@ private:
     bool shouldIgnoreHTTPStatusCodeErrors() const override { return true; }
     void allClientsRemoved() override;
 
-    void redirectReceived(ResourceRequest&, const ResourceResponse&) override;
+    void redirectReceived(ResourceRequest&&, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&&) override;
     void responseReceived(const ResourceResponse&) override;
     bool shouldCacheResponse(const ResourceResponse&) override;
     void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override;
index 52f2b66..ca8dfbe 100644 (file)
@@ -23,6 +23,7 @@
 #pragma once
 
 #include "CachedResourceClient.h"
+#include <wtf/CompletionHandler.h>
 
 namespace WebCore {
 
@@ -41,7 +42,7 @@ public:
     virtual void responseReceived(CachedResource&, const ResourceResponse&) { }
     virtual bool shouldCacheResponse(CachedResource&, const ResourceResponse&) { return true; }
     virtual void dataReceived(CachedResource&, const char* /* data */, int /* length */) { }
-    virtual void redirectReceived(CachedResource&, ResourceRequest&, const ResourceResponse&) { }
+    virtual void redirectReceived(CachedResource&, ResourceRequest&& request, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&& completionHandler) { completionHandler(WTFMove(request)); }
     virtual void finishedTimingForWorkerLoad(CachedResource&, const ResourceTiming&) { }
 #if USE(SOUP)
     virtual char* getOrCreateReadBuffer(CachedResource&, size_t /* requestedSize */, size_t& /* actualSize */) { return nullptr; }
index 971a6e3..d8dbdf3 100644 (file)
@@ -453,13 +453,14 @@ std::chrono::microseconds CachedResource::freshnessLifetime(const ResourceRespon
     return computeFreshnessLifetimeForHTTPFamily(response, m_responseTimestamp);
 }
 
-void CachedResource::redirectReceived(ResourceRequest&, const ResourceResponse& response)
+void CachedResource::redirectReceived(ResourceRequest&& request, const ResourceResponse& response, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
 {
     m_requestedFromNetworkingLayer = true;
     if (response.isNull())
-        return;
+        return completionHandler(WTFMove(request));
 
     updateRedirectChainStatus(m_redirectChainCacheStatus, response);
+    completionHandler(WTFMove(request));
 }
 
 void CachedResource::setResponse(const ResourceResponse& response)
index 99bfb8b..c7eae12 100644 (file)
@@ -201,7 +201,7 @@ public:
 
     SharedBuffer* resourceBuffer() const { return m_data.get(); }
 
-    virtual void redirectReceived(ResourceRequest&, const ResourceResponse&);
+    virtual void redirectReceived(ResourceRequest&&, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&&);
     virtual void responseReceived(const ResourceResponse&);
     virtual bool shouldCacheResponse(const ResourceResponse&) { return true; }
     void setResponse(const ResourceResponse&);
index f9fade4..a8b09c7 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(VIDEO)
 
+#include <wtf/CompletionHandler.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/RefCounted.h>
 #include <wtf/ThreadSafeRefCounted.h>
@@ -43,7 +44,7 @@ public:
     virtual ~PlatformMediaResourceClient() = default;
 
     virtual void responseReceived(PlatformMediaResource&, const ResourceResponse&) { }
-    virtual void redirectReceived(PlatformMediaResource&, ResourceRequest&, const ResourceResponse&) { }
+    virtual void redirectReceived(PlatformMediaResource&, ResourceRequest&& request, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&& completionHandler) { completionHandler(WTFMove(request)); }
     virtual bool shouldCacheResponse(PlatformMediaResource&, const ResourceResponse&) { return true; }
     virtual void dataSent(PlatformMediaResource&, unsigned long long, unsigned long long) { }
     virtual void dataReceived(PlatformMediaResource&, const char*, int) { }
index 636682d..8178c99 100644 (file)
@@ -29,6 +29,7 @@
 #import "CachedResourceRequest.h"
 #import "PlatformMediaResourceLoader.h"
 #import "SubresourceLoader.h"
+#import <wtf/CompletionHandler.h>
 
 using namespace WebCore;
 
@@ -349,7 +350,7 @@ public:
     }
 
     void responseReceived(PlatformMediaResource&, const ResourceResponse&) override;
-    void redirectReceived(PlatformMediaResource&, ResourceRequest&, const ResourceResponse&) override;
+    void redirectReceived(PlatformMediaResource&, ResourceRequest&&, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&&) override;
     bool shouldCacheResponse(PlatformMediaResource&, const ResourceResponse&) override;
     void dataSent(PlatformMediaResource&, unsigned long long, unsigned long long) override;
     void dataReceived(PlatformMediaResource&, const char* /* data */, int /* length */) override;
@@ -381,9 +382,10 @@ void WebCoreNSURLSessionDataTaskClient::dataReceived(PlatformMediaResource& reso
     [m_task resource:resource receivedData:data length:length];
 }
 
-void WebCoreNSURLSessionDataTaskClient::redirectReceived(PlatformMediaResource& resource, ResourceRequest& request, const ResourceResponse& response)
+void WebCoreNSURLSessionDataTaskClient::redirectReceived(PlatformMediaResource& resource, ResourceRequest&& request, const ResourceResponse& response, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
 {
     [m_task resource:resource receivedRedirect:response request:request];
+    completionHandler(WTFMove(request));
 }
 
 void WebCoreNSURLSessionDataTaskClient::accessControlCheckFailed(PlatformMediaResource& resource, const ResourceError& error)