Commit 776f59d5 authored by Ben Kelly's avatar Ben Kelly Committed by Commit Bot

CacheStorage: Support opting out of full cache cache based on headers.

This CL adds the CacheStorageCodeCacheHint blink runtime feature.  When
enabled it makes cache_storage look for a header when responses are put
on disk.  If the header specifies a value of "none" then the current
behavior of generating full code cache from the install event is
disabled for that specific response.  This blink feature is marked as
experimental.

The current header name is "x-CacheStorageCodeCacheHint", but its
configurable via a field trial param.  This will allow us to adjust the
header if we later choose a better name.

Currently code caching is not specified.  It is mainly only observable
by web content through quota size differences and timing.

Bug: 1007272
Change-Id: I21f90927f6ed59529c2efe8995cbdd855a87f3ec
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1881191
Commit-Queue: Ben Kelly <wanderview@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Reviewed-by: default avatarYutaka Hirano <yhirano@chromium.org>
Cr-Commit-Position: refs/heads/master@{#713029}
parent 92dc4154
...@@ -97,6 +97,7 @@ ...@@ -97,6 +97,7 @@
#include "storage/browser/blob/blob_reader.h" #include "storage/browser/blob/blob_reader.h"
#include "storage/browser/blob/blob_storage_context.h" #include "storage/browser/blob/blob_storage_context.h"
#include "storage/browser/test/blob_test_utils.h" #include "storage/browser/test/blob_test_utils.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h" #include "third_party/blink/public/common/loader/url_loader_throttle.h"
#include "third_party/blink/public/common/service_worker/service_worker_status_code.h" #include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/common/service_worker/service_worker_type_converters.h" #include "third_party/blink/public/common/service_worker/service_worker_type_converters.h"
...@@ -3348,6 +3349,8 @@ class ServiceWorkerV8CodeCacheForCacheStorageTest ...@@ -3348,6 +3349,8 @@ class ServiceWorkerV8CodeCacheForCacheStorageTest
} }
protected: protected:
virtual const char* GetWorkerURL() { return kWorkerUrl; }
void RegisterAndActivateServiceWorker() { void RegisterAndActivateServiceWorker() {
scoped_refptr<WorkerActivatedObserver> observer = scoped_refptr<WorkerActivatedObserver> observer =
new WorkerActivatedObserver(wrapper()); new WorkerActivatedObserver(wrapper());
...@@ -3357,7 +3360,7 @@ class ServiceWorkerV8CodeCacheForCacheStorageTest ...@@ -3357,7 +3360,7 @@ class ServiceWorkerV8CodeCacheForCacheStorageTest
blink::mojom::ScriptType::kClassic, blink::mojom::ScriptType::kClassic,
blink::mojom::ServiceWorkerUpdateViaCache::kImports); blink::mojom::ServiceWorkerUpdateViaCache::kImports);
public_context()->RegisterServiceWorker( public_context()->RegisterServiceWorker(
embedded_test_server()->GetURL(kWorkerUrl), options, embedded_test_server()->GetURL(GetWorkerURL()), options,
base::BindOnce(&ExpectResultAndRun, true, base::DoNothing())); base::BindOnce(&ExpectResultAndRun, true, base::DoNothing()));
observer->Wait(); observer->Wait();
} }
...@@ -3589,6 +3592,47 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerV8CodeCacheForCacheStorageBadOriginTest, ...@@ -3589,6 +3592,47 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerV8CodeCacheForCacheStorageBadOriginTest,
WaitUntilSideDataSizeIs(0); WaitUntilSideDataSizeIs(0);
} }
class ServiceWorkerCacheStorageFullCodeCacheFromInstallEventTest
: public ServiceWorkerV8CodeCacheForCacheStorageTest {
public:
const char* GetWorkerURL() override {
return "/service_worker/install_event_caches_script.js";
}
};
IN_PROC_BROWSER_TEST_F(
ServiceWorkerCacheStorageFullCodeCacheFromInstallEventTest,
FullCodeCacheGenerated) {
RegisterAndActivateServiceWorker();
// The full code cache should have been generated when the script was
// stored in the install event.
WaitUntilSideDataSizeIsBiggerThan(kV8CacheTimeStampDataSize);
}
class ServiceWorkerCacheStorageFullCodeCacheFromInstallEventDisabledByHintTest
: public ServiceWorkerV8CodeCacheForCacheStorageTest {
public:
ServiceWorkerCacheStorageFullCodeCacheFromInstallEventDisabledByHintTest() {}
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
"CacheStorageCodeCacheHint");
}
const char* GetWorkerURL() override {
return "/service_worker/install_event_caches_script_with_hint.js";
}
};
IN_PROC_BROWSER_TEST_F(
ServiceWorkerCacheStorageFullCodeCacheFromInstallEventDisabledByHintTest,
FullCodeCacheNotGenerated) {
RegisterAndActivateServiceWorker();
// The full code cache should not be generated when the script was
// stored in the install event and the header hint disables code cache.
WaitUntilSideDataSizeIs(0);
}
// ServiceWorkerDisableWebSecurityTests check the behavior when the web security // ServiceWorkerDisableWebSecurityTests check the behavior when the web security
// is disabled. If '--disable-web-security' flag is set, we don't check the // is disabled. If '--disable-web-security' flag is set, we don't check the
// origin equality in Blink. So the Service Worker related APIs should succeed // origin equality in Blink. So the Service Worker related APIs should succeed
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
self.addEventListener('install', evt => {
evt.waitUntil(async function() {
const cache_name = 'cache_name';
const url = '/service_worker/v8_cache_test.js'
const cache = await caches.open(cache_name);
const response = await fetch(url);
await cache.put(url, response);
}());
});
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
self.addEventListener('install', evt => {
evt.waitUntil(async function() {
const cache_name = 'cache_name';
const url = '/service_worker/v8_cache_test.js'
const cache = await caches.open(cache_name);
const orig_response = await fetch(url);
const mutable_response = new Response(orig_response.body, orig_response);
mutable_response.headers.append('x-CacheStorageCodeCacheHint', 'none');
await cache.put(url, mutable_response);
}());
});
...@@ -424,5 +424,15 @@ const base::Feature kSetDetachedWindowReasonByClosing{ ...@@ -424,5 +424,15 @@ const base::Feature kSetDetachedWindowReasonByClosing{
const base::Feature kSetDetachedWindowReasonByOtherReason{ const base::Feature kSetDetachedWindowReasonByOtherReason{
"SetDetachedWindowReasonByOtherReason", base::FEATURE_ENABLED_BY_DEFAULT}; "SetDetachedWindowReasonByOtherReason", base::FEATURE_ENABLED_BY_DEFAULT};
// When enabled allows the header name used in the blink
// CacheStorageCodeCacheHint runtime feature to be modified. This runtime
// feature disables generating full code cache for responses stored in
// cache_storage during a service worker install event. The runtime feature
// must be enabled via the blink runtime feature mechanism, however.
const base::Feature kCacheStorageCodeCacheHintHeader{
"CacheStorageCodeCacheHintHeader", base::FEATURE_DISABLED_BY_DEFAULT};
const base::FeatureParam<std::string> kCacheStorageCodeCacheHintHeaderName{
&kCacheStorageCodeCacheHintHeader, "name", "x-CacheStorageCodeCacheHint"};
} // namespace features } // namespace features
} // namespace blink } // namespace blink
...@@ -143,6 +143,10 @@ BLINK_COMMON_EXPORT extern const base::Feature ...@@ -143,6 +143,10 @@ BLINK_COMMON_EXPORT extern const base::Feature
BLINK_COMMON_EXPORT extern const base::Feature BLINK_COMMON_EXPORT extern const base::Feature
kSetDetachedWindowReasonByOtherReason; kSetDetachedWindowReasonByOtherReason;
BLINK_COMMON_EXPORT extern const base::Feature kCacheStorageCodeCacheHintHeader;
BLINK_COMMON_EXPORT extern const base::FeatureParam<std::string>
kCacheStorageCodeCacheHintHeaderName;
} // namespace features } // namespace features
} // namespace blink } // namespace blink
......
...@@ -143,6 +143,13 @@ const KURL* FetchResponseData::Url() const { ...@@ -143,6 +143,13 @@ const KURL* FetchResponseData::Url() const {
return &url_list_.back(); return &url_list_.back();
} }
FetchHeaderList* FetchResponseData::InternalHeaderList() const {
if (internal_response_) {
return internal_response_->HeaderList();
}
return HeaderList();
}
String FetchResponseData::MimeType() const { String FetchResponseData::MimeType() const {
return mime_type_; return mime_type_;
} }
......
...@@ -68,6 +68,7 @@ class CORE_EXPORT FetchResponseData final ...@@ -68,6 +68,7 @@ class CORE_EXPORT FetchResponseData final
uint16_t Status() const { return status_; } uint16_t Status() const { return status_; }
AtomicString StatusMessage() const { return status_message_; } AtomicString StatusMessage() const { return status_message_; }
FetchHeaderList* HeaderList() const { return header_list_.Get(); } FetchHeaderList* HeaderList() const { return header_list_.Get(); }
FetchHeaderList* InternalHeaderList() const;
BodyStreamBuffer* Buffer() const { return buffer_; } BodyStreamBuffer* Buffer() const { return buffer_; }
String MimeType() const; String MimeType() const;
// Returns the BodyStreamBuffer of |m_internalResponse| if any. Otherwise, // Returns the BodyStreamBuffer of |m_internalResponse| if any. Otherwise,
......
...@@ -535,6 +535,10 @@ const Vector<KURL>& Response::InternalURLList() const { ...@@ -535,6 +535,10 @@ const Vector<KURL>& Response::InternalURLList() const {
return response_->InternalURLList(); return response_->InternalURLList();
} }
FetchHeaderList* Response::InternalHeaderList() const {
return response_->InternalHeaderList();
}
void Response::Trace(blink::Visitor* visitor) { void Response::Trace(blink::Visitor* visitor) {
Body::Trace(visitor); Body::Trace(visitor);
visitor->Trace(response_); visitor->Trace(response_);
......
...@@ -119,6 +119,8 @@ class CORE_EXPORT Response final : public Body { ...@@ -119,6 +119,8 @@ class CORE_EXPORT Response final : public Body {
const Vector<KURL>& InternalURLList() const; const Vector<KURL>& InternalURLList() const;
FetchHeaderList* InternalHeaderList() const;
void Trace(blink::Visitor*) override; void Trace(blink::Visitor*) override;
protected: protected:
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/optional.h" #include "base/optional.h"
#include "services/network/public/mojom/fetch_api.mojom-blink.h" #include "services/network/public/mojom/fetch_api.mojom-blink.h"
#include "third_party/blink/public/common/cache_storage/cache_storage_utils.h" #include "third_party/blink/public/common/cache_storage/cache_storage_utils.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h" #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h" #include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h"
#include "third_party/blink/renderer/bindings/core/v8/idl_types.h" #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
...@@ -75,6 +76,30 @@ bool HasJavascriptMimeType(const Response* response) { ...@@ -75,6 +76,30 @@ bool HasJavascriptMimeType(const Response* response) {
return MIMETypeRegistry::IsSupportedJavaScriptMIMEType(mime_type); return MIMETypeRegistry::IsSupportedJavaScriptMIMEType(mime_type);
} }
enum class CodeCachePolicy {
// Use the default policy. Currently that policy generates full code cache
// when a script is stored during service worker install.
kAuto,
// Do not generate code cache when putting a script in cache_storage.
kNone,
};
CodeCachePolicy GetCodeCachePolicy(const Response* response) {
if (!RuntimeEnabledFeatures::CacheStorageCodeCacheHintEnabled())
return CodeCachePolicy::kAuto;
String header_name(
features::kCacheStorageCodeCacheHintHeaderName.Get().data());
String header_value;
if (!response->InternalHeaderList()->Get(header_name, header_value))
return CodeCachePolicy::kAuto;
if (header_value.LowerASCII() == "none")
return CodeCachePolicy::kNone;
return CodeCachePolicy::kAuto;
}
bool ShouldGenerateV8CodeCache(ScriptState* script_state, bool ShouldGenerateV8CodeCache(ScriptState* script_state,
const Response* response) { const Response* response) {
ExecutionContext* context = ExecutionContext::From(script_state); ExecutionContext* context = ExecutionContext::From(script_state);
...@@ -82,14 +107,20 @@ bool ShouldGenerateV8CodeCache(ScriptState* script_state, ...@@ -82,14 +107,20 @@ bool ShouldGenerateV8CodeCache(ScriptState* script_state,
if (!global_scope) if (!global_scope)
return false; return false;
if (!global_scope->IsInstalling()) if (!response->InternalBodyBuffer())
return false; return false;
if (!HasJavascriptMimeType(response)) if (!HasJavascriptMimeType(response))
return false; return false;
if (!response->InternalBodyBuffer()) auto policy = GetCodeCachePolicy(response);
if (policy == CodeCachePolicy::kNone)
return false; return false;
DCHECK_EQ(policy, CodeCachePolicy::kAuto);
if (!global_scope->IsInstalling())
return false;
return true; return true;
} }
......
...@@ -266,6 +266,10 @@ ...@@ -266,6 +266,10 @@
{ {
name: "CacheInlineScriptCode" name: "CacheInlineScriptCode"
}, },
{
name: "CacheStorageCodeCacheHint",
status: "experimental",
},
{ {
name: "Canvas2dContextLostRestored", name: "Canvas2dContextLostRestored",
status: "experimental", status: "experimental",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment