Changeset 211894 in webkit


Ignore:
Timestamp:
Feb 8, 2017 1:11:32 PM (7 years ago)
Author:
Antti Koivisto
Message:

Allow speculative redirects
https://bugs.webkit.org/show_bug.cgi?id=167982

Reviewed by Andreas Kling.

If speculative loader hits a redirect it will drop it on the floor. We should use it instead.

  • NetworkProcess/NetworkResourceLoader.cpp:

(WebKit::NetworkResourceLoader::continueWillSendRequest):
(WebKit::NetworkResourceLoader::dispatchWillSendRequestForCacheEntry):

Reset m_isWaitingContinueWillSendRequestForCachedRedirect bit immediately.

  • NetworkProcess/cache/NetworkCache.cpp:

(WebKit::NetworkCache::Cache::makeRedirectEntry):

Factor to a function.

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

  • NetworkProcess/cache/NetworkCache.h:

(WebKit::NetworkCache::Cache::speculativeLoadManager):

  • NetworkProcess/cache/NetworkCacheEntry.cpp:

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

Use std::optional instead std::unique_ptr for the redirect request.

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

  • NetworkProcess/cache/NetworkCacheEntry.h:

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

  • NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp:

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

Make a cache entry for speculative redirect.
Redirect is not actually performed, the target resource will have a separate
speculative entry.

(WebKit::NetworkCache::SpeculativeLoad::didFinishLoading):
(WebKit::NetworkCache::SpeculativeLoad::didFailLoading):
(WebKit::NetworkCache::SpeculativeLoad::didComplete):

Protect against multiple completions.

(WebKit::NetworkCache::SpeculativeLoad::abort): Deleted.

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

(WebKit::NetworkCache::SpeculativeLoadManager::retrieve):

Make successful retrieves asynchronous to avoid re-entrancy problems.

