Changeset 194313 in webkit


Ignore:
Timestamp:
Dec 19, 2015 5:26:38 AM (8 years ago)
Author:
Antti Koivisto
Message:

Cache redirects as separate entries
https://bugs.webkit.org/show_bug.cgi?id=152424

Reviewed by Alex Christensen.

Source/WebCore:

Test: http/tests/cache/disk-cache/disk-cache-redirect.html

  • platform/network/ResourceRequestBase.h:

Source/WebKit2:

We are currently caching redirect chains. This has correctness issues and can be inefficient in cases
where multiple URLs redirect to the same destination.

After this patch we write a cache entry for each redirect individually.

  • NetworkProcess/NetworkLoad.cpp:

(WebKit::NetworkLoad::sharedWillSendRedirectedRequest):

  • NetworkProcess/NetworkLoad.h:

(WebKit::NetworkLoad::currentRequest):
(WebKit::NetworkLoad::clearCurrentRequest):

  • NetworkProcess/NetworkLoadClient.h:

Add original request as a parameter for willSendRedirectedRequest.

  • NetworkProcess/NetworkResourceLoader.cpp:

(WebKit::NetworkResourceLoader::~NetworkResourceLoader):
(WebKit::NetworkResourceLoader::canUseCache):

Factor to a function.

(WebKit::NetworkResourceLoader::isSynchronous):
(WebKit::NetworkResourceLoader::start):
(WebKit::NetworkResourceLoader::retrieveCacheEntry):

Factor to a function.
Call dispatchWillSendRequestForCacheEntry for cached redirects.

(WebKit::NetworkResourceLoader::startNetworkLoad):

Make this take request as argument instead of always loading originalRequest().

(WebKit::NetworkResourceLoader::abort):
(WebKit::NetworkResourceLoader::didFinishLoading):

Remove redirect chain code.
Store cache entry for current request instead of the original request.

(WebKit::NetworkResourceLoader::didFailLoading):
(WebKit::NetworkResourceLoader::willSendRedirectedRequest):

Write cache entry for redirect.

(WebKit::NetworkResourceLoader::continueWillSendRequest):

If we are playing back cached redirect continue with another cache lookup.

(WebKit::NetworkResourceLoader::didRetrieveCacheEntry):

No need to synthesize fake willSendRequest anymore.

(WebKit::NetworkResourceLoader::validateCacheEntry):
(WebKit::NetworkResourceLoader::dispatchWillSendRequestForCacheEntry):

Route via web process willSendRequest so cached redirects looks exactly like network ones.

(WebKit::NetworkResourceLoader::messageSenderConnection):

  • NetworkProcess/NetworkResourceLoader.h:
  • NetworkProcess/cache/NetworkCache.cpp:

(WebKit::NetworkCache::makeUseDecision):

Ignore validation headers for cached redirects.

(WebKit::NetworkCache::makeRetrieveDecision):
(WebKit::NetworkCache::makeStoreDecision):
(WebKit::NetworkCache::Cache::retrieve):
(WebKit::NetworkCache::Cache::store):

Rename originalRequest -> request since it is not really the original request anymore in all cases.

(WebKit::NetworkCache::Cache::storeRedirect):

Stored redirects include the network layer generated ResourceRequest instead of body data.

(WebKit::NetworkCache::Cache::update):

  • NetworkProcess/cache/NetworkCache.h:
  • NetworkProcess/cache/NetworkCacheEntry.cpp:

(WebKit::NetworkCache::Entry::Entry):

New constructor for making redirect entries.

(WebKit::NetworkCache::Entry::encodeAsStorageRecord):
(WebKit::NetworkCache::Entry::decodeStorageRecord):

Encoding support.

  • NetworkProcess/cache/NetworkCacheEntry.h:

(WebKit::NetworkCache::Entry::varyingRequestHeaders):
(WebKit::NetworkCache::Entry::redirectRequest):

  • NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp:

(WebKit::NetworkCache::SpeculativeLoad::~SpeculativeLoad):
(WebKit::NetworkCache::SpeculativeLoad::willSendRedirectedRequest):

  • NetworkProcess/cache/NetworkCacheSpeculativeLoad.h:
  • NetworkProcess/cache/NetworkCacheStatistics.cpp:

(WebKit::NetworkCache::cachedEntryReuseFailureToDiagnosticKey):

LayoutTests:

  • http/tests/cache/disk-cache/disk-cache-redirect-expected.txt: Added.
  • http/tests/cache/disk-cache/disk-cache-redirect.html: Added.
  • http/tests/cache/disk-cache/resources/generate-response.cgi:
Location:
trunk
Files:
2 added
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r194306 r194313  
     12015-12-18  Antti Koivisto  <antti@apple.com>
     2
     3        Cache redirects as separate entries
     4        https://bugs.webkit.org/show_bug.cgi?id=152424
     5
     6        Reviewed by Alex Christensen.
     7
     8        * http/tests/cache/disk-cache/disk-cache-redirect-expected.txt: Added.
     9        * http/tests/cache/disk-cache/disk-cache-redirect.html: Added.
     10        * http/tests/cache/disk-cache/resources/generate-response.cgi:
     11
    1122015-12-18  Michael Catanzaro  <mcatanzaro@igalia.com>
    213
  • trunk/LayoutTests/http/tests/cache/disk-cache/resources/generate-response.cgi

    r189177 r194313  
    99my $delay = $query->param('delay') || 0;
    1010my $body = $query->param('body') || 0;
     11my $status = $query->param('Status') || 0;
    1112
    1213if ($body eq "unique") {
     
    1516
    1617my $hasStatusCode = 0;
     18my $hasLocation = 0;
     19if ($status == 301 || $status == 302 || $status == 303 || $status == 307) {
     20    if ($query->param('Location') eq "unique-cacheable") {
     21        my $redirectBody = sprintf "%08X", rand(0xffffffff);
     22        print "Status: ". $status . "\n";
     23        print "Location: generate-response.cgi?body=" . $redirectBody . "&Cache-control=max-age%3D1000&uniqueId=" . $query->param('uniqueId') . "\n";
     24        $hasLocation = 1;
     25        $hasStatusCode = 1;
     26    }
     27}
     28
    1729my $hasExpiresHeader = 0;
    1830if ($query->http && $query->http("If-None-Match") eq "match") {
     
    3042        print "Status: 206\n";
    3143    } else {
    32         print "Status: 416\n";
     44        print "Status: 416\n";
    3345    }
    3446
     
    4052    next if ($_ eq "delay");
    4153    next if ($_ eq "body");
     54    next if ($_ eq "Location" and $hasLocation);
    4255    next if ($_ eq "Status" and $hasStatusCode);
    4356    next if ($_ eq "Expires" and $hasExpiresHeader);
  • trunk/Source/WebCore/ChangeLog

    r194305 r194313  
     12015-12-18  Antti Koivisto  <antti@apple.com>
     2
     3        Cache redirects as separate entries
     4        https://bugs.webkit.org/show_bug.cgi?id=152424
     5
     6        Reviewed by Alex Christensen.
     7
     8        Test: http/tests/cache/disk-cache/disk-cache-redirect.html
     9
     10        * platform/network/ResourceRequestBase.h:
     11
    1122015-12-18  Per Arne Vollan  <peavo@outlook.com>
    213
  • trunk/Source/WebCore/platform/network/ResourceRequestBase.h

    r192995 r194313  
    5555        WTF_MAKE_FAST_ALLOCATED;
    5656    public:
    57         static std::unique_ptr<ResourceRequest> adopt(std::unique_ptr<CrossThreadResourceRequestData>);
     57        WEBCORE_EXPORT static std::unique_ptr<ResourceRequest> adopt(std::unique_ptr<CrossThreadResourceRequestData>);
    5858
    5959        // Gets a copy of the data suitable for passing to another thread.
    60         std::unique_ptr<CrossThreadResourceRequestData> copyData() const;
     60        WEBCORE_EXPORT std::unique_ptr<CrossThreadResourceRequestData> copyData() const;
    6161
    6262        WEBCORE_EXPORT bool isNull() const;
  • trunk/Source/WebKit2/ChangeLog

    r194303 r194313  
     12015-12-18  Antti Koivisto  <antti@apple.com>
     2
     3        Cache redirects as separate entries
     4        https://bugs.webkit.org/show_bug.cgi?id=152424
     5
     6        Reviewed by Alex Christensen.
     7
     8        We are currently caching redirect chains. This has correctness issues and can be inefficient in cases
     9        where multiple URLs redirect to the same destination.
     10
     11        After this patch we write a cache entry for each redirect individually.
     12
     13        * NetworkProcess/NetworkLoad.cpp:
     14        (WebKit::NetworkLoad::sharedWillSendRedirectedRequest):
     15        * NetworkProcess/NetworkLoad.h:
     16        (WebKit::NetworkLoad::currentRequest):
     17        (WebKit::NetworkLoad::clearCurrentRequest):
     18        * NetworkProcess/NetworkLoadClient.h:
     19
     20            Add original request as a parameter for willSendRedirectedRequest.
     21
     22        * NetworkProcess/NetworkResourceLoader.cpp:
     23        (WebKit::NetworkResourceLoader::~NetworkResourceLoader):
     24        (WebKit::NetworkResourceLoader::canUseCache):
     25
     26            Factor to a function.
     27
     28        (WebKit::NetworkResourceLoader::isSynchronous):
     29        (WebKit::NetworkResourceLoader::start):
     30        (WebKit::NetworkResourceLoader::retrieveCacheEntry):
     31
     32            Factor to a function.
     33            Call dispatchWillSendRequestForCacheEntry for cached redirects.
     34
     35        (WebKit::NetworkResourceLoader::startNetworkLoad):
     36
     37            Make this take request as argument instead of always loading originalRequest().
     38
     39        (WebKit::NetworkResourceLoader::abort):
     40        (WebKit::NetworkResourceLoader::didFinishLoading):
     41
     42            Remove redirect chain code.
     43            Store cache entry for current request instead of the original request.
     44
     45        (WebKit::NetworkResourceLoader::didFailLoading):
     46        (WebKit::NetworkResourceLoader::willSendRedirectedRequest):
     47
     48            Write cache entry for redirect.
     49
     50        (WebKit::NetworkResourceLoader::continueWillSendRequest):
     51
     52            If we are playing back cached redirect continue with another cache lookup.
     53
     54        (WebKit::NetworkResourceLoader::didRetrieveCacheEntry):
     55
     56            No need to synthesize fake willSendRequest anymore.
     57
     58        (WebKit::NetworkResourceLoader::validateCacheEntry):
     59        (WebKit::NetworkResourceLoader::dispatchWillSendRequestForCacheEntry):
     60
     61            Route via web process willSendRequest so cached redirects looks exactly like network ones.
     62
     63        (WebKit::NetworkResourceLoader::messageSenderConnection):
     64        * NetworkProcess/NetworkResourceLoader.h:
     65        * NetworkProcess/cache/NetworkCache.cpp:
     66        (WebKit::NetworkCache::makeUseDecision):
     67
     68            Ignore validation headers for cached redirects.
     69
     70        (WebKit::NetworkCache::makeRetrieveDecision):
     71        (WebKit::NetworkCache::makeStoreDecision):
     72        (WebKit::NetworkCache::Cache::retrieve):
     73        (WebKit::NetworkCache::Cache::store):
     74
     75            Rename originalRequest -> request since it is not really the original request anymore in all cases.
     76
     77        (WebKit::NetworkCache::Cache::storeRedirect):
     78
     79            Stored redirects include the network layer generated ResourceRequest instead of body data.
     80
     81        (WebKit::NetworkCache::Cache::update):
     82        * NetworkProcess/cache/NetworkCache.h:
     83        * NetworkProcess/cache/NetworkCacheEntry.cpp:
     84        (WebKit::NetworkCache::Entry::Entry):
     85
     86            New constructor for making redirect entries.
     87
     88        (WebKit::NetworkCache::Entry::encodeAsStorageRecord):
     89        (WebKit::NetworkCache::Entry::decodeStorageRecord):
     90
     91            Encoding support.
     92
     93        * NetworkProcess/cache/NetworkCacheEntry.h:
     94        (WebKit::NetworkCache::Entry::varyingRequestHeaders):
     95        (WebKit::NetworkCache::Entry::redirectRequest):
     96        * NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp:
     97        (WebKit::NetworkCache::SpeculativeLoad::~SpeculativeLoad):
     98        (WebKit::NetworkCache::SpeculativeLoad::willSendRedirectedRequest):
     99        * NetworkProcess/cache/NetworkCacheSpeculativeLoad.h:
     100        * NetworkProcess/cache/NetworkCacheStatistics.cpp:
     101        (WebKit::NetworkCache::cachedEntryReuseFailureToDiagnosticKey):
     102
    11032015-12-18  Michael Catanzaro  <mcatanzaro@igalia.com>
    2104
  • trunk/Source/WebKit2/NetworkProcess/NetworkLoad.cpp

    r194043 r194313  
    150150    ASSERT(RunLoop::isMain());
    151151
     152    auto oldRequest = m_currentRequest;
    152153    m_currentRequest = request;
    153     m_client.willSendRedirectedRequest(request, redirectResponse);
     154    m_client.willSendRedirectedRequest(oldRequest, request, redirectResponse);
    154155}
    155156
  • trunk/Source/WebKit2/NetworkProcess/NetworkLoad.h

    r194043 r194313  
    5454    void cancel();
    5555
     56    const WebCore::ResourceRequest& currentRequest() const { return m_currentRequest; }
    5657    void clearCurrentRequest() { m_currentRequest = WebCore::ResourceRequest(); }
    5758
  • trunk/Source/WebKit2/NetworkProcess/NetworkLoadClient.h

    r193787 r194313  
    5151    virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) = 0;
    5252    virtual void canAuthenticateAgainstProtectionSpaceAsync(const WebCore::ProtectionSpace&) = 0;
    53     virtual void willSendRedirectedRequest(const WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse) = 0;
     53    virtual void willSendRedirectedRequest(const WebCore::ResourceRequest&, const WebCore::ResourceRequest& redirectRequest, const WebCore::ResourceResponse& redirectResponse) = 0;
    5454    enum class ShouldContinueDidReceiveResponse { No, Yes };
    5555    virtual ShouldContinueDidReceiveResponse didReceiveResponse(const WebCore::ResourceResponse&) = 0;
  • trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp

    r193787 r194313  
    108108}
    109109
     110#if ENABLE(NETWORK_CACHE)
     111bool NetworkResourceLoader::canUseCache(const ResourceRequest& request) const
     112{
     113    if (!NetworkCache::singleton().isEnabled())
     114        return false;
     115    if (sessionID().isEphemeral())
     116        return false;
     117    if (!request.url().protocolIsInHTTPFamily())
     118        return false;
     119    return true;
     120}
     121#endif
     122
    110123bool NetworkResourceLoader::isSynchronous() const
    111124{
     
    121134
    122135#if ENABLE(NETWORK_CACHE)
    123     if (!NetworkCache::singleton().isEnabled() || sessionID().isEphemeral() || !originalRequest().url().protocolIsInHTTPFamily()) {
    124         startNetworkLoad();
    125         return;
    126     }
     136    if (canUseCache(originalRequest())) {
     137        retrieveCacheEntry(originalRequest());
     138        return;
     139    }
     140#endif
     141
     142    startNetworkLoad(originalRequest());
     143}
     144
     145#if ENABLE(NETWORK_CACHE)
     146void NetworkResourceLoader::retrieveCacheEntry(const ResourceRequest& request)
     147{
     148    ASSERT(canUseCache(request));
    127149
    128150    RefPtr<NetworkResourceLoader> loader(this);
    129     NetworkCache::singleton().retrieve(originalRequest(), { m_parameters.webPageID, m_parameters.webFrameID }, [loader](std::unique_ptr<NetworkCache::Entry> entry) {
     151    NetworkCache::singleton().retrieve(request, { m_parameters.webPageID, m_parameters.webFrameID }, [loader, request](std::unique_ptr<NetworkCache::Entry> entry) {
    130152        if (loader->hasOneRef()) {
    131153            // The loader has been aborted and is only held alive by this lambda.
     
    133155        }
    134156        if (!entry) {
    135             loader->startNetworkLoad();
     157            loader->startNetworkLoad(request);
    136158            return;
    137159        }
     160        if (entry->redirectRequest()) {
     161            loader->dispatchWillSendRequestForCacheEntry(WTF::move(entry));
     162            return;
     163        }
    138164        if (loader->m_parameters.needsCertificateInfo && !entry->response().containsCertificateInfo()) {
    139             loader->startNetworkLoad();
     165            loader->startNetworkLoad(request);
    140166            return;
    141167        }
     
    146172        loader->didRetrieveCacheEntry(WTF::move(entry));
    147173    });
    148 #else
    149     startNetworkLoad();
    150 #endif
    151 }
    152 
    153 void NetworkResourceLoader::startNetworkLoad(const Optional<ResourceRequest>& updatedRequest)
     174}
     175#endif
     176
     177void NetworkResourceLoader::startNetworkLoad(const ResourceRequest& request)
    154178{
    155179    consumeSandboxExtensions();
     
    159183
    160184#if ENABLE(NETWORK_CACHE)
    161     if (NetworkCache::singleton().isEnabled())
     185    if (canUseCache(request))
    162186        m_bufferedDataForCache = SharedBuffer::create();
    163187#endif
     
    165189    NetworkLoadParameters parameters = m_parameters;
    166190    parameters.defersLoading = m_defersLoading;
    167     if (updatedRequest)
    168         parameters.request = updatedRequest.value();
     191    parameters.request = request;
    169192    m_networkLoad = std::make_unique<NetworkLoad>(*this, parameters);
    170193}
     
    213236
    214237    if (m_networkLoad && !m_didConvertToDownload) {
    215         m_networkLoad->cancel();
    216 
    217 #if ENABLE(NETWORK_CACHE)
    218         if (NetworkCache::singleton().isEnabled()) {
     238#if ENABLE(NETWORK_CACHE)
     239        if (canUseCache(m_networkLoad->currentRequest())) {
    219240            // We might already have used data from this incomplete load. Ensure older versions don't remain in the cache after cancel.
    220241            if (!m_response.isNull())
    221                 NetworkCache::singleton().remove(originalRequest());
    222         }
    223 #endif
     242                NetworkCache::singleton().remove(m_networkLoad->currentRequest());
     243        }
     244#endif
     245        m_networkLoad->cancel();
    224246    }
    225247
     
    303325{
    304326#if ENABLE(NETWORK_CACHE)
    305     if (NetworkCache::singleton().isEnabled()) {
     327    if (canUseCache(m_networkLoad->currentRequest())) {
    306328        if (m_cacheEntryForValidation) {
    307329            // 304 Not Modified
     
    311333            return;
    312334        }
    313         bool allowStale = originalRequest().cachePolicy() >= ReturnCacheDataElseLoad;
    314         bool hasCacheableRedirect = m_response.isHTTP() && redirectChainAllowsReuse(m_redirectChainCacheStatus, allowStale ? ReuseExpiredRedirection : DoNotReuseExpiredRedirection);
    315         if (hasCacheableRedirect && m_redirectChainCacheStatus.status == RedirectChainCacheStatus::CachedRedirection) {
    316             // Maybe we should cache the actual redirects instead of the end result?
    317             auto now = std::chrono::system_clock::now();
    318             auto responseEndOfValidity = now + computeFreshnessLifetimeForHTTPFamily(m_response, now) - computeCurrentAge(m_response, now);
    319             hasCacheableRedirect = responseEndOfValidity <= m_redirectChainCacheStatus.endOfValidity;
    320         }
    321335
    322336        bool isPrivateSession = sessionID().isEphemeral();
    323         if (m_bufferedDataForCache && hasCacheableRedirect && !isPrivateSession) {
     337        if (m_bufferedDataForCache && m_response.isHTTP() && !isPrivateSession) {
    324338            // Keep the connection alive.
    325339            RefPtr<NetworkConnectionToWebProcess> connection(&connectionToWebProcess());
    326340            RefPtr<NetworkResourceLoader> loader(this);
    327             NetworkCache::singleton().store(originalRequest(), m_response, WTF::move(m_bufferedDataForCache), [loader, connection](NetworkCache::MappedBody& mappedBody) {
     341            NetworkCache::singleton().store(m_networkLoad->currentRequest(), m_response, WTF::move(m_bufferedDataForCache), [loader, connection](NetworkCache::MappedBody& mappedBody) {
    328342#if ENABLE(SHAREABLE_RESOURCE)
    329343                if (mappedBody.shareableResourceHandle.isNull())
     
    333347#endif
    334348            });
    335         } else if (!hasCacheableRedirect) {
    336             // Make sure we don't keep a stale entry in the cache.
    337             NetworkCache::singleton().remove(originalRequest());
    338349        }
    339350    }
     
    372383}
    373384
    374 void NetworkResourceLoader::willSendRedirectedRequest(const ResourceRequest& request, const ResourceResponse& redirectResponse)
    375 {
    376 #if ENABLE(NETWORK_CACHE)
    377     updateRedirectChainStatus(m_redirectChainCacheStatus, redirectResponse);
    378 #endif
    379 
     385void NetworkResourceLoader::willSendRedirectedRequest(const ResourceRequest& request, const WebCore::ResourceRequest& redirectRequest, const ResourceResponse& redirectResponse)
     386{
    380387    if (isSynchronous()) {
    381         ResourceRequest overridenRequest = request;
     388        ResourceRequest overridenRequest = redirectRequest;
    382389        // FIXME: This needs to be fixed to follow the redirect correctly even for cross-domain requests.
    383390        // This includes at least updating host records, and comparing the current request instead of the original request here.
    384         if (!protocolHostAndPortAreEqual(originalRequest().url(), request.url())) {
     391        if (!protocolHostAndPortAreEqual(originalRequest().url(), redirectRequest.url())) {
    385392            ASSERT(m_synchronousLoadData->error.isNull());
    386393            m_synchronousLoadData->error = SynchronousLoaderClient::platformBadResponseError();
     
    391398        return;
    392399    }
    393     sendAbortingOnFailure(Messages::WebResourceLoader::WillSendRequest(request, redirectResponse));
    394 }
    395    
     400    sendAbortingOnFailure(Messages::WebResourceLoader::WillSendRequest(redirectRequest, redirectResponse));
     401
     402#if ENABLE(NETWORK_CACHE)
     403    if (canUseCache(request))
     404        NetworkCache::singleton().storeRedirect(request, redirectResponse, redirectRequest);
     405#else
     406    UNUSED_PARAM(request);
     407#endif
     408}
     409
    396410void NetworkResourceLoader::continueWillSendRequest(const ResourceRequest& newRequest)
    397411{
     412#if ENABLE(NETWORK_CACHE)
     413    if (m_isWaitingContinueWillSendRequestForCachedRedirect) {
     414        LOG(NetworkCache, "(NetworkProcess) Retrieving cached redirect");
     415        if (canUseCache(newRequest))
     416            retrieveCacheEntry(newRequest);
     417        else
     418            startNetworkLoad(newRequest);
     419
     420        m_isWaitingContinueWillSendRequestForCachedRedirect = false;
     421        return;
     422    }
     423#endif
    398424    m_networkLoad->continueWillSendRequest(newRequest);
    399425}
     
    464490        sendReplyToSynchronousRequest(*m_synchronousLoadData, entry->buffer());
    465491    } else {
    466         if (entry->response().url() != originalRequest().url()) {
    467             // This is a cached redirect. Synthesize a minimal redirect so we get things like referer header right.
    468             // FIXME: We should cache the actual redirects.
    469             ResourceRequest syntheticRedirectRequest(entry->response().url());
    470             ResourceResponse syntheticRedirectResponse(originalRequest().url(), { }, 0, { });
    471             sendAbortingOnFailure(Messages::WebResourceLoader::WillSendRequest(syntheticRedirectRequest, syntheticRedirectResponse));
    472         }
    473 
    474492        bool needsContinueDidReceiveResponseMessage = originalRequest().requester() == ResourceRequest::Requester::Main;
    475493        sendAbortingOnFailure(Messages::WebResourceLoader::DidReceiveResponse(entry->response(), needsContinueDidReceiveResponseMessage));
     
    512530    startNetworkLoad(revalidationRequest);
    513531}
     532
     533void NetworkResourceLoader::dispatchWillSendRequestForCacheEntry(std::unique_ptr<NetworkCache::Entry> entry)
     534{
     535    ASSERT(entry->redirectRequest());
     536    LOG(NetworkCache, "(NetworkProcess) Executing cached redirect");
     537
     538    sendAbortingOnFailure(Messages::WebResourceLoader::WillSendRequest(*entry->redirectRequest(), entry->response()));
     539    m_isWaitingContinueWillSendRequestForCachedRedirect = true;
     540}
    514541#endif
    515542
  • trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.h

    r193787 r194313  
    6262    NetworkLoad* networkLoad() const { return m_networkLoad.get(); }
    6363
     64#if ENABLE(NETWORK_CACHE)
     65    bool canUseCache(const WebCore::ResourceRequest&) const;
     66#endif
     67
    6468    void start();
    6569    void abort();
     
    98102    virtual void canAuthenticateAgainstProtectionSpaceAsync(const WebCore::ProtectionSpace&) override;
    99103    virtual bool isSynchronous() const override;
    100     virtual void willSendRedirectedRequest(const WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse) override;
     104    virtual void willSendRedirectedRequest(const WebCore::ResourceRequest&, const WebCore::ResourceRequest& redirectRequest, const WebCore::ResourceResponse& redirectResponse) override;
    101105    virtual ShouldContinueDidReceiveResponse didReceiveResponse(const WebCore::ResourceResponse&) override;
    102106    virtual void didReceiveBuffer(RefPtr<WebCore::SharedBuffer>&&, int reportedEncodedDataLength) override;
     
    113117
    114118#if ENABLE(NETWORK_CACHE)
     119    void retrieveCacheEntry(const WebCore::ResourceRequest&);
    115120    void didRetrieveCacheEntry(std::unique_ptr<NetworkCache::Entry>);
    116121    void validateCacheEntry(std::unique_ptr<NetworkCache::Entry>);
     122    void dispatchWillSendRequestForCacheEntry(std::unique_ptr<NetworkCache::Entry>);
    117123#endif
    118124
    119     void startNetworkLoad(const Optional<WebCore::ResourceRequest>& updatedRequest = { });
     125    void startNetworkLoad(const WebCore::ResourceRequest&);
    120126    void continueDidReceiveResponse();
    121127
     
    156162    RefPtr<WebCore::SharedBuffer> m_bufferedDataForCache;
    157163    std::unique_ptr<NetworkCache::Entry> m_cacheEntryForValidation;
    158 
    159     WebCore::RedirectChainCacheStatus m_redirectChainCacheStatus;
     164    bool m_isWaitingContinueWillSendRequestForCachedRedirect { false };
    160165#endif
    161166};
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp

    r193756 r194313  
    221221    // The request is conditional so we force revalidation from the network. We merely check the disk cache
    222222    // so we can update the cache entry.
    223     if (request.isConditional())
     223    if (request.isConditional() && !entry.redirectRequest())
    224224        return UseDecision::Validate;
    225225
     
    237237        return UseDecision::NoDueToMissingValidatorFields;
    238238
    239     return UseDecision::Validate;
     239    return entry.redirectRequest() ? UseDecision::NoDueToExpiredRedirect : UseDecision::Validate;
    240240}
    241241
     
    344344}
    345345
    346 void Cache::retrieve(const WebCore::ResourceRequest& originalRequest, const GlobalFrameID& frameID, std::function<void (std::unique_ptr<Entry>)> completionHandler)
     346void Cache::retrieve(const WebCore::ResourceRequest& request, const GlobalFrameID& frameID, std::function<void (std::unique_ptr<Entry>)> completionHandler)
    347347{
    348348    ASSERT(isEnabled());
    349     ASSERT(originalRequest.url().protocolIsInHTTPFamily());
    350 
    351     LOG(NetworkCache, "(NetworkProcess) retrieving %s priority %d", originalRequest.url().string().ascii().data(), static_cast<int>(originalRequest.priority()));
     349    ASSERT(request.url().protocolIsInHTTPFamily());
     350
     351    LOG(NetworkCache, "(NetworkProcess) retrieving %s priority %d", request.url().string().ascii().data(), static_cast<int>(request.priority()));
    352352
    353353    if (m_statistics)
    354354        m_statistics->recordRetrievalRequest(frameID.first);
    355355
    356     Key storageKey = makeCacheKey(originalRequest);
     356    Key storageKey = makeCacheKey(request);
    357357
    358358#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
    359359    if (m_speculativeLoadManager)
    360         m_speculativeLoadManager->registerLoad(frameID, originalRequest, storageKey);
    361 #endif
    362 
    363     auto retrieveDecision = makeRetrieveDecision(originalRequest);
     360        m_speculativeLoadManager->registerLoad(frameID, request, storageKey);
     361#endif
     362
     363    auto retrieveDecision = makeRetrieveDecision(request);
    364364    if (retrieveDecision != RetrieveDecision::Yes) {
    365365        if (m_statistics)
    366             m_statistics->recordNotUsingCacheForRequest(frameID.first, storageKey, originalRequest, retrieveDecision);
     366            m_statistics->recordNotUsingCacheForRequest(frameID.first, storageKey, request, retrieveDecision);
    367367
    368368        completionHandler(nullptr);
     
    371371
    372372#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
    373     if (m_speculativeLoadManager && m_speculativeLoadManager->retrieve(frameID, storageKey, [originalRequest, completionHandler](std::unique_ptr<Entry> entry) {
    374         if (entry && verifyVaryingRequestHeaders(entry->varyingRequestHeaders(), originalRequest))
     373    if (m_speculativeLoadManager && m_speculativeLoadManager->retrieve(frameID, storageKey, [request, completionHandler](std::unique_ptr<Entry> entry) {
     374        if (entry && verifyVaryingRequestHeaders(entry->varyingRequestHeaders(), request))
    375375            completionHandler(WTF::move(entry));
    376376        else
     
    381381
    382382    auto startTime = std::chrono::system_clock::now();
    383     auto priority = static_cast<unsigned>(originalRequest.priority());
    384 
    385     m_storage->retrieve(storageKey, priority, [this, originalRequest, completionHandler, startTime, storageKey, frameID](std::unique_ptr<Storage::Record> record) {
     383    auto priority = static_cast<unsigned>(request.priority());
     384
     385    m_storage->retrieve(storageKey, priority, [this, request, completionHandler, startTime, storageKey, frameID](std::unique_ptr<Storage::Record> record) {
    386386        if (!record) {
    387387            LOG(NetworkCache, "(NetworkProcess) not found in storage");
    388388
    389389            if (m_statistics)
    390                 m_statistics->recordRetrievalFailure(frameID.first, storageKey, originalRequest);
     390                m_statistics->recordRetrievalFailure(frameID.first, storageKey, request);
    391391
    392392            completionHandler(nullptr);
     
    398398        auto entry = Entry::decodeStorageRecord(*record);
    399399
    400         auto useDecision = entry ? makeUseDecision(*entry, originalRequest) : UseDecision::NoDueToDecodeFailure;
     400        auto useDecision = entry ? makeUseDecision(*entry, request) : UseDecision::NoDueToDecodeFailure;
    401401        switch (useDecision) {
    402402        case UseDecision::Use:
     
    411411#if !LOG_DISABLED
    412412        auto elapsedMS = static_cast<int64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - startTime).count());
    413         LOG(NetworkCache, "(NetworkProcess) retrieve complete useDecision=%d priority=%d time=%" PRIi64 "ms", static_cast<int>(useDecision), static_cast<int>(originalRequest.priority()), elapsedMS);
     413        LOG(NetworkCache, "(NetworkProcess) retrieve complete useDecision=%d priority=%d time=%" PRIi64 "ms", static_cast<int>(useDecision), static_cast<int>(request.priority()), elapsedMS);
    414414#endif
    415415        completionHandler(WTF::move(entry));
    416416
    417417        if (m_statistics)
    418             m_statistics->recordRetrievedCachedEntry(frameID.first, storageKey, originalRequest, useDecision);
     418            m_statistics->recordRetrievedCachedEntry(frameID.first, storageKey, request, useDecision);
    419419        return useDecision != UseDecision::NoDueToDecodeFailure;
    420420    });
    421421}
    422422
    423 std::unique_ptr<Entry> Cache::store(const WebCore::ResourceRequest& originalRequest, const WebCore::ResourceResponse& response, RefPtr<WebCore::SharedBuffer>&& responseData, std::function<void (MappedBody&)> completionHandler)
     423std::unique_ptr<Entry> Cache::store(const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response, RefPtr<WebCore::SharedBuffer>&& responseData, std::function<void (MappedBody&)> completionHandler)
    424424{
    425425    ASSERT(isEnabled());
    426426    ASSERT(responseData);
    427427
    428 #if !LOG_DISABLED
    429 #if ENABLE(CACHE_PARTITIONING)
    430     CString partition = originalRequest.cachePartition().latin1();
    431 #else
    432     CString partition = "No partition";
    433 #endif
    434     LOG(NetworkCache, "(NetworkProcess) storing %s, partition %s", originalRequest.url().string().latin1().data(), partition.data());
    435 #endif // !LOG_DISABLED
    436 
    437     StoreDecision storeDecision = makeStoreDecision(originalRequest, response);
     428    LOG(NetworkCache, "(NetworkProcess) storing %s, partition %s", request.url().string().latin1().data(), makeCacheKey(request).partition().latin1().data());
     429
     430    StoreDecision storeDecision = makeStoreDecision(request, response);
    438431    if (storeDecision != StoreDecision::Yes) {
    439432        LOG(NetworkCache, "(NetworkProcess) didn't store, storeDecision=%d", static_cast<int>(storeDecision));
    440         auto key = makeCacheKey(originalRequest);
     433        auto key = makeCacheKey(request);
    441434
    442435        auto isSuccessfulRevalidation = response.httpStatusCode() == 304;
     
    452445    }
    453446
    454     std::unique_ptr<Entry> cacheEntry = std::make_unique<Entry>(makeCacheKey(originalRequest), response, WTF::move(responseData), collectVaryingRequestHeaders(originalRequest, response));
     447    std::unique_ptr<Entry> cacheEntry = std::make_unique<Entry>(makeCacheKey(request), response, WTF::move(responseData), collectVaryingRequestHeaders(request, response));
    455448
    456449    auto record = cacheEntry->encodeAsStorageRecord();
     
    469462    });
    470463
     464    return cacheEntry;
     465}
     466
     467std::unique_ptr<Entry> Cache::storeRedirect(const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& redirectRequest)
     468{
     469    ASSERT(isEnabled());
     470
     471    LOG(NetworkCache, "(NetworkProcess) storing redirect %s -> %s", request.url().string().latin1().data(), redirectRequest.url().string().latin1().data());
     472
     473    StoreDecision storeDecision = makeStoreDecision(request, response);
     474    if (storeDecision != StoreDecision::Yes) {
     475        LOG(NetworkCache, "(NetworkProcess) didn't store redirect, storeDecision=%d", static_cast<int>(storeDecision));
     476        auto key = makeCacheKey(request);
     477        if (m_statistics)
     478            m_statistics->recordNotCachingResponse(key, storeDecision);
     479
     480        return nullptr;
     481    }
     482
     483    std::unique_ptr<Entry> cacheEntry = std::make_unique<Entry>(makeCacheKey(request), response, redirectRequest, collectVaryingRequestHeaders(request, response));
     484
     485    auto record = cacheEntry->encodeAsStorageRecord();
     486
     487    m_storage->store(record, nullptr);
     488   
    471489    return cacheEntry;
    472490}
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h

    r192328 r194313  
    8383    NoDueToMissingValidatorFields,
    8484    NoDueToDecodeFailure,
     85    NoDueToExpiredRedirect,
    8586};
    8687
     
    105106    void retrieve(const WebCore::ResourceRequest&, const GlobalFrameID&, std::function<void (std::unique_ptr<Entry>)>);
    106107    std::unique_ptr<Entry> store(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, RefPtr<WebCore::SharedBuffer>&&, std::function<void (MappedBody&)>);
     108    std::unique_ptr<Entry> storeRedirect(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, const WebCore::ResourceRequest& redirectRequest);
    107109    std::unique_ptr<Entry> update(const WebCore::ResourceRequest&, const GlobalFrameID&, const Entry&, const WebCore::ResourceResponse& validatingResponse);
    108110
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.cpp

    r192328 r194313  
    5050}
    5151
     52Entry::Entry(const Key& key, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& redirectRequest, const Vector<std::pair<String, String>>& varyingRequestHeaders)
     53    : m_key(key)
     54    , m_timeStamp(std::chrono::system_clock::now())
     55    , m_response(response)
     56    , m_varyingRequestHeaders(varyingRequestHeaders)
     57    , m_redirectRequest(WebCore::ResourceRequest::adopt(redirectRequest.copyData())) // Don't include the underlying platform request object.
     58{
     59    ASSERT(m_key.type() == "resource");
     60    // Redirect body is not needed even if exists.
     61    m_redirectRequest->setHTTPBody(nullptr);
     62}
     63
    5264Entry::Entry(const Entry& other)
    5365    : m_key(other.m_key)
     
    7890        encoder << m_varyingRequestHeaders;
    7991
     92    bool isRedirect = !!m_redirectRequest;
     93    encoder << isRedirect;
     94    if (isRedirect)
     95        m_redirectRequest->encodeWithoutPlatformData(encoder);
     96
    8097    encoder.encodeChecksum();
    8198
     
    103120    if (hasVaryingRequestHeaders) {
    104121        if (!decoder.decode(entry->m_varyingRequestHeaders))
     122            return nullptr;
     123    }
     124
     125    bool isRedirect;
     126    if (!decoder.decode(isRedirect))
     127        return nullptr;
     128
     129    if (isRedirect) {
     130        entry->m_redirectRequest = std::make_unique<WebCore::ResourceRequest>();
     131        if (!entry->m_redirectRequest->decodeWithoutPlatformData(decoder))
    105132            return nullptr;
    106133    }
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.h

    r192328 r194313  
    3131#include "NetworkCacheStorage.h"
    3232#include "ShareableResource.h"
     33#include <WebCore/ResourceRequest.h>
    3334#include <WebCore/ResourceResponse.h>
    3435#include <wtf/Noncopyable.h>
     
    3637
    3738namespace WebCore {
    38 class ResourceRequest;
    3939class SharedBuffer;
    4040}
     
    4747public:
    4848    Entry(const Key&, const WebCore::ResourceResponse&, RefPtr<WebCore::SharedBuffer>&&, const Vector<std::pair<String, String>>& varyingRequestHeaders);
     49    Entry(const Key&, const WebCore::ResourceResponse&, const WebCore::ResourceRequest& redirectRequest, const Vector<std::pair<String, String>>& varyingRequestHeaders);
    4950    explicit Entry(const Storage::Record&);
    5051    Entry(const Entry&);
     
    5960
    6061    WebCore::SharedBuffer* buffer() const;
     62    const WebCore::ResourceRequest* redirectRequest() const { return m_redirectRequest.get(); }
     63
    6164#if ENABLE(SHAREABLE_RESOURCE)
    6265    ShareableResource::Handle& shareableResourceHandle() const;
     
    8184    Vector<std::pair<String, String>> m_varyingRequestHeaders;
    8285
     86    std::unique_ptr<WebCore::ResourceRequest> m_redirectRequest;
    8387    mutable RefPtr<WebCore::SharedBuffer> m_buffer;
    8488#if ENABLE(SHAREABLE_RESOURCE)
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp

    r192328 r194313  
    6464}
    6565
    66 void SpeculativeLoad::willSendRedirectedRequest(const ResourceRequest& request, const ResourceResponse& redirectResponse)
     66void SpeculativeLoad::willSendRedirectedRequest(const ResourceRequest& request, const ResourceRequest& redirectRequest, const ResourceResponse& redirectResponse)
    6767{
    6868    updateRedirectChainStatus(m_redirectChainCacheStatus, redirectResponse);
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.h

    r193787 r194313  
    5555    virtual void canAuthenticateAgainstProtectionSpaceAsync(const WebCore::ProtectionSpace&) override { }
    5656    virtual bool isSynchronous() const override { return false; }
    57     virtual void willSendRedirectedRequest(const WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse) override;
     57    virtual void willSendRedirectedRequest(const WebCore::ResourceRequest&, const WebCore::ResourceRequest& redirectRequest, const WebCore::ResourceResponse& redirectResponse) override;
    5858    virtual ShouldContinueDidReceiveResponse didReceiveResponse(const WebCore::ResourceResponse&) override;
    5959    virtual void didReceiveBuffer(RefPtr<WebCore::SharedBuffer>&&, int reportedEncodedDataLength) override;
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatistics.cpp

    r191377 r194313  
    281281        return WebCore::DiagnosticLoggingKeys::missingValidatorFieldsKey();
    282282    case UseDecision::NoDueToDecodeFailure:
     283    case UseDecision::NoDueToExpiredRedirect:
    283284        return WebCore::DiagnosticLoggingKeys::otherKey();
    284285    case UseDecision::Use:
Note: See TracChangeset for help on using the changeset viewer.