| Index: third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
|
| diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
|
| index 2d8978511ff052a131b6b9344867777c25f2c7a8..2e644c877b061bd3de3bcdada01250e22deb8bf9 100644
|
| --- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
|
| +++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
|
| @@ -217,6 +217,101 @@ bool shouldDisallowFetchForMainFrameScript(ResourceRequest& request,
|
| isConnectionEffectively2G(effectiveConnection));
|
| }
|
|
|
| +enum class RequestMethod { kIsPost, kIsNotPost };
|
| +enum class RequestType { kIsConditional, kIsNotConditional };
|
| +enum class ResourceType { kIsMainResource, kIsNotMainResource };
|
| +
|
| +WebCachePolicy determineWebCachePolicy(RequestMethod method,
|
| + RequestType requestType,
|
| + ResourceType resourceType,
|
| + FrameLoadType loadType) {
|
| + switch (loadType) {
|
| + case FrameLoadTypeStandard:
|
| + return (requestType == RequestType::kIsConditional ||
|
| + method == RequestMethod::kIsPost)
|
| + ? WebCachePolicy::ValidatingCacheData
|
| + : WebCachePolicy::UseProtocolCachePolicy;
|
| + case FrameLoadTypeReplaceCurrentItem:
|
| + case FrameLoadTypeInitialInChildFrame:
|
| + // TODO(toyoshim): Should be the same with FrameLoadTypeStandard, but
|
| + // keep legacy logic as is. To be changed in a follow-up patch soon.
|
| + return (resourceType == ResourceType::kIsMainResource &&
|
| + (requestType == RequestType::kIsConditional ||
|
| + method == RequestMethod::kIsPost))
|
| + ? WebCachePolicy::ValidatingCacheData
|
| + : WebCachePolicy::UseProtocolCachePolicy;
|
| + case FrameLoadTypeInitialHistoryLoad:
|
| + // TODO(toyoshim): Should be the same with FrameLoadTypeBackForward, but
|
| + // keep legacy logic as is. To be changed in a follow-up patch soon.
|
| + return (resourceType == ResourceType::kIsMainResource &&
|
| + (requestType == RequestType::kIsConditional ||
|
| + method == RequestMethod::kIsPost))
|
| + ? WebCachePolicy::ValidatingCacheData
|
| + : WebCachePolicy::UseProtocolCachePolicy;
|
| + case FrameLoadTypeBackForward:
|
| + // Mutates the policy for POST requests to avoid form resubmission.
|
| + return method == RequestMethod::kIsPost
|
| + ? WebCachePolicy::ReturnCacheDataDontLoad
|
| + : WebCachePolicy::ReturnCacheDataElseLoad;
|
| + case FrameLoadTypeReload:
|
| + return WebCachePolicy::ValidatingCacheData;
|
| + case FrameLoadTypeReloadMainResource:
|
| + return resourceType == ResourceType::kIsMainResource
|
| + ? WebCachePolicy::ValidatingCacheData
|
| + : WebCachePolicy::UseProtocolCachePolicy;
|
| + case FrameLoadTypeReloadBypassingCache:
|
| + // TODO(toyoshim): Should return BypassingCache always, but keep legacy
|
| + // logic as is. To be changed in a follow-up patch soon.
|
| + return (resourceType == ResourceType::kIsMainResource &&
|
| + (requestType == RequestType::kIsConditional ||
|
| + method == RequestMethod::kIsPost))
|
| + ? WebCachePolicy::ValidatingCacheData
|
| + : WebCachePolicy::BypassingCache;
|
| + }
|
| + NOTREACHED();
|
| + return WebCachePolicy::UseProtocolCachePolicy;
|
| +}
|
| +
|
| +// TODO(toyoshim): Remove |resourceType|. See comments in
|
| +// resourceRequestCachePolicy().
|
| +WebCachePolicy determineFrameWebCachePolicy(Frame* frame,
|
| + ResourceType resourceType) {
|
| + if (!frame)
|
| + return WebCachePolicy::UseProtocolCachePolicy;
|
| + if (!frame->isLocalFrame())
|
| + return determineFrameWebCachePolicy(frame->tree().parent(), resourceType);
|
| +
|
| + // Does not propagate cache policy for subresources after the load event.
|
| + // TODO(toyoshim): We should be able to remove following parents' policy check
|
| + // if each frame has a relevant FrameLoadType for reload and history
|
| + // navigations.
|
| + if (resourceType == ResourceType::kIsNotMainResource &&
|
| + toLocalFrame(frame)->document()->loadEventFinished()) {
|
| + return WebCachePolicy::UseProtocolCachePolicy;
|
| + }
|
| +
|
| + // Respects BypassingCache rather than parent's policy.
|
| + // TODO(toyoshim): Adopt BypassingCache even for MainResource.
|
| + FrameLoadType loadType =
|
| + toLocalFrame(frame)->loader().documentLoader()->loadType();
|
| + if (resourceType == ResourceType::kIsNotMainResource &&
|
| + loadType == FrameLoadTypeReloadBypassingCache) {
|
| + return WebCachePolicy::BypassingCache;
|
| + }
|
| +
|
| + // Respects parent's policy if it has a special one.
|
| + WebCachePolicy parentPolicy =
|
| + determineFrameWebCachePolicy(frame->tree().parent(), resourceType);
|
| + if (parentPolicy != WebCachePolicy::UseProtocolCachePolicy)
|
| + return parentPolicy;
|
| +
|
| + // Otherwise, follows FrameLoadType. Use kIsNotPost, kIsNotConditional, and
|
| + // kIsNotMainResource to obtain a representative policy for the frame.
|
| + return determineWebCachePolicy(RequestMethod::kIsNotPost,
|
| + RequestType::kIsNotConditional,
|
| + ResourceType::kIsNotMainResource, loadType);
|
| +}
|
| +
|
| } // namespace
|
|
|
| FrameFetchContext::FrameFetchContext(DocumentLoader* loader, Document* document)
|
| @@ -287,118 +382,46 @@ void FrameFetchContext::addAdditionalRequestHeaders(ResourceRequest& request,
|
| request.setHTTPHeaderField("Save-Data", "on");
|
| }
|
|
|
| -CachePolicy FrameFetchContext::getCachePolicy() const {
|
| - if (m_document && m_document->loadEventFinished())
|
| - return CachePolicyVerify;
|
| -
|
| - FrameLoadType loadType = masterDocumentLoader()->loadType();
|
| - if (loadType == FrameLoadTypeReloadBypassingCache)
|
| - return CachePolicyReload;
|
| -
|
| - Frame* parentFrame = frame()->tree().parent();
|
| - if (parentFrame && parentFrame->isLocalFrame()) {
|
| - CachePolicy parentCachePolicy = toLocalFrame(parentFrame)
|
| - ->document()
|
| - ->fetcher()
|
| - ->context()
|
| - .getCachePolicy();
|
| - if (parentCachePolicy != CachePolicyVerify)
|
| - return parentCachePolicy;
|
| - }
|
| -
|
| - if (loadType == FrameLoadTypeReload)
|
| - return CachePolicyRevalidate;
|
| -
|
| - if (m_documentLoader &&
|
| - m_documentLoader->getRequest().getCachePolicy() ==
|
| - WebCachePolicy::ReturnCacheDataElseLoad)
|
| - return CachePolicyHistoryBuffer;
|
| -
|
| - // Returns CachePolicyVerify for other cases, mainly FrameLoadTypeStandard and
|
| - // FrameLoadTypeReloadMainResource. See public/web/WebFrameLoadType.h to know
|
| - // how these load types work.
|
| - return CachePolicyVerify;
|
| -}
|
| -
|
| -static WebCachePolicy memoryCachePolicyToResourceRequestCachePolicy(
|
| - const CachePolicy policy) {
|
| - if (policy == CachePolicyVerify)
|
| - return WebCachePolicy::UseProtocolCachePolicy;
|
| - if (policy == CachePolicyRevalidate)
|
| - return WebCachePolicy::ValidatingCacheData;
|
| - if (policy == CachePolicyReload)
|
| - return WebCachePolicy::BypassingCache;
|
| - if (policy == CachePolicyHistoryBuffer)
|
| - return WebCachePolicy::ReturnCacheDataElseLoad;
|
| - return WebCachePolicy::UseProtocolCachePolicy;
|
| -}
|
| -
|
| -static WebCachePolicy frameLoadTypeToWebCachePolicy(FrameLoadType type) {
|
| - if (type == FrameLoadTypeBackForward)
|
| - return WebCachePolicy::ReturnCacheDataElseLoad;
|
| - if (type == FrameLoadTypeReloadBypassingCache)
|
| - return WebCachePolicy::BypassingCache;
|
| - if (type == FrameLoadTypeReload)
|
| - return WebCachePolicy::ValidatingCacheData;
|
| - return WebCachePolicy::UseProtocolCachePolicy;
|
| -}
|
| -
|
| WebCachePolicy FrameFetchContext::resourceRequestCachePolicy(
|
| ResourceRequest& request,
|
| Resource::Type type,
|
| FetchRequest::DeferOption defer) const {
|
| DCHECK(frame());
|
| if (type == Resource::MainResource) {
|
| - FrameLoadType frameLoadType = masterDocumentLoader()->loadType();
|
| - if (request.httpMethod() == "POST" &&
|
| - frameLoadType == FrameLoadTypeBackForward)
|
| - return WebCachePolicy::ReturnCacheDataDontLoad;
|
| - if (frameLoadType == FrameLoadTypeReloadMainResource ||
|
| - request.isConditional() || request.httpMethod() == "POST")
|
| - return WebCachePolicy::ValidatingCacheData;
|
| -
|
| - WebCachePolicy policy = frameLoadTypeToWebCachePolicy(frameLoadType);
|
| - if (policy != WebCachePolicy::UseProtocolCachePolicy)
|
| - return policy;
|
| -
|
| - for (Frame* f = frame()->tree().parent(); f; f = f->tree().parent()) {
|
| - if (!f->isLocalFrame())
|
| - continue;
|
| - policy = frameLoadTypeToWebCachePolicy(
|
| - toLocalFrame(f)->loader().documentLoader()->loadType());
|
| - if (policy != WebCachePolicy::UseProtocolCachePolicy)
|
| - return policy;
|
| - }
|
| - // Returns UseProtocolCachePolicy for other cases, parent frames not having
|
| - // special kinds of FrameLoadType as they are checked inside the for loop
|
| - // above, or |frameLoadType| being FrameLoadTypeStandard. See
|
| - // public/web/WebFrameLoadType.h to know how these load types work.
|
| - return WebCachePolicy::UseProtocolCachePolicy;
|
| + const WebCachePolicy cachePolicy = determineWebCachePolicy(
|
| + request.httpMethod() == "POST" ? RequestMethod::kIsPost
|
| + : RequestMethod::kIsNotPost,
|
| + request.isConditional() ? RequestType::kIsConditional
|
| + : RequestType::kIsNotConditional,
|
| + ResourceType::kIsMainResource, masterDocumentLoader()->loadType());
|
| + // Follows the parent frame's policy.
|
| + // TODO(toyoshim): Probably, FrameLoadType for each frame should have a
|
| + // right type for reload or history navigations, and should not need to
|
| + // check parent's frame policy here. Once it has a right FrameLoadType,
|
| + // we can remove Resource::Type argument from determineFrameWebCachePolicy.
|
| + // See also crbug.com/332602.
|
| + if (cachePolicy != WebCachePolicy::UseProtocolCachePolicy)
|
| + return cachePolicy;
|
| + return determineFrameWebCachePolicy(frame()->tree().parent(),
|
| + ResourceType::kIsMainResource);
|
| }
|
|
|
| // For users on slow connections, we want to avoid blocking the parser in
|
| // the main frame on script loads inserted via document.write, since it can
|
| // add significant delays before page content is displayed on the screen.
|
| + // TODO(toyoshim): Move following logic that rewrites ResourceRequest to
|
| + // somewhere that should be relevant to the script resource handling.
|
| if (type == Resource::Script && isMainFrame() && m_document &&
|
| shouldDisallowFetchForMainFrameScript(request, defer, *m_document))
|
| return WebCachePolicy::ReturnCacheDataDontLoad;
|
|
|
| + // TODO(toyoshim): We should check isConditional() and use ValidatingCacheData
|
| + // only when |cachePolicy| below is UseProtocolCachePolicy.
|
| if (request.isConditional())
|
| return WebCachePolicy::ValidatingCacheData;
|
|
|
| - if (m_documentLoader && m_document && !m_document->loadEventFinished()) {
|
| - // For POST requests, we mutate the main resource's cache policy to avoid
|
| - // form resubmission. This policy should not be inherited by subresources.
|
| - WebCachePolicy mainResourceCachePolicy =
|
| - m_documentLoader->getRequest().getCachePolicy();
|
| - if (m_documentLoader->getRequest().httpMethod() == "POST") {
|
| - if (mainResourceCachePolicy == WebCachePolicy::ReturnCacheDataDontLoad)
|
| - return WebCachePolicy::ReturnCacheDataElseLoad;
|
| - return WebCachePolicy::UseProtocolCachePolicy;
|
| - }
|
| - return memoryCachePolicyToResourceRequestCachePolicy(getCachePolicy());
|
| - }
|
| - return WebCachePolicy::UseProtocolCachePolicy;
|
| + return determineFrameWebCachePolicy(frame(),
|
| + ResourceType::kIsNotMainResource);
|
| }
|
|
|
| // The |m_documentLoader| is null in the FrameFetchContext of an imported
|
|
|