Changeset 244248 in webkit


Ignore:
Timestamp:
Apr 14, 2019 1:52:46 PM (5 years ago)
Author:
commit-queue@webkit.org
Message:

Link prefetch not useful for top-level navigation
https://bugs.webkit.org/show_bug.cgi?id=195623

Patch by Rob Buis <rbuis@igalia.com> on 2019-04-14
Reviewed by Youenn Fablet.

Source/WebCore:

Cache cross-domain top-level prefetches in a dedicated cache and not in the
memory cache. Ignore prefetches for content extension checks.

Tests: http/tests/cache/link-prefetch-main-resource-iframe.html

http/tests/cache/link-prefetch-main-resource.html

  • loader/LinkLoader.cpp:

(WebCore::LinkLoader::prefetchIfNeeded):

  • loader/ResourceLoadInfo.cpp:

(WebCore::toResourceType):

  • loader/ResourceLoadInfo.h:
  • loader/ResourceLoader.cpp:

(WebCore::ResourceLoader::willSendRequestInternal):

  • loader/cache/CachedResourceLoader.cpp:

(WebCore::CachedResourceLoader::requestResource):

Source/WebKit:

Cache cross-domain top-level prefetches in a dedicated cache. When a navigation
to the same url is done within a threshold (5 seconds), reuse the
prefetch cache entry, move it to the disk cache and navigate to
the url, meaning no extra network trip is needed. When not used within
the threshold period, the prefetch entry will be erased using a timer.

  • NetworkProcess/NetworkProcess.cpp:

(WebKit::NetworkProcess::lowMemoryHandler):

  • NetworkProcess/NetworkProcess.h:

(WebKit::NetworkProcess::prefetchCache):

  • NetworkProcess/NetworkResourceLoader.cpp:

(WebKit::NetworkResourceLoader::retrieveCacheEntry):
(WebKit::NetworkResourceLoader::didReceiveResponse):
(WebKit::NetworkResourceLoader::didReceiveBuffer):
(WebKit::NetworkResourceLoader::tryStoreAsCacheEntry):
(WebKit::NetworkResourceLoader::isCrossOriginPrefetch const):

  • NetworkProcess/NetworkResourceLoader.h:
  • NetworkProcess/cache/PrefetchCache.cpp: Added.

(WebKit::PrefetchCache::Entry::Entry):
(WebKit::PrefetchCache::PrefetchCache):
(WebKit::PrefetchCache::~PrefetchCache):
(WebKit::PrefetchCache::clear):
(WebKit::PrefetchCache::take):
(WebKit::PrefetchCache::store):
(WebKit::PrefetchCache::sessionPrefetchMap const):
(WebKit::PrefetchCache::clearExpiredEntries):

  • NetworkProcess/cache/PrefetchCache.h: Added.

(WebKit::PrefetchCache::Entry::response const):
(WebKit::PrefetchCache::Entry::releaseBuffer):

  • Shared/WebPreferences.yaml:
  • Sources.txt:
  • WebKit.xcodeproj/project.pbxproj:

LayoutTests:

Verify that prefetching a cross-domain top-level main resource
is cached in the prefetch cache and only loaded once, and that non
top-level prefetches keep the old behavior.

  • http/tests/cache/link-prefetch-main-resource-expected.txt: Added.
  • http/tests/cache/link-prefetch-main-resource-iframe-expected.txt: Added.
  • http/tests/cache/link-prefetch-main-resource-iframe.html: Added.
  • http/tests/cache/link-prefetch-main-resource.html: Added.
  • http/tests/cache/resources/prefetched-main-resource-iframe.php: Added.
  • http/tests/cache/resources/prefetched-main-resource.php: Added.
  • platform/mac-wk1/TestExpectations:
  • platform/win/TestExpectations:
Location:
trunk
Files:
8 added
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r244231 r244248  
     12019-04-14  Rob Buis  <rbuis@igalia.com>
     2
     3        Link prefetch not useful for top-level navigation
     4        https://bugs.webkit.org/show_bug.cgi?id=195623
     5
     6        Reviewed by Youenn Fablet.
     7
     8        Verify that prefetching a cross-domain top-level main resource
     9        is cached in the prefetch cache and only loaded once, and that non
     10        top-level prefetches keep the old behavior.
     11
     12        * http/tests/cache/link-prefetch-main-resource-expected.txt: Added.
     13        * http/tests/cache/link-prefetch-main-resource-iframe-expected.txt: Added.
     14        * http/tests/cache/link-prefetch-main-resource-iframe.html: Added.
     15        * http/tests/cache/link-prefetch-main-resource.html: Added.
     16        * http/tests/cache/resources/prefetched-main-resource-iframe.php: Added.
     17        * http/tests/cache/resources/prefetched-main-resource.php: Added.
     18        * platform/mac-wk1/TestExpectations:
     19        * platform/win/TestExpectations:
     20
    1212019-04-12  Ross Kirsling  <ross.kirsling@sony.com>
    222
  • trunk/LayoutTests/platform/mac-wk1/TestExpectations

    r244219 r244248  
    708708
    709709webkit.org/b/196502 media/video-background-tab-playback.html [ Pass Failure ]
     710
     711webkit.org/b/195623 http/tests/cache/link-prefetch-main-resource.html [ Skip ]
     712webkit.org/b/195623 http/tests/cache/link-prefetch-main-resource-iframe.html [ Skip ]
  • trunk/LayoutTests/platform/win/TestExpectations

    r244227 r244248  
    43314331webkit.org/b/196869 legacy-animation-engine/animations/animation-multiple-callbacks-timestamp.html [ Failure ]
    43324332webkit.org/b/196869 imported/mozilla/css-animations/test_animation-currenttime.html [ Failure ]
     4333
     4334webkit.org/b/195623 http/tests/cache/link-prefetch-main-resource.html [ Skip ]
     4335webkit.org/b/195623 http/tests/cache/link-prefetch-main-resource-iframe.html [ Skip ]
  • trunk/Source/WebCore/ChangeLog

    r244247 r244248  
     12019-04-14  Rob Buis  <rbuis@igalia.com>
     2
     3        Link prefetch not useful for top-level navigation
     4        https://bugs.webkit.org/show_bug.cgi?id=195623
     5
     6        Reviewed by Youenn Fablet.
     7
     8        Cache cross-domain top-level prefetches in a dedicated cache and not in the
     9        memory cache. Ignore prefetches for content extension checks.
     10
     11        Tests: http/tests/cache/link-prefetch-main-resource-iframe.html
     12               http/tests/cache/link-prefetch-main-resource.html
     13
     14        * loader/LinkLoader.cpp:
     15        (WebCore::LinkLoader::prefetchIfNeeded):
     16        * loader/ResourceLoadInfo.cpp:
     17        (WebCore::toResourceType):
     18        * loader/ResourceLoadInfo.h:
     19        * loader/ResourceLoader.cpp:
     20        (WebCore::ResourceLoader::willSendRequestInternal):
     21        * loader/cache/CachedResourceLoader.cpp:
     22        (WebCore::CachedResourceLoader::requestResource):
     23
    1242019-04-14  Dean Jackson  <dino@apple.com>
    225
  • trunk/Source/WebCore/loader/LinkLoader.cpp

    r239427 r244248  
    277277        m_cachedLinkResource = nullptr;
    278278    }
     279    // FIXME: Add further prefetch restrictions/limitations:
     280    // - third-party iframes cannot trigger prefetches
     281    // - Number of prefetches of a given page is limited (to 1 maybe?)
    279282    ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions();
    280283    options.contentSecurityPolicyImposition = ContentSecurityPolicyImposition::SkipPolicyCheck;
     284    options.certificateInfoPolicy = CertificateInfoPolicy::IncludeCertificateInfo;
     285    options.credentials = FetchOptions::Credentials::SameOrigin;
     286    options.redirect = FetchOptions::Redirect::Manual;
     287    options.mode = FetchOptions::Mode::Navigate;
     288    options.serviceWorkersMode = ServiceWorkersMode::None;
     289    options.cachingPolicy = CachingPolicy::DisallowCaching;
    281290    m_cachedLinkResource = document.cachedResourceLoader().requestLinkResource(type, CachedResourceRequest(ResourceRequest(document.completeURL(href)), options, priority)).value_or(nullptr);
    282291    if (m_cachedLinkResource)
  • trunk/Source/WebCore/loader/ResourceLoadInfo.cpp

    r239069 r244248  
    6969#endif
    7070    case CachedResource::Type::LinkPrefetch:
    71         ASSERT_NOT_REACHED();
    72         break;
     71        return ResourceType::Prefetch;
    7372#if ENABLE(APPLICATION_MANIFEST)
    7473    case CachedResource::Type::ApplicationManifest:
  • trunk/Source/WebCore/loader/ResourceLoadInfo.h

    r238771 r244248  
    4343    PlugInStream = 0x0100,
    4444    Popup = 0x0200,
     45    Prefetch = 0x0400,
    4546};
    46 const uint16_t ResourceTypeMask = 0x03FF;
     47const uint16_t ResourceTypeMask = 0x07FF;
    4748
    4849enum class LoadType : uint16_t {
  • trunk/Source/WebCore/loader/ResourceLoader.cpp

    r243319 r244248  
    343343    ASSERT(!m_reachedTerminalState);
    344344#if ENABLE(CONTENT_EXTENSIONS)
    345     ASSERT(m_resourceType != ResourceType::Invalid);
     345    ASSERT(m_resourceType != ResourceType::Invalid || m_resourceType == ResourceType::Prefetch);
    346346#endif
    347347
     
    354354
    355355#if ENABLE(CONTENT_EXTENSIONS)
    356     if (!redirectResponse.isNull() && frameLoader()) {
     356    if (!redirectResponse.isNull() && frameLoader() && m_resourceType != ResourceType::Prefetch) {
    357357        Page* page = frameLoader()->frame().page();
    358358        if (page && m_documentLoader) {
  • trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp

    r243459 r244248  
    807807
    808808#if ENABLE(CONTENT_EXTENSIONS)
    809     if (frame() && frame()->page() && m_documentLoader) {
     809    if (frame() && frame()->page() && m_documentLoader && type != CachedResource::Type::LinkPrefetch) {
    810810        const auto& resourceRequest = request.resourceRequest();
    811811        auto* page = frame()->page();
  • trunk/Source/WebKit/ChangeLog

    r244246 r244248  
     12019-04-14  Rob Buis  <rbuis@igalia.com>
     2
     3        Link prefetch not useful for top-level navigation
     4        https://bugs.webkit.org/show_bug.cgi?id=195623
     5
     6        Reviewed by Youenn Fablet.
     7
     8        Cache cross-domain top-level prefetches in a dedicated cache. When a navigation
     9        to the same url is done within a threshold (5 seconds), reuse the
     10        prefetch cache entry, move it to the disk cache and navigate to
     11        the url, meaning no extra network trip is needed. When not used within
     12        the threshold period, the prefetch entry will be erased using a timer.
     13
     14        * NetworkProcess/NetworkProcess.cpp:
     15        (WebKit::NetworkProcess::lowMemoryHandler):
     16        * NetworkProcess/NetworkProcess.h:
     17        (WebKit::NetworkProcess::prefetchCache):
     18        * NetworkProcess/NetworkResourceLoader.cpp:
     19        (WebKit::NetworkResourceLoader::retrieveCacheEntry):
     20        (WebKit::NetworkResourceLoader::didReceiveResponse):
     21        (WebKit::NetworkResourceLoader::didReceiveBuffer):
     22        (WebKit::NetworkResourceLoader::tryStoreAsCacheEntry):
     23        (WebKit::NetworkResourceLoader::isCrossOriginPrefetch const):
     24        * NetworkProcess/NetworkResourceLoader.h:
     25        * NetworkProcess/cache/PrefetchCache.cpp: Added.
     26        (WebKit::PrefetchCache::Entry::Entry):
     27        (WebKit::PrefetchCache::PrefetchCache):
     28        (WebKit::PrefetchCache::~PrefetchCache):
     29        (WebKit::PrefetchCache::clear):
     30        (WebKit::PrefetchCache::take):
     31        (WebKit::PrefetchCache::store):
     32        (WebKit::PrefetchCache::sessionPrefetchMap const):
     33        (WebKit::PrefetchCache::clearExpiredEntries):
     34        * NetworkProcess/cache/PrefetchCache.h: Added.
     35        (WebKit::PrefetchCache::Entry::response const):
     36        (WebKit::PrefetchCache::Entry::releaseBuffer):
     37        * Shared/WebPreferences.yaml:
     38        * Sources.txt:
     39        * WebKit.xcodeproj/project.pbxproj:
     40
    1412019-04-14  Andy Estes  <aestes@apple.com>
    242
  • trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp

    r244225 r244248  
    271271
    272272    WTF::releaseFastMallocFreeMemory();
     273
     274    m_prefetchCache.clear();
    273275}
    274276
  • trunk/Source/WebKit/NetworkProcess/NetworkProcess.h

    r244097 r244248  
    3232#include "NetworkContentRuleListManager.h"
    3333#include "NetworkHTTPSUpgradeChecker.h"
     34#include "PrefetchCache.h"
    3435#include "SandboxExtension.h"
    3536#include "WebResourceLoadStatisticsStore.h"
     
    331332    WebCore::StorageQuotaManager& storageQuotaManager(PAL::SessionID, const WebCore::ClientOrigin&);
    332333
     334    PrefetchCache& prefetchCache() { return m_prefetchCache; }
     335
    333336private:
    334337    void platformInitializeNetworkProcess(const NetworkProcessCreationParameters&);
     
    552555    HashMap<PAL::SessionID, StorageQuotaManagers> m_storageQuotaManagers;
    553556    uint32_t m_downloadMonitorSpeedMultiplier { 1 };
     557
     558    PrefetchCache m_prefetchCache;
    554559};
    555560
  • trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp

    r244225 r244248  
    213213
    214214    RefPtr<NetworkResourceLoader> loader(this);
     215    if (isMainFrameLoad() && m_parameters.options.mode == FetchOptions::Mode::Navigate) {
     216        if (auto entry = m_connection->networkProcess().prefetchCache().take(sessionID(), request.url()))
     217            m_cache->store(request, entry->response, entry->releaseBuffer(), nullptr);
     218    }
    215219    m_cache->retrieve(request, { m_parameters.webPageID, m_parameters.webFrameID }, [this, loader = WTFMove(loader), request = ResourceRequest { request }](auto entry, auto info) mutable {
    216220        if (loader->hasOneRef()) {
     
    462466    }
    463467
     468    if (isCrossOriginPrefetch(originalRequest())) {
     469        send(Messages::WebResourceLoader::DidReceiveResponse { ResourceResponse { }, false });
     470        return completionHandler(PolicyAction::Use);
     471    }
    464472    // We wait to receive message NetworkResourceLoader::ContinueDidReceiveResponse before continuing a load for
    465473    // a main resource because the embedding client must decide whether to allow the load.
     
    488496            m_bufferedDataForCache = nullptr;
    489497    }
     498    if (isCrossOriginPrefetch(originalRequest()))
     499        return;
    490500    // FIXME: At least on OS X Yosemite we always get -1 from the resource handle.
    491501    unsigned encodedDataLength = reportedEncodedDataLength >= 0 ? reportedEncodedDataLength : buffer->size();
     
    770780        return;
    771781
     782    if (isCrossOriginPrefetch(originalRequest())) {
     783        m_connection->networkProcess().prefetchCache().store(sessionID(), m_networkLoad->currentRequest().url(), WTFMove(m_response), WTFMove(m_bufferedDataForCache));
     784        return;
     785    }
    772786    m_cache->store(m_networkLoad->currentRequest(), m_response, WTFMove(m_bufferedDataForCache), [loader = makeRef(*this)](auto& mappedBody) mutable {
    773787#if ENABLE(SHAREABLE_RESOURCE)
     
    11001114}
    11011115
     1116bool NetworkResourceLoader::isCrossOriginPrefetch(const ResourceRequest& request) const
     1117{
     1118    return request.httpHeaderField(HTTPHeaderName::Purpose) == "prefetch" && !m_parameters.sourceOrigin->canRequest(request.url());
     1119}
     1120
    11021121} // namespace WebKit
    11031122
  • trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.h

    r241317 r244248  
    104104    bool isMainResource() const { return m_parameters.request.requester() == WebCore::ResourceRequest::Requester::Main; }
    105105    bool isMainFrameLoad() const { return isMainResource() && m_parameters.frameAncestorOrigins.isEmpty(); }
     106    bool isCrossOriginPrefetch(const WebCore::ResourceRequest&) const;
    106107
    107108    bool isAlwaysOnLoggingAllowed() const;
  • trunk/Source/WebKit/Shared/WebPreferences.yaml

    r244239 r244248  
    16451645  type: bool
    16461646
     1647LinkPrefetchEnabled:
     1648  type: bool
     1649  defaultValue: false
     1650  humanReadableName: "LinkPrefetch"
     1651  humanReadableDescription: "Enable LinkedPrefetch"
     1652  webcoreBinding: RuntimeEnabledFeatures
     1653  category: experimental
     1654
    16471655# Deprecated
    16481656
  • trunk/Source/WebKit/Sources.txt

    r243319 r244248  
    8181NetworkProcess/cache/NetworkCacheStorage.cpp
    8282NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp
     83NetworkProcess/cache/PrefetchCache.cpp
    8384
    8485NetworkProcess/webrtc/NetworkMDNSRegister.cpp
  • trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj

    r244218 r244248  
    13311331                A78CCDDC193AC9FB005ECC25 /* com.apple.WebKit.WebContent.sb in CopyFiles */ = {isa = PBXBuildFile; fileRef = A78CCDD9193AC9E3005ECC25 /* com.apple.WebKit.WebContent.sb */; };
    13321332                A7D792D81767CCA300881CBE /* ActivityAssertion.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D792D41767CB0900881CBE /* ActivityAssertion.h */; };
     1333                AAB145E6223F931200E489D8 /* PrefetchCache.h in Headers */ = {isa = PBXBuildFile; fileRef = AAB145E4223F931200E489D8 /* PrefetchCache.h */; };
    13331334                B62E7312143047B00069EC35 /* WKHitTestResult.h in Headers */ = {isa = PBXBuildFile; fileRef = B62E7311143047B00069EC35 /* WKHitTestResult.h */; settings = {ATTRIBUTES = (Private, ); }; };
    13341335                B878B615133428DC006888E9 /* CorrectionPanel.h in Headers */ = {isa = PBXBuildFile; fileRef = B878B613133428DC006888E9 /* CorrectionPanel.h */; };
     
    39723973                A7D792D51767CB6E00881CBE /* ActivityAssertion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActivityAssertion.cpp; sourceTree = "<group>"; };
    39733974                A7E93CEB192531AA00A1DC48 /* AuxiliaryProcessIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AuxiliaryProcessIOS.mm; path = ios/AuxiliaryProcessIOS.mm; sourceTree = "<group>"; };
     3975                AAB145E4223F931200E489D8 /* PrefetchCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrefetchCache.h; sourceTree = "<group>"; };
     3976                AAB145E5223F931200E489D8 /* PrefetchCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrefetchCache.cpp; sourceTree = "<group>"; };
    39743977                B396EA5512E0ED2D00F4FEB7 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
    39753978                B62E730F143047A60069EC35 /* WKHitTestResult.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKHitTestResult.cpp; sourceTree = "<group>"; };
     
    89308933                                8310428A1BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.cpp */,
    89318934                                831042891BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.h */,
     8935                                AAB145E5223F931200E489D8 /* PrefetchCache.cpp */,
     8936                                AAB145E4223F931200E489D8 /* PrefetchCache.h */,
    89328937                        );
    89338938                        path = cache;
     
    94079412                                1A6FB7AF11E64B6800DB1371 /* PluginView.h in Headers */,
    94089413                                83A0ED351F747CCF003299EB /* PreconnectTask.h in Headers */,
     9414                                AAB145E6223F931200E489D8 /* PrefetchCache.h in Headers */,
    94099415                                E1CC1B9012D7EADF00625838 /* PrintInfo.h in Headers */,
    94109416                                86F9536518FF58F5001DB2EF /* ProcessAssertion.h in Headers */,
Note: See TracChangeset for help on using the changeset viewer.