Location:
trunk/Source/WebKit2
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r211893 r211894  
     12017-02-08  Antti Koivisto  <antti@apple.com>
     2
     3        Allow speculative redirects
     4        https://bugs.webkit.org/show_bug.cgi?id=167982
     5
     6        Reviewed by Andreas Kling.
     7
     8        If speculative loader hits a redirect it will drop it on the floor. We should use it instead.
     9
     10        * NetworkProcess/NetworkResourceLoader.cpp:
     11        (WebKit::NetworkResourceLoader::continueWillSendRequest):
     12        (WebKit::NetworkResourceLoader::dispatchWillSendRequestForCacheEntry):
     13
     14            Reset m_isWaitingContinueWillSendRequestForCachedRedirect bit immediately.
     15
     16        * NetworkProcess/cache/NetworkCache.cpp:
     17        (WebKit::NetworkCache::Cache::makeRedirectEntry):
     18
     19            Factor to a function.
     20
     21        (WebKit::NetworkCache::Cache::storeRedirect):
     22        * NetworkProcess/cache/NetworkCache.h:
     23        (WebKit::NetworkCache::Cache::speculativeLoadManager):
     24        * NetworkProcess/cache/NetworkCacheEntry.cpp:
     25        (WebKit::NetworkCache::Entry::Entry):
     26
     27            Use std::optional instead std::unique_ptr for the redirect request.
     28
     29        (WebKit::NetworkCache::Entry::decodeStorageRecord):
     30        * NetworkProcess/cache/NetworkCacheEntry.h:
     31        (WebKit::NetworkCache::Entry::redirectRequest):
     32        * NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp:
     33        (WebKit::NetworkCache::SpeculativeLoad::willSendRedirectedRequest):
     34
     35            Make a cache entry for speculative redirect.
     36            Redirect is not actually performed, the target resource will have a separate
     37            speculative entry.
     38
     39        (WebKit::NetworkCache::SpeculativeLoad::didFinishLoading):
     40        (WebKit::NetworkCache::SpeculativeLoad::didFailLoading):
     41        (WebKit::NetworkCache::SpeculativeLoad::didComplete):
     42
     43            Protect against multiple completions.
     44
     45        (WebKit::NetworkCache::SpeculativeLoad::abort): Deleted.
     46        * NetworkProcess/cache/NetworkCacheSpeculativeLoad.h:
     47        * NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp:
     48        (WebKit::NetworkCache::SpeculativeLoadManager::retrieve):
     49
     50            Make successful retrieves asynchronous to avoid re-entrancy problems.
     51
    1522017-02-08  Jer Noble  <jer.noble@apple.com>
    253
  • trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp

    r211882 r211894  
    477477#if ENABLE(NETWORK_CACHE)
    478478    if (m_isWaitingContinueWillSendRequestForCachedRedirect) {
     479        m_isWaitingContinueWillSendRequestForCachedRedirect = false;
     480
    479481        LOG(NetworkCache, "(NetworkProcess) Retrieving cached redirect");
    480482
     
    484486            startNetworkLoad(newRequest);
    485487
    486         m_isWaitingContinueWillSendRequestForCachedRedirect = false;
    487488        return;
    488489    }
     
    644645{
    645646    ASSERT(entry->redirectRequest());
     647    ASSERT(!m_isWaitingContinueWillSendRequestForCachedRedirect);
     648
    646649    LOG(NetworkCache, "(NetworkProcess) Executing cached redirect");
    647650
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp

    r211882 r211894  
    396396}
    397397
     398std::unique_ptr<Entry> Cache::makeRedirectEntry(const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& redirectRequest)
     399{
     400    return std::make_unique<Entry>(makeCacheKey(request), response, redirectRequest, WebCore::collectVaryingRequestHeaders(request, response));
     401}
     402
    398403std::unique_ptr<Entry> Cache::store(const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response, RefPtr<WebCore::SharedBuffer>&& responseData, Function<void (MappedBody&)>&& completionHandler)
    399404{
     
    455460    }
    456461
    457     std::unique_ptr<Entry> cacheEntry = std::make_unique<Entry>(makeCacheKey(request), response, redirectRequest, WebCore::collectVaryingRequestHeaders(request, response));
    458 
     462    auto cacheEntry = makeRedirectEntry(request, response, redirectRequest);
    459463    auto record = cacheEntry->encodeAsStorageRecord();
    460464
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h

    r211882 r211894  
    126126   
    127127    std::unique_ptr<Entry> makeEntry(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, RefPtr<WebCore::SharedBuffer>&&);
     128    std::unique_ptr<Entry> makeRedirectEntry(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, const WebCore::ResourceRequest& redirectRequest);
    128129
    129130    void dumpContentsToFile();
    130131
    131132    String recordsPath() const;
     133
     134#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
     135    SpeculativeLoadManager* speculativeLoadManager() { return m_speculativeLoadManager.get(); }
     136#endif
    132137
    133138private:
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.cpp

    r211882 r211894  
    5555{
    5656    ASSERT(m_key.type() == "Resource");
     57
     58    m_redirectRequest.emplace();
     59    m_redirectRequest->setAsIsolatedCopy(redirectRequest);
    5760    // Redirect body is not needed even if exists.
    58 
    59     m_redirectRequest = std::make_unique<WebCore::ResourceRequest>();
    60     m_redirectRequest->setAsIsolatedCopy(redirectRequest);
    6161    m_redirectRequest->setHTTPBody(nullptr);
    6262}
     
    6767    , m_response(other.m_response)
    6868    , m_varyingRequestHeaders(other.m_varyingRequestHeaders)
     69    , m_redirectRequest(other.m_redirectRequest)
    6970    , m_buffer(other.m_buffer)
    7071    , m_sourceStorageRecord(other.m_sourceStorageRecord)
     
    130131
    131132    if (isRedirect) {
    132         entry->m_redirectRequest = std::make_unique<WebCore::ResourceRequest>();
     133        entry->m_redirectRequest.emplace();
    133134        if (!entry->m_redirectRequest->decodeWithoutPlatformData(decoder))
    134135            return nullptr;
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.h

    r211882 r211894  
    6060
    6161    WebCore::SharedBuffer* buffer() const;
    62     const WebCore::ResourceRequest* redirectRequest() const { return m_redirectRequest.get(); }
     62    const std::optional<WebCore::ResourceRequest>& redirectRequest() const { return m_redirectRequest; }
    6363
    6464#if ENABLE(SHAREABLE_RESOURCE)
     
    8484    Vector<std::pair<String, String>> m_varyingRequestHeaders;
    8585
    86     std::unique_ptr<WebCore::ResourceRequest> m_redirectRequest;
     86    std::optional<WebCore::ResourceRequest> m_redirectRequest;
    8787    mutable RefPtr<WebCore::SharedBuffer> m_buffer;
    8888#if ENABLE(SHAREABLE_RESOURCE)
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp

    r211882 r211894  
    6868}
    6969
    70 void SpeculativeLoad::willSendRedirectedRequest(ResourceRequest&&, ResourceRequest&& redirectRequest, ResourceResponse&& redirectResponse)
     70void SpeculativeLoad::willSendRedirectedRequest(ResourceRequest&& request, ResourceRequest&& redirectRequest, ResourceResponse&& redirectResponse)
    7171{
    72     LOG(NetworkCacheSpeculativePreloading, "(NetworkProcess) Speculative revalidation for %s hit a redirect, aborting the load.", redirectResponse.url().string().utf8().data());
    73     // We drop speculative revalidations if they redirect for now as we would need to notify WebCore of such redirects.
    74     abort();
     72    LOG(NetworkCacheSpeculativePreloading, "Speculative redirect %s -> %s", request.url().string().utf8().data(), redirectRequest.url().string().utf8().data());
     73
     74    m_cacheEntry = NetworkCache::singleton().storeRedirect(request, redirectResponse, redirectRequest);
     75    // Create a synthetic cache entry if we can't store.
     76    if (!m_cacheEntry)
     77        m_cacheEntry = NetworkCache::singleton().makeRedirectEntry(request, redirectResponse, redirectRequest);
     78
     79    auto load = WTFMove(m_networkLoad);
     80
     81    // Don't follow the redirect. The redirect target will be registered for speculative load when it is loaded.
     82    didComplete();
     83
     84    // This causes call to didFailLoading().
     85    if (load)
     86        load->continueWillSendRequest({ });
    7587}
    7688
     
    107119void SpeculativeLoad::didFinishLoading(double finishTime)
    108120{
     121    if (m_didComplete)
     122        return;
    109123    if (!m_cacheEntry && m_bufferedDataForCache) {
    110         m_cacheEntry = NetworkCache::singleton().store(m_originalRequest, m_response, WTFMove(m_bufferedDataForCache), [](auto& mappedBody) { });
     124        m_cacheEntry = NetworkCache::singleton().store(m_originalRequest, m_response, m_bufferedDataForCache.copyRef(), [](auto& mappedBody) { });
    111125        // Create a synthetic cache entry if we can't store.
    112126        if (!m_cacheEntry && m_response.httpStatusCode() == 200)
     
    126140void SpeculativeLoad::didFailLoading(const ResourceError&)
    127141{
     142    if (m_didComplete)
     143        return;
    128144    m_cacheEntry = nullptr;
    129145
    130     didComplete();
    131 }
    132 
    133 void SpeculativeLoad::abort()
    134 {
    135     if (m_networkLoad)
    136         m_networkLoad->cancel();
    137 
    138     m_cacheEntry = nullptr;
    139146    didComplete();
    140147}
     
    144151    RELEASE_ASSERT(RunLoop::isMain());
    145152
     153    if (m_didComplete)
     154        return;
     155    m_didComplete = true;
    146156    m_networkLoad = nullptr;
    147157
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.h

    r211882 r211894  
    6565    void didFailLoading(const WebCore::ResourceError&) override;
    6666
    67     void abort();
    6867    void didComplete();
    6968
     
    7877    RefPtr<WebCore::SharedBuffer> m_bufferedDataForCache;
    7978    std::unique_ptr<NetworkCache::Entry> m_cacheEntry;
     79    bool m_didComplete { false };
    8080};
    8181
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp

    r211882 r211894  
    346346{
    347347    if (auto preloadedEntry = m_preloadedEntries.take(storageKey)) {
    348         completionHandler(preloadedEntry->takeCacheEntry());
     348        RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), cacheEntry = preloadedEntry->takeCacheEntry()] () mutable {
     349            completionHandler(WTFMove(cacheEntry));
     350        });
    349351        return;
    350352    }
Note: See TracChangeset for help on using the changeset viewer.