Reviewers: kouhei, yhirano, hiroshige, Kunihiko Sakamoto, toyoshim
CL:
https://codereview.chromium.org/2390583002/Message:
This is the tentative implementation based on the design notes
(
https://docs.google.com/a/chromium.org/document/d/1vaGzhJyfR6ozSiMfphdOrwrca51MNVRT6K2r5M1xtlE/edit?usp=sharing)
and previous offline discussions, PTAL.
Changes to RemoteFontFaceSource are not yet included.
Description:
WIP: Cache-aware FontResource loading
In cache-aware loading, we attempt to load the resource from disk cache by
setting WebCachePolicy to ReturnCacheDataDontLoad. If the load failed,
ResourceClients are notified by callback, and the request is resent with
original cache policy. Here we enable cache-aware loading for FontResources by
default.
Note: ReturnCacheDataDontLoad maps to net::LOAD_ONLY_FROM_CACHE which may return
stale data, changes in net are required to support loading from disk cache with
validation.
Affected files (+90, -0 lines):
M third_party/WebKit/Source/core/css/CSSFontFaceSrcValue.cpp
M third_party/WebKit/Source/core/fetch/Resource.h
M third_party/WebKit/Source/core/fetch/Resource.cpp
M third_party/WebKit/Source/core/fetch/ResourceClient.h
M third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
M third_party/WebKit/Source/platform/network/ResourceRequest.h
M third_party/WebKit/Source/platform/network/ResourceRequest.cpp
Index: third_party/WebKit/Source/core/css/CSSFontFaceSrcValue.cpp
diff --git a/third_party/WebKit/Source/core/css/CSSFontFaceSrcValue.cpp b/third_party/WebKit/Source/core/css/CSSFontFaceSrcValue.cpp
index 6a88cbe223d3a28d1510ec6cb5bf1bc2700cdbaf..fb8e7b5e567bebac0b87ab76c76c47b0d48aa73c 100644
--- a/third_party/WebKit/Source/core/css/CSSFontFaceSrcValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSFontFaceSrcValue.cpp
@@ -88,6 +88,7 @@ FontResource* CSSFontFaceSrcValue::fetch(Document* document) const {
if (!m_fetched) {
FetchRequest request(ResourceRequest(m_absoluteResource),
FetchInitiatorTypeNames::css);
+ request.mutableResourceRequest().setIsCacheAwareLoadingEnabled(true);
request.setContentSecurityCheck(m_shouldCheckContentSecurityPolicy);
SecurityOrigin* securityOrigin = document->getSecurityOrigin();
setCrossOriginAccessControl(request, securityOrigin);
Index: third_party/WebKit/Source/core/fetch/Resource.cpp
diff --git a/third_party/WebKit/Source/core/fetch/Resource.cpp b/third_party/WebKit/Source/core/fetch/Resource.cpp
index 9d88d0191a75c2bba0f1e63d567acc4874e14f93..b31394ae2d01f01a881bf94082a09743a43f30d2 100644
--- a/third_party/WebKit/Source/core/fetch/Resource.cpp
+++ b/third_party/WebKit/Source/core/fetch/Resource.cpp
@@ -312,6 +312,7 @@ Resource::Resource(const ResourceRequest& request,
m_linkPreload(false),
m_isRevalidating(false),
m_isAlive(false),
+ m_isAddClientProhibited(false),
m_options(options),
m_responseTimestamp(currentTime()),
m_cancelTimer(this, &Resource::cancelTimerFired),
@@ -686,6 +687,8 @@ void Resource::willAddClientOrObserver(PreloadReferencePolicy policy) {
void Resource::addClient(ResourceClient* client,
PreloadReferencePolicy policy) {
+ DCHECK(!m_isAddClientProhibited);
+
willAddClientOrObserver(policy);
if (m_isRevalidating) {
@@ -1074,4 +1077,15 @@ bool Resource::isLoadEventBlockingResourceType() const {
return false;
}
+void Resource::willReloadAfterDiskCacheMiss() {
+ m_resourceRequest.deactivateCacheAwareLoading();
+
+ m_isAddClientProhibited = true;
+ ResourceClientWalker<ResourceClient> w(m_clients);
+ while (ResourceClient* c = w.next()) {
+ c->willReloadAfterDiskCacheMiss(this);
+ }
+ m_isAddClientProhibited = false;
+}
+
} // namespace blink
Index: third_party/WebKit/Source/core/fetch/Resource.h
diff --git a/third_party/WebKit/Source/core/fetch/Resource.h b/third_party/WebKit/Source/core/fetch/Resource.h
index 08f24c01b62c5fa797af8745a5788313364e4668..5c97dfa3d5bfa1b696708935e7241077e0e7360a 100644
--- a/third_party/WebKit/Source/core/fetch/Resource.h
+++ b/third_party/WebKit/Source/core/fetch/Resource.h
@@ -35,6 +35,7 @@
#include "platform/network/ResourceResponse.h"
#include "platform/scheduler/CancellableTaskFactory.h"
#include "platform/web_process_memory_dump.h"
+#include "public/platform/WebCachePolicy.h"
#include "public/platform/WebDataConsumerHandle.h"
#include "wtf/Allocator.h"
#include "wtf/HashCountedSet.h"
@@ -286,6 +287,13 @@ class CORE_EXPORT Resource : public GarbageCollectedFinalized<Resource>,
virtual bool canReuse(const ResourceRequest&) const { return true; }
+ virtual void willReloadAfterDiskCacheMiss();
+
+ // TODO(632580): Workaround to persist cache-aware state, remove after fixed.
+ void setResourceRequest(const ResourceRequest& resourceRequest) {
+ m_resourceRequest = resourceRequest;
+ }
+
// Used by the MemoryCache to reduce the memory consumption of the entry.
void prune();
@@ -409,6 +417,8 @@ class CORE_EXPORT Resource : public GarbageCollectedFinalized<Resource>,
bool m_isRevalidating : 1;
bool m_isAlive : 1;
+ bool m_isAddClientProhibited : 1;
+
// Ordered list of all redirects followed while fetching this resource.
Vector<RedirectPair> m_redirectChain;
Index: third_party/WebKit/Source/core/fetch/ResourceClient.h
diff --git a/third_party/WebKit/Source/core/fetch/ResourceClient.h b/third_party/WebKit/Source/core/fetch/ResourceClient.h
index f75dd04d45ee58eb8ae5429cff552226b124d8c8..76cc1cceb1df0a577377f4ac6d71707c910b3650 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceClient.h
+++ b/third_party/WebKit/Source/core/fetch/ResourceClient.h
@@ -52,6 +52,8 @@ class CORE_EXPORT ResourceClient : public GarbageCollectedMixin {
return BaseResourceType;
}
+ virtual void willReloadAfterDiskCacheMiss(Resource*) {}
+
// Name for debugging, e.g. shown in memory-infra.
virtual String debugName() const = 0;
Index: third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
index aab6e32f909db869ae8dbc90db1b6bae95c83f27..ac0881ea45584084e232cd4c99ed10c8374b9e5a 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
+++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
@@ -1108,6 +1108,16 @@ void ResourceFetcher::didFinishLoading(Resource* resource,
void ResourceFetcher::didFailLoading(Resource* resource,
const ResourceError& error) {
+ if (resource->resourceRequest().isCacheAwareLoadingActivated()) {
+ // Assume error.errorCode() == net::ERR_CACHE_MISS, resend request with
+ // existing ResourceLoader.
+ resource->willReloadAfterDiskCacheMiss();
+ resource->loader()->start(resource->resourceRequest(),
+ context().loadingTaskRunner(),
+ context().defersLoading());
+ return;
+ }
+
TRACE_EVENT_ASYNC_END0("
blink.net", "Resource", resource->identifier());
removeResourceLoader(resource->loader());
m_resourceTimingInfoMap.take(const_cast<Resource*>(resource));
@@ -1220,6 +1230,9 @@ bool ResourceFetcher::startLoad(Resource* resource) {
if (sourceOrigin && sourceOrigin->hasSuborigin())
request.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All);
+ // TODO(632580): Workaround to persist cache-aware state, remove after fixed.
+ resource->setResourceRequest(request);
+
ResourceLoader* loader = ResourceLoader::create(this, resource);
if (resource->shouldBlockLoadEvent())
m_loaders.add(loader);
@@ -1332,6 +1345,7 @@ void ResourceFetcher::willSendRequest(unsigned long identifier,
const ResourceLoaderOptions& options) {
context().dispatchWillSendRequest(identifier, newRequest, redirectResponse,
options.initiatorInfo);
+ newRequest.mayActivateCacheAwareLoading();
}
void ResourceFetcher::updateAllImageResourcePriorities() {
Index: third_party/WebKit/Source/platform/network/ResourceRequest.cpp
diff --git a/third_party/WebKit/Source/platform/network/ResourceRequest.cpp b/third_party/WebKit/Source/platform/network/ResourceRequest.cpp
index dd9afd70463b65ca5578de5a29332df80b5968fd..4c6596d666b7ccee5ee559a0d36f0c5ebc2708d9 100644
--- a/third_party/WebKit/Source/platform/network/ResourceRequest.cpp
+++ b/third_party/WebKit/Source/platform/network/ResourceRequest.cpp
@@ -88,6 +88,9 @@ ResourceRequest::ResourceRequest(CrossThreadResourceRequestData* data)
m_uiStartTime = data->m_uiStartTime;
m_isExternalRequest = data->m_isExternalRequest;
m_inputPerfMetricReportPolicy = data->m_inputPerfMetricReportPolicy;
+ m_isCacheAwareLoadingEnabled = data->m_isCacheAwareLoadingEnabled;
+ m_isCacheAwareLoadingActivated = data->m_isCacheAwareLoadingActivated;
+ m_savedCachePolicy = data->m_savedCachePolicy;
m_redirectStatus = data->m_redirectStatus;
}
@@ -136,6 +139,9 @@ std::unique_ptr<CrossThreadResourceRequestData> ResourceRequest::copyData()
data->m_uiStartTime = m_uiStartTime;
data->m_isExternalRequest = m_isExternalRequest;
data->m_inputPerfMetricReportPolicy = m_inputPerfMetricReportPolicy;
+ data->m_isCacheAwareLoadingEnabled = m_isCacheAwareLoadingEnabled;
+ data->m_isCacheAwareLoadingActivated = m_isCacheAwareLoadingActivated;
+ data->m_savedCachePolicy = m_savedCachePolicy;
data->m_redirectStatus = m_redirectStatus;
return data;
}
@@ -387,6 +393,25 @@ bool ResourceRequest::hasCacheValidatorFields() const {
!m_httpHeaderFields.get(HTTPNames::ETag).isEmpty();
}
+void ResourceRequest::mayActivateCacheAwareLoading() {
+ if (!m_isCacheAwareLoadingEnabled)
+ return;
+
+ if (m_cachePolicy == WebCachePolicy::BypassingCache ||
+ m_cachePolicy == WebCachePolicy::ReturnCacheDataDontLoad)
+ return;
+
+ m_savedCachePolicy = m_cachePolicy;
+ m_cachePolicy = WebCachePolicy::ReturnCacheDataDontLoad;
+ m_isCacheAwareLoadingActivated = true;
+}
+
+void ResourceRequest::deactivateCacheAwareLoading() {
+ DCHECK(m_isCacheAwareLoadingActivated);
+ m_cachePolicy = m_savedCachePolicy;
+ m_isCacheAwareLoadingActivated = false;
+}
+
void ResourceRequest::initialize(const KURL& url) {
m_url = url;
m_cachePolicy = WebCachePolicy::UseProtocolCachePolicy;
@@ -419,6 +444,9 @@ void ResourceRequest::initialize(const KURL& url) {
m_inputPerfMetricReportPolicy = InputToLoadPerfMetricReportPolicy::NoReport;
m_redirectStatus = RedirectStatus::NoRedirect;
m_requestorOrigin = SecurityOrigin::createUnique();
+ m_isCacheAwareLoadingEnabled = false;
+ m_isCacheAwareLoadingActivated = false;
+ m_savedCachePolicy = WebCachePolicy::UseProtocolCachePolicy;
}
} // namespace blink
Index: third_party/WebKit/Source/platform/network/ResourceRequest.h
diff --git a/third_party/WebKit/Source/platform/network/ResourceRequest.h b/third_party/WebKit/Source/platform/network/ResourceRequest.h
index 8682a497ea5430af68372f09f248e4434df41c3a..c3efd40fcbb5b9a05a40b7c515e7c4f7e1ad6f1f 100644
--- a/third_party/WebKit/Source/platform/network/ResourceRequest.h
+++ b/third_party/WebKit/Source/platform/network/ResourceRequest.h
@@ -302,6 +302,21 @@ class PLATFORM_EXPORT ResourceRequest final {
void setRedirectStatus(RedirectStatus status) { m_redirectStatus = status; }
RedirectStatus redirectStatus() const { return m_redirectStatus; }
+ bool isCacheAwareLoadingEnabled() const {
+ return m_isCacheAwareLoadingEnabled;
+ }
+
+ void setIsCacheAwareLoadingEnabled(bool isCacheAwareLoadingEnabled) {
+ m_isCacheAwareLoadingEnabled = isCacheAwareLoadingEnabled;
+ }
+
+ bool isCacheAwareLoadingActivated() const {
+ return m_isCacheAwareLoadingActivated;
+ }
+
+ void mayActivateCacheAwareLoading();
+ void deactivateCacheAwareLoading();
+
private:
void initialize(const KURL&);
@@ -343,6 +358,9 @@ class PLATFORM_EXPORT ResourceRequest final {
double m_uiStartTime;
bool m_isExternalRequest;
InputToLoadPerfMetricReportPolicy m_inputPerfMetricReportPolicy;
+ bool m_isCacheAwareLoadingEnabled;
+ bool m_isCacheAwareLoadingActivated;
+ WebCachePolicy m_savedCachePolicy;
mutable CacheControlHeader m_cacheControlHeaderCache;
@@ -392,6 +410,9 @@ struct CrossThreadResourceRequestData {
double m_uiStartTime;
bool m_isExternalRequest;
InputToLoadPerfMetricReportPolicy m_inputPerfMetricReportPolicy;
+ bool m_isCacheAwareLoadingEnabled;
+ bool m_isCacheAwareLoadingActivated;
+ WebCachePolicy m_savedCachePolicy;
ResourceRequest::RedirectStatus m_redirectStatus;
};