diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-06 12:48:11 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:33:43 +0000 |
commit | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (patch) | |
tree | fa14ba0ca8d2683ba2efdabd246dc9b18a1229c6 /chromium/third_party/blink/renderer/platform/loader/fetch | |
parent | 79b4f909db1049fca459c07cca55af56a9b54fe3 (diff) | |
download | qtwebengine-chromium-7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3.tar.gz |
BASELINE: Update Chromium to 84.0.4147.141
Change-Id: Ib85eb4cfa1cbe2b2b81e5022c8cad5c493969535
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/loader/fetch')
32 files changed, 685 insertions, 504 deletions
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/DEPS b/chromium/third_party/blink/renderer/platform/loader/fetch/DEPS index 35694fdca61..643d9d95205 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/DEPS +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/DEPS @@ -2,4 +2,5 @@ include_rules = [ "+net/dns/public", "+services/network/public/cpp/fetch_api_utils.h", "+services/network/public/cpp/optional_trust_token_params.h", + "+third_party/blink/renderer/platform/mojo", ] diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.cc index b49dc9e74a1..f9e536b3212 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.cc @@ -4,8 +4,11 @@ #include "third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.h" +#include "base/command_line.h" #include "base/macros.h" +#include "services/network/public/cpp/client_hints.h" #include "third_party/blink/public/common/client_hints/client_hints.h" +#include "third_party/blink/public/common/switches.h" #include "third_party/blink/renderer/platform/network/http_names.h" #include "third_party/blink/renderer/platform/network/http_parsers.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" @@ -15,26 +18,33 @@ namespace blink { ClientHintsPreferences::ClientHintsPreferences() { - DCHECK_EQ(static_cast<size_t>(mojom::WebClientHintsType::kMaxValue) + 1, - kClientHintsMappingsCount); + DCHECK_EQ( + static_cast<size_t>(network::mojom::WebClientHintsType::kMaxValue) + 1, + kClientHintsMappingsCount); } void ClientHintsPreferences::UpdateFrom( const ClientHintsPreferences& preferences) { for (size_t i = 0; - i < static_cast<int>(mojom::WebClientHintsType::kMaxValue) + 1; ++i) { - mojom::WebClientHintsType type = static_cast<mojom::WebClientHintsType>(i); + i < static_cast<int>(network::mojom::WebClientHintsType::kMaxValue) + 1; + ++i) { + network::mojom::WebClientHintsType type = + static_cast<network::mojom::WebClientHintsType>(i); enabled_hints_.SetIsEnabled(type, preferences.ShouldSend(type)); } } +bool ClientHintsPreferences::UserAgentClientHintEnabled() { + return RuntimeEnabledFeatures::UserAgentClientHintEnabled() && + !base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kUserAgentClientHintDisable); +} + void ClientHintsPreferences::UpdateFromAcceptClientHintsHeader( const String& header_value, const KURL& url, + UpdateMode mode, Context* context) { - if (header_value.IsEmpty()) - return; - // Client hints should be allowed only on secure URLs. if (!IsClientHintsAllowed(url)) return; @@ -47,22 +57,26 @@ void ClientHintsPreferences::UpdateFromAcceptClientHintsHeader( return; // Note: .Ascii() would convert tab to ?, which is undesirable. - base::Optional<std::vector<blink::mojom::WebClientHintsType>> parsed_ch = - ParseAcceptCH(header_value.Latin1(), - RuntimeEnabledFeatures::LangClientHintHeaderEnabled(), - RuntimeEnabledFeatures::UserAgentClientHintEnabled()); + base::Optional<std::vector<network::mojom::WebClientHintsType>> parsed_ch = + FilterAcceptCH(network::ParseAcceptCH(header_value.Latin1()), + RuntimeEnabledFeatures::LangClientHintHeaderEnabled(), + UserAgentClientHintEnabled()); if (!parsed_ch.has_value()) return; - // Note: this keeps previously enabled hints. - for (blink::mojom::WebClientHintsType newly_enabled : parsed_ch.value()) + if (mode == UpdateMode::kReplace) + enabled_hints_ = WebEnabledClientHints(); + + for (network::mojom::WebClientHintsType newly_enabled : parsed_ch.value()) enabled_hints_.SetIsEnabled(newly_enabled, true); if (context) { for (size_t i = 0; - i < static_cast<int>(mojom::WebClientHintsType::kMaxValue) + 1; ++i) { - mojom::WebClientHintsType type = - static_cast<mojom::WebClientHintsType>(i); + i < + static_cast<int>(network::mojom::WebClientHintsType::kMaxValue) + 1; + ++i) { + network::mojom::WebClientHintsType type = + static_cast<network::mojom::WebClientHintsType>(i); if (enabled_hints_.IsEnabled(type)) context->CountClientHints(type); } diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.h b/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.h index c722244370a..b010f9f3a70 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.h @@ -22,13 +22,15 @@ class PLATFORM_EXPORT ClientHintsPreferences { public: class Context { public: - virtual void CountClientHints(mojom::WebClientHintsType) = 0; + virtual void CountClientHints(network::mojom::WebClientHintsType) = 0; virtual void CountPersistentClientHintHeaders() = 0; protected: virtual ~Context() = default; }; + enum class UpdateMode { kReplace, kMerge }; + ClientHintsPreferences(); void UpdateFrom(const ClientHintsPreferences&); @@ -39,12 +41,13 @@ class PLATFORM_EXPORT ClientHintsPreferences { // |url|, then |this| would not be updated. void UpdateFromAcceptClientHintsHeader(const String& header_value, const KURL&, + UpdateMode mode, Context*); - bool ShouldSend(mojom::WebClientHintsType type) const { + bool ShouldSend(network::mojom::WebClientHintsType type) const { return enabled_hints_.IsEnabled(type); } - void SetShouldSendForTesting(mojom::WebClientHintsType type) { + void SetShouldSendForTesting(network::mojom::WebClientHintsType type) { enabled_hints_.SetIsEnabled(type, true); } @@ -60,6 +63,8 @@ class PLATFORM_EXPORT ClientHintsPreferences { // hints are allowed only on HTTP URLs that belong to secure contexts. static bool IsClientHintsAllowed(const KURL&); + static bool UserAgentClientHintEnabled(); + WebEnabledClientHints GetWebEnabledClientHints() const; base::TimeDelta GetPersistDuration() const; diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences_test.cc index 1b6afccf66a..6dad0f43fcc 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences_test.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences_test.cc @@ -61,124 +61,289 @@ TEST_F(ClientHintsPreferencesTest, BasicSecure) { SCOPED_TRACE(testing::Message() << test_case.header_value); ClientHintsPreferences preferences; const KURL kurl(String::FromUTF8("https://www.google.com/")); - preferences.UpdateFromAcceptClientHintsHeader(test_case.header_value, kurl, - nullptr); - EXPECT_EQ( - test_case.expectation_resource_width, - preferences.ShouldSend(mojom::WebClientHintsType::kResourceWidth)); + preferences.UpdateFromAcceptClientHintsHeader( + test_case.header_value, kurl, + ClientHintsPreferences::UpdateMode::kReplace, nullptr); + EXPECT_EQ(test_case.expectation_resource_width, + preferences.ShouldSend( + network::mojom::WebClientHintsType::kResourceWidth)); EXPECT_EQ(test_case.expectation_dpr, - preferences.ShouldSend(mojom::WebClientHintsType::kDpr)); - EXPECT_EQ( - test_case.expectation_viewport_width, - preferences.ShouldSend(mojom::WebClientHintsType::kViewportWidth)); + preferences.ShouldSend(network::mojom::WebClientHintsType::kDpr)); + EXPECT_EQ(test_case.expectation_viewport_width, + preferences.ShouldSend( + network::mojom::WebClientHintsType::kViewportWidth)); EXPECT_EQ(test_case.expectation_rtt, - preferences.ShouldSend(mojom::WebClientHintsType::kRtt)); - EXPECT_EQ(test_case.expectation_downlink, - preferences.ShouldSend(mojom::WebClientHintsType::kDownlink)); + preferences.ShouldSend(network::mojom::WebClientHintsType::kRtt)); + EXPECT_EQ( + test_case.expectation_downlink, + preferences.ShouldSend(network::mojom::WebClientHintsType::kDownlink)); EXPECT_EQ(test_case.expectation_ect, - preferences.ShouldSend(mojom::WebClientHintsType::kEct)); - EXPECT_EQ(test_case.expectation_lang, - preferences.ShouldSend(mojom::WebClientHintsType::kLang)); + preferences.ShouldSend(network::mojom::WebClientHintsType::kEct)); + EXPECT_EQ( + test_case.expectation_lang, + preferences.ShouldSend(network::mojom::WebClientHintsType::kLang)); EXPECT_EQ(test_case.expectation_ua, - preferences.ShouldSend(mojom::WebClientHintsType::kUA)); - EXPECT_EQ(test_case.expectation_ua_arch, - preferences.ShouldSend(mojom::WebClientHintsType::kUAArch)); - EXPECT_EQ(test_case.expectation_ua_platform, - preferences.ShouldSend(mojom::WebClientHintsType::kUAPlatform)); - EXPECT_EQ(test_case.expectation_ua_model, - preferences.ShouldSend(mojom::WebClientHintsType::kUAModel)); - - // Calling UpdateFromAcceptClientHintsHeader with empty header should have - // no impact on client hint preferences. - preferences.UpdateFromAcceptClientHintsHeader("", kurl, nullptr); + preferences.ShouldSend(network::mojom::WebClientHintsType::kUA)); EXPECT_EQ( - test_case.expectation_resource_width, - preferences.ShouldSend(mojom::WebClientHintsType::kResourceWidth)); - EXPECT_EQ(test_case.expectation_dpr, - preferences.ShouldSend(mojom::WebClientHintsType::kDpr)); + test_case.expectation_ua_arch, + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAArch)); + EXPECT_EQ(test_case.expectation_ua_platform, + preferences.ShouldSend( + network::mojom::WebClientHintsType::kUAPlatform)); EXPECT_EQ( - test_case.expectation_viewport_width, - preferences.ShouldSend(mojom::WebClientHintsType::kViewportWidth)); + test_case.expectation_ua_model, + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAModel)); // Calling UpdateFromAcceptClientHintsHeader with an invalid header should - // have no impact on client hint preferences. - preferences.UpdateFromAcceptClientHintsHeader("foobar", kurl, nullptr); - EXPECT_EQ( - test_case.expectation_resource_width, - preferences.ShouldSend(mojom::WebClientHintsType::kResourceWidth)); + // have no impact on client hint preferences, for either mode. + preferences.UpdateFromAcceptClientHintsHeader( + "1, 42,", kurl, ClientHintsPreferences::UpdateMode::kReplace, nullptr); + EXPECT_EQ(test_case.expectation_resource_width, + preferences.ShouldSend( + network::mojom::WebClientHintsType::kResourceWidth)); EXPECT_EQ(test_case.expectation_dpr, - preferences.ShouldSend(mojom::WebClientHintsType::kDpr)); - EXPECT_EQ( - test_case.expectation_viewport_width, - preferences.ShouldSend(mojom::WebClientHintsType::kViewportWidth)); + preferences.ShouldSend(network::mojom::WebClientHintsType::kDpr)); + EXPECT_EQ(test_case.expectation_viewport_width, + preferences.ShouldSend( + network::mojom::WebClientHintsType::kViewportWidth)); + + preferences.UpdateFromAcceptClientHintsHeader( + "1, 42,", kurl, ClientHintsPreferences::UpdateMode::kMerge, nullptr); + EXPECT_EQ(test_case.expectation_resource_width, + preferences.ShouldSend( + network::mojom::WebClientHintsType::kResourceWidth)); + EXPECT_EQ(test_case.expectation_dpr, + preferences.ShouldSend(network::mojom::WebClientHintsType::kDpr)); + EXPECT_EQ(test_case.expectation_viewport_width, + preferences.ShouldSend( + network::mojom::WebClientHintsType::kViewportWidth)); + + // Calling UpdateFromAcceptClientHintsHeader with empty header in merge + // mode is also a no-op. + preferences.UpdateFromAcceptClientHintsHeader( + "", kurl, ClientHintsPreferences::UpdateMode::kMerge, nullptr); + EXPECT_EQ(test_case.expectation_resource_width, + preferences.ShouldSend( + network::mojom::WebClientHintsType::kResourceWidth)); + EXPECT_EQ(test_case.expectation_dpr, + preferences.ShouldSend(network::mojom::WebClientHintsType::kDpr)); + EXPECT_EQ(test_case.expectation_viewport_width, + preferences.ShouldSend( + network::mojom::WebClientHintsType::kViewportWidth)); + + // Calling UpdateFromAcceptClientHintsHeader with empty header in replace + // mode should clear client hint preferences. + preferences.UpdateFromAcceptClientHintsHeader( + "", kurl, ClientHintsPreferences::UpdateMode::kReplace, nullptr); + EXPECT_EQ(false, preferences.ShouldSend( + network::mojom::WebClientHintsType::kResourceWidth)); + EXPECT_EQ(false, + preferences.ShouldSend(network::mojom::WebClientHintsType::kDpr)); + EXPECT_EQ(false, preferences.ShouldSend( + network::mojom::WebClientHintsType::kViewportWidth)); } } -// Verify that the set of enabled client hints is updated every time Update*() -// methods are called. -TEST_F(ClientHintsPreferencesTest, SecureEnabledTypesAreUpdated) { +// Verify that the set of enabled client hints is overwritten every time +// Update*() methods are called with replace mode. +TEST_F(ClientHintsPreferencesTest, SecureEnabledTypesReplace) { ClientHintsPreferences preferences; const KURL kurl(String::FromUTF8("https://www.google.com/")); - preferences.UpdateFromAcceptClientHintsHeader("rtt, downlink", kurl, nullptr); + preferences.UpdateFromAcceptClientHintsHeader( + "rtt, downlink", kurl, ClientHintsPreferences::UpdateMode::kReplace, + nullptr); EXPECT_EQ(base::TimeDelta(), preferences.GetPersistDuration()); + EXPECT_FALSE(preferences.ShouldSend( + network::mojom::WebClientHintsType::kResourceWidth)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kDpr)); + EXPECT_FALSE(preferences.ShouldSend( + network::mojom::WebClientHintsType::kViewportWidth)); + EXPECT_TRUE(preferences.ShouldSend(network::mojom::WebClientHintsType::kRtt)); + EXPECT_TRUE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kDownlink)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kEct)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kLang)); + EXPECT_FALSE(preferences.ShouldSend(network::mojom::WebClientHintsType::kUA)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAArch)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAPlatform)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAModel)); + + // Calling UpdateFromAcceptClientHintsHeader with an invalid header should + // have no impact on client hint preferences. + preferences.UpdateFromAcceptClientHintsHeader( + "1,,42", kurl, ClientHintsPreferences::UpdateMode::kReplace, nullptr); + EXPECT_EQ(base::TimeDelta(), preferences.GetPersistDuration()); + EXPECT_FALSE(preferences.ShouldSend( + network::mojom::WebClientHintsType::kResourceWidth)); + EXPECT_TRUE(preferences.ShouldSend(network::mojom::WebClientHintsType::kRtt)); + EXPECT_TRUE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kDownlink)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kEct)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kLang)); + EXPECT_FALSE(preferences.ShouldSend(network::mojom::WebClientHintsType::kUA)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAArch)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAPlatform)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAModel)); + + // Calling UpdateFromAcceptClientHintsHeader with "width" header should + // replace preferences with just width. + preferences.UpdateFromAcceptClientHintsHeader( + "width", kurl, ClientHintsPreferences::UpdateMode::kReplace, nullptr); + EXPECT_EQ(base::TimeDelta(), preferences.GetPersistDuration()); + EXPECT_TRUE(preferences.ShouldSend( + network::mojom::WebClientHintsType::kResourceWidth)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kRtt)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kDownlink)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kEct)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kLang)); + EXPECT_FALSE(preferences.ShouldSend(network::mojom::WebClientHintsType::kUA)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAArch)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAPlatform)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAModel)); + + // Calling UpdateFromAcceptClientHintsHeader with empty header should empty + // client hint preferences. + preferences.UpdateFromAcceptClientHintsHeader( + "", kurl, ClientHintsPreferences::UpdateMode::kReplace, nullptr); + EXPECT_EQ(base::TimeDelta(), preferences.GetPersistDuration()); + EXPECT_FALSE(preferences.ShouldSend( + network::mojom::WebClientHintsType::kResourceWidth)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kRtt)); EXPECT_FALSE( - preferences.ShouldSend(mojom::WebClientHintsType::kResourceWidth)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kDpr)); - EXPECT_FALSE( - preferences.ShouldSend(mojom::WebClientHintsType::kViewportWidth)); - EXPECT_TRUE(preferences.ShouldSend(mojom::WebClientHintsType::kRtt)); - EXPECT_TRUE(preferences.ShouldSend(mojom::WebClientHintsType::kDownlink)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kEct)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kLang)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kUA)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kUAArch)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kUAPlatform)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kUAModel)); + preferences.ShouldSend(network::mojom::WebClientHintsType::kDownlink)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kEct)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kLang)); + EXPECT_FALSE(preferences.ShouldSend(network::mojom::WebClientHintsType::kUA)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAArch)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAPlatform)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAModel)); + + preferences.UpdateFromAcceptClientHintsLifetimeHeader("1000", kurl, nullptr); + EXPECT_EQ(base::TimeDelta::FromSeconds(1000), + preferences.GetPersistDuration()); +} + +// Verify that the set of enabled client hints is merged every time +// Update*() methods are called with merge mode. +TEST_F(ClientHintsPreferencesTest, SecureEnabledTypesMerge) { + ClientHintsPreferences preferences; + const KURL kurl(String::FromUTF8("https://www.google.com/")); + preferences.UpdateFromAcceptClientHintsHeader( + "rtt, downlink", kurl, ClientHintsPreferences::UpdateMode::kMerge, + nullptr); - // Calling UpdateFromAcceptClientHintsHeader with empty header should have - // no impact on client hint preferences. - preferences.UpdateFromAcceptClientHintsHeader("", kurl, nullptr); EXPECT_EQ(base::TimeDelta(), preferences.GetPersistDuration()); + EXPECT_FALSE(preferences.ShouldSend( + network::mojom::WebClientHintsType::kResourceWidth)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kDpr)); + EXPECT_FALSE(preferences.ShouldSend( + network::mojom::WebClientHintsType::kViewportWidth)); + EXPECT_TRUE(preferences.ShouldSend(network::mojom::WebClientHintsType::kRtt)); + EXPECT_TRUE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kDownlink)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kEct)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kLang)); + EXPECT_FALSE(preferences.ShouldSend(network::mojom::WebClientHintsType::kUA)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAArch)); EXPECT_FALSE( - preferences.ShouldSend(mojom::WebClientHintsType::kResourceWidth)); - EXPECT_TRUE(preferences.ShouldSend(mojom::WebClientHintsType::kRtt)); - EXPECT_TRUE(preferences.ShouldSend(mojom::WebClientHintsType::kDownlink)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kEct)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kLang)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kUA)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kUAArch)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kUAPlatform)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kUAModel)); + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAPlatform)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAModel)); // Calling UpdateFromAcceptClientHintsHeader with an invalid header should // have no impact on client hint preferences. - preferences.UpdateFromAcceptClientHintsHeader("foobar", kurl, nullptr); + preferences.UpdateFromAcceptClientHintsHeader( + "1,,42", kurl, ClientHintsPreferences::UpdateMode::kMerge, nullptr); EXPECT_EQ(base::TimeDelta(), preferences.GetPersistDuration()); + EXPECT_FALSE(preferences.ShouldSend( + network::mojom::WebClientHintsType::kResourceWidth)); + EXPECT_TRUE(preferences.ShouldSend(network::mojom::WebClientHintsType::kRtt)); + EXPECT_TRUE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kDownlink)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kEct)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kLang)); + EXPECT_FALSE(preferences.ShouldSend(network::mojom::WebClientHintsType::kUA)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAArch)); EXPECT_FALSE( - preferences.ShouldSend(mojom::WebClientHintsType::kResourceWidth)); - EXPECT_TRUE(preferences.ShouldSend(mojom::WebClientHintsType::kRtt)); - EXPECT_TRUE(preferences.ShouldSend(mojom::WebClientHintsType::kDownlink)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kLang)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kUA)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kUAArch)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kUAPlatform)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kUAModel)); + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAPlatform)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAModel)); // Calling UpdateFromAcceptClientHintsHeader with "width" header should - // have no impact on already enabled client hint preferences. - preferences.UpdateFromAcceptClientHintsHeader("width", kurl, nullptr); + // replace add width to preferences + preferences.UpdateFromAcceptClientHintsHeader( + "width", kurl, ClientHintsPreferences::UpdateMode::kMerge, nullptr); EXPECT_EQ(base::TimeDelta(), preferences.GetPersistDuration()); + EXPECT_TRUE(preferences.ShouldSend( + network::mojom::WebClientHintsType::kResourceWidth)); + EXPECT_TRUE(preferences.ShouldSend(network::mojom::WebClientHintsType::kRtt)); EXPECT_TRUE( - preferences.ShouldSend(mojom::WebClientHintsType::kResourceWidth)); - EXPECT_TRUE(preferences.ShouldSend(mojom::WebClientHintsType::kRtt)); - EXPECT_TRUE(preferences.ShouldSend(mojom::WebClientHintsType::kDownlink)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kEct)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kLang)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kUA)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kUAArch)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kUAPlatform)); - EXPECT_FALSE(preferences.ShouldSend(mojom::WebClientHintsType::kUAModel)); + preferences.ShouldSend(network::mojom::WebClientHintsType::kDownlink)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kEct)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kLang)); + EXPECT_FALSE(preferences.ShouldSend(network::mojom::WebClientHintsType::kUA)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAArch)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAPlatform)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAModel)); + + // Calling UpdateFromAcceptClientHintsHeader with empty header should not + // change anything with the mode is merge. + preferences.UpdateFromAcceptClientHintsHeader( + "", kurl, ClientHintsPreferences::UpdateMode::kMerge, nullptr); + EXPECT_EQ(base::TimeDelta(), preferences.GetPersistDuration()); + EXPECT_TRUE(preferences.ShouldSend( + network::mojom::WebClientHintsType::kResourceWidth)); + EXPECT_TRUE(preferences.ShouldSend(network::mojom::WebClientHintsType::kRtt)); + EXPECT_TRUE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kDownlink)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kEct)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kLang)); + EXPECT_FALSE(preferences.ShouldSend(network::mojom::WebClientHintsType::kUA)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAArch)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAPlatform)); + EXPECT_FALSE( + preferences.ShouldSend(network::mojom::WebClientHintsType::kUAModel)); preferences.UpdateFromAcceptClientHintsLifetimeHeader("1000", kurl, nullptr); EXPECT_EQ(base::TimeDelta::FromSeconds(1000), @@ -191,9 +356,10 @@ TEST_F(ClientHintsPreferencesTest, Insecure) { const KURL kurl = use_secure_url ? KURL(String::FromUTF8("https://www.google.com/")) : KURL(String::FromUTF8("http://www.google.com/")); - preferences.UpdateFromAcceptClientHintsHeader("dpr", kurl, nullptr); + preferences.UpdateFromAcceptClientHintsHeader( + "dpr", kurl, ClientHintsPreferences::UpdateMode::kReplace, nullptr); EXPECT_EQ(use_secure_url, - preferences.ShouldSend(mojom::WebClientHintsType::kDpr)); + preferences.ShouldSend(network::mojom::WebClientHintsType::kDpr)); } } @@ -241,28 +407,37 @@ TEST_F(ClientHintsPreferencesTest, ParseHeaders) { ClientHintsPreferences preferences; WebEnabledClientHints enabled_types = preferences.GetWebEnabledClientHints(); + EXPECT_FALSE(enabled_types.IsEnabled( + network::mojom::WebClientHintsType::kDeviceMemory)); + EXPECT_FALSE( + enabled_types.IsEnabled(network::mojom::WebClientHintsType::kDpr)); + EXPECT_FALSE(enabled_types.IsEnabled( + network::mojom::WebClientHintsType::kResourceWidth)); + EXPECT_FALSE(enabled_types.IsEnabled( + network::mojom::WebClientHintsType::kViewportWidth)); + EXPECT_FALSE( + enabled_types.IsEnabled(network::mojom::WebClientHintsType::kRtt)); + EXPECT_FALSE( + enabled_types.IsEnabled(network::mojom::WebClientHintsType::kDownlink)); EXPECT_FALSE( - enabled_types.IsEnabled(mojom::WebClientHintsType::kDeviceMemory)); - EXPECT_FALSE(enabled_types.IsEnabled(mojom::WebClientHintsType::kDpr)); + enabled_types.IsEnabled(network::mojom::WebClientHintsType::kEct)); EXPECT_FALSE( - enabled_types.IsEnabled(mojom::WebClientHintsType::kResourceWidth)); + enabled_types.IsEnabled(network::mojom::WebClientHintsType::kLang)); EXPECT_FALSE( - enabled_types.IsEnabled(mojom::WebClientHintsType::kViewportWidth)); - EXPECT_FALSE(enabled_types.IsEnabled(mojom::WebClientHintsType::kRtt)); - EXPECT_FALSE(enabled_types.IsEnabled(mojom::WebClientHintsType::kDownlink)); - EXPECT_FALSE(enabled_types.IsEnabled(mojom::WebClientHintsType::kEct)); - EXPECT_FALSE(enabled_types.IsEnabled(mojom::WebClientHintsType::kLang)); - EXPECT_FALSE(enabled_types.IsEnabled(mojom::WebClientHintsType::kUA)); - EXPECT_FALSE(enabled_types.IsEnabled(mojom::WebClientHintsType::kUAArch)); + enabled_types.IsEnabled(network::mojom::WebClientHintsType::kUA)); EXPECT_FALSE( - enabled_types.IsEnabled(mojom::WebClientHintsType::kUAPlatform)); - EXPECT_FALSE(enabled_types.IsEnabled(mojom::WebClientHintsType::kUAModel)); + enabled_types.IsEnabled(network::mojom::WebClientHintsType::kUAArch)); + EXPECT_FALSE(enabled_types.IsEnabled( + network::mojom::WebClientHintsType::kUAPlatform)); + EXPECT_FALSE( + enabled_types.IsEnabled(network::mojom::WebClientHintsType::kUAModel)); base::TimeDelta persist_duration = preferences.GetPersistDuration(); EXPECT_EQ(base::TimeDelta(), persist_duration); const KURL kurl(String::FromUTF8("https://www.google.com/")); - preferences.UpdateFromAcceptClientHintsHeader(test.accept_ch_header_value, - kurl, nullptr); + preferences.UpdateFromAcceptClientHintsHeader( + test.accept_ch_header_value, kurl, + ClientHintsPreferences::UpdateMode::kReplace, nullptr); preferences.UpdateFromAcceptClientHintsLifetimeHeader( test.accept_lifetime_header_value, kurl, nullptr); @@ -272,33 +447,37 @@ TEST_F(ClientHintsPreferencesTest, ParseHeaders) { EXPECT_EQ(test.expect_persist_duration_seconds, persist_duration.InSeconds()); + EXPECT_EQ(test.expect_device_memory, + enabled_types.IsEnabled( + network::mojom::WebClientHintsType::kDeviceMemory)); + EXPECT_EQ(test.expect_dpr, enabled_types.IsEnabled( + network::mojom::WebClientHintsType::kDpr)); + EXPECT_EQ(test.expect_width, + enabled_types.IsEnabled( + network::mojom::WebClientHintsType::kResourceWidth)); + EXPECT_EQ(test.expect_viewport_width, + enabled_types.IsEnabled( + network::mojom::WebClientHintsType::kViewportWidth)); + EXPECT_EQ(test.expect_rtt, enabled_types.IsEnabled( + network::mojom::WebClientHintsType::kRtt)); EXPECT_EQ( - test.expect_device_memory, - enabled_types.IsEnabled(mojom::WebClientHintsType::kDeviceMemory)); - EXPECT_EQ(test.expect_dpr, - enabled_types.IsEnabled(mojom::WebClientHintsType::kDpr)); - EXPECT_EQ( - test.expect_width, - enabled_types.IsEnabled(mojom::WebClientHintsType::kResourceWidth)); - EXPECT_EQ( - test.expect_viewport_width, - enabled_types.IsEnabled(mojom::WebClientHintsType::kViewportWidth)); - EXPECT_EQ(test.expect_rtt, - enabled_types.IsEnabled(mojom::WebClientHintsType::kRtt)); - EXPECT_EQ(test.expect_downlink, - enabled_types.IsEnabled(mojom::WebClientHintsType::kDownlink)); - EXPECT_EQ(test.expect_ect, - enabled_types.IsEnabled(mojom::WebClientHintsType::kEct)); - EXPECT_EQ(test.expect_lang, - enabled_types.IsEnabled(mojom::WebClientHintsType::kLang)); + test.expect_downlink, + enabled_types.IsEnabled(network::mojom::WebClientHintsType::kDownlink)); + EXPECT_EQ(test.expect_ect, enabled_types.IsEnabled( + network::mojom::WebClientHintsType::kEct)); + EXPECT_EQ(test.expect_lang, enabled_types.IsEnabled( + network::mojom::WebClientHintsType::kLang)); EXPECT_EQ(test.expect_ua, - enabled_types.IsEnabled(mojom::WebClientHintsType::kUA)); - EXPECT_EQ(test.expect_ua_arch, - enabled_types.IsEnabled(mojom::WebClientHintsType::kUAArch)); + enabled_types.IsEnabled(network::mojom::WebClientHintsType::kUA)); + EXPECT_EQ( + test.expect_ua_arch, + enabled_types.IsEnabled(network::mojom::WebClientHintsType::kUAArch)); EXPECT_EQ(test.expect_ua_platform, - enabled_types.IsEnabled(mojom::WebClientHintsType::kUAPlatform)); - EXPECT_EQ(test.expect_ua_model, - enabled_types.IsEnabled(mojom::WebClientHintsType::kUAModel)); + enabled_types.IsEnabled( + network::mojom::WebClientHintsType::kUAPlatform)); + EXPECT_EQ( + test.expect_ua_model, + enabled_types.IsEnabled(network::mojom::WebClientHintsType::kUAModel)); } } diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.h b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.h index 916041c76e1..1be8c54a4f6 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.h @@ -54,6 +54,7 @@ namespace blink { enum class ResourceType : uint8_t; class ClientHintsPreferences; +class FeaturePolicy; class KURL; class ResourceTimingInfo; class WebScopedVirtualTimePauser; @@ -118,6 +119,7 @@ class PLATFORM_EXPORT FetchContext : public GarbageCollected<FetchContext> { } virtual base::Optional<ResourceRequestBlockedReason> CheckCSPForRequest( mojom::RequestContextType, + network::mojom::RequestDestination request_destination, const KURL&, const ResourceLoaderOptions&, ReportingDisposition, @@ -141,10 +143,14 @@ class PLATFORM_EXPORT FetchContext : public GarbageCollected<FetchContext> { return MakeGarbageCollected<FetchContext>(); } + virtual const FeaturePolicy* GetFeaturePolicy() const { return nullptr; } + // Determine if the request is on behalf of an advertisement. If so, return // true. - virtual bool CalculateIfAdSubresource(const ResourceRequest& resource_request, - ResourceType type) { + virtual bool CalculateIfAdSubresource( + const ResourceRequest& resource_request, + ResourceType type, + const FetchInitiatorInfo& initiator_info) { return false; } diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_initiator_info.h b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_initiator_info.h index 4ee9d7ceeff..9fdbb8a949b 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_initiator_info.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_initiator_info.h @@ -38,12 +38,17 @@ struct FetchInitiatorInfo { FetchInitiatorInfo() : name(), position(TextPosition::BelowRangePosition()), - is_link_preload(false) {} + is_link_preload(false), + is_imported_module(false) {} AtomicString name; TextPosition position; bool is_link_preload; - String imported_module_referrer; + bool is_imported_module; + + // Should only be set when |is_imported_module| or when |name| is + // fetch_initiator_type_names::kCSS or fetch_initiator_type_names::kUaCSS. + String referrer; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc index c57dfd3b668..6d4df25c903 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc @@ -38,7 +38,7 @@ FetchParameters::FetchParameters(ResourceRequest resource_request) decoder_options_(TextResourceDecoderOptions::kPlainTextContent), speculative_preload_type_(SpeculativePreloadType::kNotSpeculative), defer_(kNoDefer), - image_request_optimization_(kNone) {} + image_request_behavior_(kNone) {} FetchParameters::FetchParameters(ResourceRequest resource_request, const ResourceLoaderOptions& options) @@ -47,7 +47,7 @@ FetchParameters::FetchParameters(ResourceRequest resource_request, options_(options), speculative_preload_type_(SpeculativePreloadType::kNotSpeculative), defer_(kNoDefer), - image_request_optimization_(kNone) {} + image_request_behavior_(kNone) {} FetchParameters::FetchParameters(FetchParameters&&) = default; @@ -111,48 +111,14 @@ void FetchParameters::MakeSynchronous() { options_.synchronous_policy = kRequestSynchronously; } -void FetchParameters::SetLazyImagePlaceholder() { - resource_request_.SetPreviewsState(resource_request_.GetPreviewsState() | - WebURLRequest::kLazyImageLoadDeferred); - SetAllowImagePlaceholder(); -} - void FetchParameters::SetLazyImageDeferred() { - resource_request_.SetPreviewsState(resource_request_.GetPreviewsState() | - WebURLRequest::kLazyImageLoadDeferred); - DCHECK_EQ(kNone, image_request_optimization_); - image_request_optimization_ = kDeferImageLoad; -} - -void FetchParameters::SetLazyImageAutoReload() { - resource_request_.SetPreviewsState(resource_request_.GetPreviewsState() | - WebURLRequest::kLazyImageAutoReload); + DCHECK_EQ(kNone, image_request_behavior_); + image_request_behavior_ = kDeferImageLoad; } -void FetchParameters::SetAllowImagePlaceholder() { - DCHECK_EQ(kNone, image_request_optimization_); - if (!resource_request_.Url().ProtocolIsInHTTPFamily() || - resource_request_.HttpMethod() != "GET" || - !resource_request_.HttpHeaderField("range").IsNull()) { - // Make sure that the request isn't marked as using an image preview type, - // since without loading an image placeholder, Client Lo-Fi isn't really - // in use. - resource_request_.SetPreviewsState(resource_request_.GetPreviewsState() & - ~WebURLRequest::kLazyImageLoadDeferred); - return; - } - - image_request_optimization_ = kAllowPlaceholder; - - // Fetch the first few bytes of the image. This number is tuned to both (a) - // likely capture the entire image for small images and (b) likely contain - // the dimensions for larger images. - // TODO(sclittle): Calculate the optimal value for this number. - resource_request_.SetHttpHeaderField("range", "bytes=0-2047"); - - // TODO(sclittle): Indicate somehow (e.g. through a new request bit) to the - // embedder that it should return the full resource if the entire resource is - // fresh in the cache. +void FetchParameters::SetLazyImageNonBlocking() { + // TODO(domfarolino): [Before merging]: can we DCHECK here. + image_request_behavior_ = kNonBlockingImage; } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h index a1e29fbe9b6..b2adcf02184 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h @@ -56,12 +56,13 @@ class PLATFORM_EXPORT FetchParameters { kInDocument, // The request was discovered in the main document kInserted // The request was discovered in a document.write() }; - enum ImageRequestOptimization { + enum ImageRequestBehavior { kNone = 0, // No optimization. - kAllowPlaceholder, // The image is allowed to be a placeholder. - kDeferImageLoad, // Defer loading the image from network. Full image might - // still load if the request is already-loaded or in - // memory cache. + kDeferImageLoad, // Defer loading the image from network. Full image + // might still load if the request is already-loaded or + // in memory cache. + kNonBlockingImage // The image load may continue, but must be placed in + // ResourceFetcher::non_blocking_loaders_. }; struct ResourceWidth { DISALLOW_NEW(); @@ -179,21 +180,13 @@ class PLATFORM_EXPORT FetchParameters { void MakeSynchronous(); - ImageRequestOptimization GetImageRequestOptimization() const { - return image_request_optimization_; + ImageRequestBehavior GetImageRequestBehavior() const { + return image_request_behavior_; } - // Configures the request to load an image as a placeholder or defers the - // image and sets the lazy image load bit. - void SetLazyImagePlaceholder(); + // Configures the request to defer the image and set the lazy image load bit. void SetLazyImageDeferred(); - void SetLazyImageAutoReload(); - - // Configures the request to load an image placeholder if the request is - // eligible (e.g. the url's protocol is HTTP, etc.). If this request is - // non-eligible, this method doesn't modify the ResourceRequest. Calling this - // method sets image_request_optimization_ to the appropriate value. - void SetAllowImagePlaceholder(); + void SetLazyImageNonBlocking(); // See documentation in blink::ResourceRequest. bool IsFromOriginDirtyStyleSheet() const { @@ -218,7 +211,7 @@ class PLATFORM_EXPORT FetchParameters { DeferOption defer_; ResourceWidth resource_width_; ClientHintsPreferences client_hint_preferences_; - ImageRequestOptimization image_request_optimization_; + ImageRequestBehavior image_request_behavior_; bool is_stale_revalidation_ = false; bool is_from_origin_dirty_style_sheet_ = false; }; diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/loading_attribute_value.h b/chromium/third_party/blink/renderer/platform/loader/fetch/loading_attribute_value.h new file mode 100644 index 00000000000..34302e0af99 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/loading_attribute_value.h @@ -0,0 +1,18 @@ +// Copyright 2020 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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_LOADING_ATTRIBUTE_VALUE_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_LOADING_ATTRIBUTE_VALUE_H_ + +namespace blink { + +enum class LoadingAttributeValue { + kAuto, + kLazy, + kEager, +}; + +} // namespace blink + +#endif diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc index f43766d2fcd..90f489445b7 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc @@ -71,7 +71,7 @@ void MemoryCacheEntry::Trace(Visitor* visitor) { MemoryCacheEntry, &MemoryCacheEntry::ClearResourceWeak>(this); } -void MemoryCacheEntry::ClearResourceWeak(const WeakCallbackInfo& info) { +void MemoryCacheEntry::ClearResourceWeak(const LivenessBroker& info) { if (!resource_ || info.IsHeapObjectAlive(resource_)) return; GetMemoryCache()->Remove(resource_.Get()); diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.h b/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.h index d797ba16873..9ade4a0c74a 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache.h @@ -55,8 +55,9 @@ class MemoryCacheEntry final : public GarbageCollected<MemoryCacheEntry> { Resource* GetResource() const { return resource_; } private: - void ClearResourceWeak(const WeakCallbackInfo&); + void ClearResourceWeak(const LivenessBroker&); + // We use UntracedMember<> here to do custom weak processing. UntracedMember<Resource> resource_; }; diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h b/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h index e5d2d6f5863..0a2433b1e0f 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h @@ -44,6 +44,7 @@ class PLATFORM_EXPORT NullResourceFetcherProperties final return scheduler::FrameStatus::kNone; } const KURL& WebBundlePhysicalUrl() const override; + int GetOutstandingThrottledLimit() const override { return 0; } private: const Member<const FetchClientSettingsObject> fetch_client_settings_object_; diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc index 449d18c456b..e4725807ea0 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc @@ -350,15 +350,10 @@ void RawResource::DidDownloadToBlob(scoped_refptr<BlobDataHandle> blob) { c->DidDownloadToBlob(this, blob); } -bool RawResource::MatchPreload(const FetchParameters& params, - base::SingleThreadTaskRunner* task_runner) { - if (!Resource::MatchPreload(params, task_runner)) - return false; - +void RawResource::MatchPreload(const FetchParameters& params) { + Resource::MatchPreload(params); matched_with_non_streaming_destination_ = !params.GetResourceRequest().UseStreamOnResponse(); - - return true; } static bool ShouldIgnoreHeaderForCacheReuse(AtomicString header_name) { diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.h b/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.h index 3a22921c1f3..f6d5e482e33 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.h @@ -128,8 +128,7 @@ class PLATFORM_EXPORT RawResource final : public Resource { uint64_t total_bytes_to_be_sent) override; void DidDownloadData(uint64_t) override; void DidDownloadToBlob(scoped_refptr<BlobDataHandle>) override; - bool MatchPreload(const FetchParameters&, - base::SingleThreadTaskRunner*) override; + void MatchPreload(const FetchParameters&) override; scoped_refptr<BlobDataHandle> downloaded_blob_; diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc index a469fe6ae20..f4085622ad2 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc @@ -255,7 +255,8 @@ TEST_F(RawResourceTest, PreloadWithAsynchronousAddClient) { FetchParameters params(std::move(request)); params.MutableResourceRequest().SetUseStreamOnResponse(false); - raw->MatchPreload(params, platform_->test_task_runner().get()); + raw->MatchPreload(params); + EXPECT_FALSE(raw->IsUnusedPreload()); raw->AddClient(dummy_client, platform_->test_task_runner().get()); raw->ResponseBodyReceived(*body_loader, platform_->test_task_runner()); diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc index d7c24f32f9e..08c2b41d79e 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc @@ -1017,11 +1017,9 @@ void Resource::MarkAsPreload() { is_unused_preload_ = true; } -bool Resource::MatchPreload(const FetchParameters& params, - base::SingleThreadTaskRunner*) { +void Resource::MatchPreload(const FetchParameters& params) { DCHECK(is_unused_preload_); is_unused_preload_ = false; - return true; } bool Resource::CanReuseRedirectChain() const { diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource.h index 4dc121198b8..70f2b412cb8 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource.h @@ -66,7 +66,6 @@ class CachedMetadataHandler; class CachedMetadataSender; class FetchParameters; class ResourceClient; -class ResourceFetcher; class ResourceFinishObserver; class ResourceLoader; class ResponseBodyLoaderDrainableInterface; @@ -144,15 +143,6 @@ class PLATFORM_EXPORT Resource : public GarbageCollected<Resource>, // Match fails due to different request headers. kRequestHeadersDoNotMatch, - - // Match fails due to different image placeholder policies. - kImagePlaceholder, - }; - - // Used by reloadIfLoFiOrPlaceholderImage(). - enum ReloadLoFiOrPlaceholderPolicy { - kReloadIfNeeded, - kReloadAlways, }; ~Resource() override; @@ -295,8 +285,7 @@ class PLATFORM_EXPORT Resource : public GarbageCollected<Resource>, void MarkAsPreload(); // Returns true if |this| resource is matched with the given parameters. - virtual bool MatchPreload(const FetchParameters&, - base::SingleThreadTaskRunner*); + virtual void MatchPreload(const FetchParameters&); bool CanReuseRedirectChain() const; bool MustRevalidateDueToCacheHeaders(bool allow_stale) const; @@ -380,12 +369,6 @@ class PLATFORM_EXPORT Resource : public GarbageCollected<Resource>, virtual void OnMemoryDump(WebMemoryDumpLevelOfDetail, WebProcessMemoryDump*) const; - // If this Resource is ImageResource and has the Lo-Fi response headers or is - // a placeholder, reload the full original image with the Lo-Fi state set to - // off and optionally bypassing the cache. - virtual void ReloadIfLoFiOrPlaceholderImage(ResourceFetcher*, - ReloadLoFiOrPlaceholderPolicy) {} - // Used to notify ImageResourceContent of the start of actual loading. // JavaScript calls or client/observer notifications are disallowed inside // NotifyStartLoad(). diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.cc index a6706847ef4..efee303d37e 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.cc @@ -26,13 +26,16 @@ #include "third_party/blink/renderer/platform/loader/fetch/resource_error.h" +#include "base/strings/string_number_conversions.h" #include "net/base/net_errors.h" +#include "services/network/public/mojom/trust_tokens.mojom-blink-forward.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/resource_request_blocked_reason.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/platform/web_url_error.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" +#include "third_party/blink/renderer/platform/loader/fetch/trust_token_params_conversion.h" namespace blink { @@ -101,7 +104,8 @@ ResourceError::ResourceError(const WebURLError& error) is_access_check_(error.is_web_security_violation()), has_copy_in_cache_(error.has_copy_in_cache()), cors_error_status_(error.cors_error_status()), - blocked_by_response_reason_(error.blocked_by_response_reason()) { + blocked_by_response_reason_(error.blocked_by_response_reason()), + trust_token_operation_error_(error.trust_token_operation_error()) { DCHECK_NE(error_code_, 0); InitializeDescription(); } @@ -114,6 +118,7 @@ ResourceError ResourceError::Copy() const { error_copy.has_copy_in_cache_ = has_copy_in_cache_; error_copy.localized_description_ = localized_description_.IsolatedCopy(); error_copy.is_access_check_ = is_access_check_; + error_copy.trust_token_operation_error_ = trust_token_operation_error_; return error_copy; } @@ -127,6 +132,11 @@ ResourceError::operator WebURLError() const { return WebURLError(*cors_error_status_, has_copy_in_cache, failing_url_); } + if (trust_token_operation_error_ != + network::mojom::blink::TrustTokenOperationStatus::kOk) { + return WebURLError(error_code_, trust_token_operation_error_, failing_url_); + } + return WebURLError( error_code_, extended_error_code_, resolve_error_info_, has_copy_in_cache, is_access_check_ ? WebURLError::IsWebSecurityViolation::kTrue @@ -159,6 +169,9 @@ bool ResourceError::Compare(const ResourceError& a, const ResourceError& b) { if (a.resolve_error_info_ != b.resolve_error_info_) return false; + if (a.trust_token_operation_error_ != b.trust_token_operation_error_) + return false; + return true; } @@ -170,6 +183,10 @@ bool ResourceError::IsCancellation() const { return error_code_ == net::ERR_ABORTED; } +bool ResourceError::IsTrustTokenCacheHit() const { + return error_code_ == net::ERR_TRUST_TOKEN_OPERATION_CACHE_HIT; +} + bool ResourceError::IsCacheMiss() const { return error_code_ == net::ERR_CACHE_MISS; } @@ -188,25 +205,24 @@ namespace { blink::ResourceRequestBlockedReason BlockedByResponseReasonToResourceRequestBlockedReason( - network::BlockedByResponseReason reason) { + network::mojom::BlockedByResponseReason reason) { switch (reason) { - case network::BlockedByResponseReason::kCoepFrameResourceNeedsCoepHeader: + case network::mojom::BlockedByResponseReason:: + kCoepFrameResourceNeedsCoepHeader: return blink::ResourceRequestBlockedReason:: kCoepFrameResourceNeedsCoepHeader; - case network::BlockedByResponseReason:: + case network::mojom::BlockedByResponseReason:: kCoopSandboxedIFrameCannotNavigateToCoopPage: return blink::ResourceRequestBlockedReason:: kCoopSandboxedIFrameCannotNavigateToCoopPage; - case network::BlockedByResponseReason::kCorpNotSameOrigin: + case network::mojom::BlockedByResponseReason::kCorpNotSameOrigin: return blink::ResourceRequestBlockedReason::kCorpNotSameOrigin; - case network::BlockedByResponseReason:: + case network::mojom::BlockedByResponseReason:: kCorpNotSameOriginAfterDefaultedToSameOriginByCoep: return blink::ResourceRequestBlockedReason:: kCorpNotSameOriginAfterDefaultedToSameOriginByCoep; - break; - case network::BlockedByResponseReason::kCorpNotSameSite: + case network::mojom::BlockedByResponseReason::kCorpNotSameSite: return blink::ResourceRequestBlockedReason::kCorpNotSameSite; - break; } NOTREACHED(); return blink::ResourceRequestBlockedReason::kOther; @@ -299,7 +315,10 @@ std::ostream& operator<<(std::ostream& os, const ResourceError& error) { << ", IsAccessCheck = " << error.IsAccessCheck() << ", IsTimeout = " << error.IsTimeout() << ", HasCopyInCache = " << error.HasCopyInCache() - << ", IsCacheMiss = " << error.IsCacheMiss(); + << ", IsCacheMiss = " << error.IsCacheMiss() + << ", TrustTokenOperationError = " + << String::FromUTF8(base::NumberToString( + static_cast<int32_t>(error.TrustTokenOperationError()))); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.h index 19c60919c24..b5e3030a4e1 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.h @@ -30,8 +30,9 @@ #include <iosfwd> #include "base/optional.h" #include "net/dns/public/resolve_error_info.h" -#include "services/network/public/cpp/blocked_by_response_reason.h" #include "services/network/public/cpp/cors/cors_error_status.h" +#include "services/network/public/mojom/blocked_by_response_reason.mojom-blink.h" +#include "services/network/public/mojom/trust_tokens.mojom-blink.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -79,6 +80,13 @@ class PLATFORM_EXPORT ResourceError final { const String& LocalizedDescription() const { return localized_description_; } bool IsCancellation() const; + + // If the error was due to a Trust Tokens cache hit, the purpose of this + // request was to update some state in the network stack (with a response from + // the server), but that this state was already present, so there was no need + // to send the request. + bool IsTrustTokenCacheHit() const; + bool IsAccessCheck() const { return is_access_check_; } bool HasCopyInCache() const { return has_copy_in_cache_; } bool IsTimeout() const; @@ -92,7 +100,12 @@ class PLATFORM_EXPORT ResourceError final { return cors_error_status_; } - operator WebURLError() const; + network::mojom::blink::TrustTokenOperationStatus TrustTokenOperationError() + const { + return trust_token_operation_error_; + } + + explicit operator WebURLError() const; static bool Compare(const ResourceError&, const ResourceError&); @@ -109,7 +122,13 @@ class PLATFORM_EXPORT ResourceError final { bool blocked_by_subresource_filter_ = false; base::Optional<network::CorsErrorStatus> cors_error_status_; - base::Optional<network::BlockedByResponseReason> blocked_by_response_reason_; + base::Optional<network::mojom::BlockedByResponseReason> + blocked_by_response_reason_; + + // Refer to the member comment in WebURLError. + network::mojom::blink::TrustTokenOperationStatus + trust_token_operation_error_ = + network::mojom::blink::TrustTokenOperationStatus::kOk; }; inline bool operator==(const ResourceError& a, const ResourceError& b) { diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index 04ed5036553..73291aca6fa 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc @@ -310,6 +310,24 @@ void SetReferrer( request.SetReferrerPolicy(generated_referrer.referrer_policy); } +void PopulateAndAddResourceTimingInfo(Resource* resource, + scoped_refptr<ResourceTimingInfo> info, + base::TimeTicks response_end, + int64_t encoded_data_length) { + info->SetInitialURL( + resource->GetResourceRequest().GetInitialUrlForResourceTiming().IsNull() + ? resource->GetResourceRequest().Url() + : resource->GetResourceRequest().GetInitialUrlForResourceTiming()); + info->SetFinalResponse(resource->GetResponse()); + info->SetLoadResponseEnd(response_end); + // encodedDataLength == -1 means "not available". + // TODO(ricea): Find cases where it is not available but the + // PerformanceResourceTiming spec requires it to be available and fix + // them. + info->AddFinalTransferSize(encoded_data_length == -1 ? 0 + : encoded_data_length); +} + } // namespace ResourceFetcherInit::ResourceFetcherInit( @@ -536,16 +554,20 @@ ResourceFetcher::ResourceFetcher(const ResourceFetcherInit& init) loader_factory_(init.loader_factory), scheduler_(MakeGarbageCollected<ResourceLoadScheduler>( init.initial_throttling_policy, + init.throttle_option_override, *properties_, - init.frame_scheduler, + init.frame_or_worker_scheduler, *console_logger_)), archive_(init.archive), resource_timing_report_timer_( task_runner_, this, &ResourceFetcher::ResourceTimingReportTimerFired), - frame_scheduler_(init.frame_scheduler ? init.frame_scheduler->GetWeakPtr() - : nullptr), + frame_or_worker_scheduler_( + init.frame_or_worker_scheduler + ? init.frame_or_worker_scheduler->GetWeakPtr() + : nullptr), + blob_registry_remote_(nullptr), auto_load_images_(true), images_enabled_(true), allow_stale_resources_(false), @@ -590,15 +612,13 @@ bool ResourceFetcher::ResourceNeedsLoad(Resource* resource, // - instructed to defer loading images from network if (resource->GetType() == ResourceType::kImage && (ShouldDeferImageLoad(resource->Url()) || - params.GetImageRequestOptimization() == - FetchParameters::kDeferImageLoad)) { + params.GetImageRequestBehavior() == FetchParameters::kDeferImageLoad)) { return false; } return policy != RevalidationPolicy::kUse || resource->StillNeedsLoad(); } void ResourceFetcher::DidLoadResourceFromMemoryCache( - uint64_t identifier, Resource* resource, const ResourceRequest& request, bool is_static_data) { @@ -606,18 +626,19 @@ void ResourceFetcher::DidLoadResourceFromMemoryCache( return; resource_load_observer_->WillSendRequest( - identifier, request, ResourceResponse() /* redirects */, + request.InspectorId(), request, ResourceResponse() /* redirects */, resource->GetType(), resource->Options().initiator_info); resource_load_observer_->DidReceiveResponse( - identifier, request, resource->GetResponse(), resource, + request.InspectorId(), request, resource->GetResponse(), resource, ResourceLoadObserver::ResponseSource::kFromMemoryCache); if (resource->EncodedSize() > 0) { resource_load_observer_->DidReceiveData( - identifier, base::span<const char>(nullptr, resource->EncodedSize())); + request.InspectorId(), + base::span<const char>(nullptr, resource->EncodedSize())); } resource_load_observer_->DidFinishLoading( - identifier, base::TimeTicks(), 0, + request.InspectorId(), base::TimeTicks(), 0, resource->GetResponse().DecodedBodyLength(), false); if (!is_static_data) { @@ -782,7 +803,6 @@ void ResourceFetcher::RemovePreload(Resource* resource) { base::Optional<ResourceRequestBlockedReason> ResourceFetcher::PrepareRequest( FetchParameters& params, const ResourceFactory& factory, - uint64_t identifier, WebScopedVirtualTimePauser& virtual_time_pauser) { ResourceRequest& resource_request = params.MutableResourceRequest(); ResourceType resource_type = factory.GetType(); @@ -794,10 +814,28 @@ base::Optional<ResourceRequestBlockedReason> ResourceFetcher::PrepareRequest( params.OverrideContentType(factory.ContentType()); - // Don't send security violation reports for speculative preloads. + // No CSP reports are sent for: + // + // Speculative preload + // =================== + // This avoids sending 2 reports for a single resource (preload + real load). + // Moreover the speculative preload are 'speculative', it might not even be + // possible to issue a real request. + // + // Stale revalidations + // =================== + // Web browser should not send violation reports for stale revalidations. The + // initial request was allowed. In theory, the revalidation request should be + // allowed as well. However, some <meta> CSP header might have been added in + // the meantime. See https://crbug.com/1070117. + // + // Note: Ideally, stale revalidations should bypass every checks. In practise, + // they are run and block the request. Bypassing all security checks could be + // risky and probably doesn't really worth it. They are very rarely blocked. ReportingDisposition reporting_disposition = - params.IsSpeculativePreload() ? ReportingDisposition::kSuppressReporting - : ReportingDisposition::kReport; + params.IsSpeculativePreload() || params.IsStaleRevalidation() + ? ReportingDisposition::kSuppressReporting + : ReportingDisposition::kReport; // Note that resource_request.GetRedirectStatus() may return kFollowedRedirect // here since e.g. ThreadableLoader may create a new Resource from @@ -809,6 +847,7 @@ base::Optional<ResourceRequestBlockedReason> ResourceFetcher::PrepareRequest( // (e.g. mixed content that is being upgraded by upgrade-insecure-requests). Context().CheckCSPForRequest( resource_request.GetRequestContext(), + resource_request.GetRequestDestination(), MemoryCache::RemoveFragmentIdentifierIfNeeded(params.Url()), options, reporting_disposition, resource_request.GetRedirectStatus()); @@ -864,7 +903,8 @@ base::Optional<ResourceRequestBlockedReason> ResourceFetcher::PrepareRequest( TRACE_EVENT_NESTABLE_ASYNC_INSTANT1( TRACE_DISABLED_BY_DEFAULT("network"), "ResourcePrioritySet", - TRACE_ID_WITH_SCOPE("BlinkResourceID", TRACE_ID_LOCAL(identifier)), + TRACE_ID_WITH_SCOPE("BlinkResourceID", + TRACE_ID_LOCAL(resource_request.InspectorId())), "data", ResourcePrioritySetData(resource_request.Priority())); KURL url = MemoryCache::RemoveFragmentIdentifierIfNeeded(params.Url()); @@ -873,7 +913,8 @@ base::Optional<ResourceRequestBlockedReason> ResourceFetcher::PrepareRequest( reporting_disposition, resource_request.GetRedirectStatus()); - if (Context().CalculateIfAdSubresource(resource_request, resource_type)) + if (Context().CalculateIfAdSubresource(resource_request, resource_type, + options.initiator_info)) resource_request.SetIsAdResource(); if (blocked_reason) @@ -973,7 +1014,7 @@ Resource* ResourceFetcher::RequestResource(FetchParameters& params, WebScopedVirtualTimePauser pauser; base::Optional<ResourceRequestBlockedReason> blocked_reason = - PrepareRequest(params, factory, identifier, pauser); + PrepareRequest(params, factory, pauser); if (blocked_reason) { return ResourceForBlockedRequest(params, factory, blocked_reason.value(), client); @@ -1068,8 +1109,7 @@ Resource* ResourceFetcher::RequestResource(FetchParameters& params, !cached_resources_map_.Contains( MemoryCache::RemoveFragmentIdentifierIfNeeded(params.Url()))) { // Loaded from MemoryCache. - DidLoadResourceFromMemoryCache(identifier, resource, resource_request, - is_static_data); + DidLoadResourceFromMemoryCache(resource, resource_request, is_static_data); } if (!is_stale_revalidation) { String resource_url = @@ -1083,9 +1123,18 @@ Resource* ResourceFetcher::RequestResource(FetchParameters& params, } } + // Image loaders are by default added to |loaders_|, and are therefore + // load-blocking. Lazy loaded images that are eventually fetched, however, + // should always be added to |non_blocking_loaders_|, as they are never + // load-blocking. + LoadBlockingPolicy load_blocking_policy = LoadBlockingPolicy::kDefault; if (resource->GetType() == ResourceType::kImage) { image_resources_.insert(resource); not_loaded_image_resources_.insert(resource); + if (params.GetImageRequestBehavior() == + FetchParameters::kNonBlockingImage) { + load_blocking_policy = LoadBlockingPolicy::kForceNonBlockingLoad; + } } // Returns with an existing resource if the resource does not need to start @@ -1094,7 +1143,8 @@ Resource* ResourceFetcher::RequestResource(FetchParameters& params, // start loading. if (ResourceNeedsLoad(resource, params, policy)) { if (!StartLoad(resource, - std::move(params.MutableResourceRequest().MutableBody()))) { + std::move(params.MutableResourceRequest().MutableBody()), + load_blocking_policy)) { resource->FinishAsError(ResourceError::CancelledError(params.Url()), task_runner_.get()); } @@ -1269,11 +1319,7 @@ Resource* ResourceFetcher::MatchPreload(const FetchParameters& params, return nullptr; } - if (!resource->MatchPreload(params, task_runner_.get())) { - PrintPreloadWarning(resource, Resource::MatchStatus::kUnknownFailure); - return nullptr; - } - + resource->MatchPreload(params); preloads_.erase(it); matched_preloads_.push_back(resource); return resource; @@ -1325,9 +1371,6 @@ void ResourceFetcher::PrintPreloadWarning(Resource* resource, case Resource::MatchStatus::kRequestHeadersDoNotMatch: builder.Append("because the request headers do not match."); break; - case Resource::MatchStatus::kImagePlaceholder: - builder.Append("due to different image placeholder policies."); - break; } console_logger_->AddConsoleMessage(mojom::ConsoleMessageSource::kOther, mojom::ConsoleMessageLevel::kWarning, @@ -1761,21 +1804,8 @@ void ResourceFetcher::HandleLoaderFinish(Resource* resource, if (scoped_refptr<ResourceTimingInfo> info = resource_timing_info_map_.Take(resource)) { if (resource->GetResponse().IsHTTP()) { - info->SetInitialURL(resource->GetResourceRequest() - .GetInitialUrlForResourceTiming() - .IsNull() - ? resource->GetResourceRequest().Url() - : resource->GetResourceRequest() - .GetInitialUrlForResourceTiming()); - info->SetFinalResponse(resource->GetResponse()); - info->SetLoadResponseEnd(response_end); - // encodedDataLength == -1 means "not available". - // TODO(ricea): Find cases where it is not available but the - // PerformanceResourceTiming spec requires it to be available and fix - // them. - info->AddFinalTransferSize( - encoded_data_length == -1 ? 0 : encoded_data_length); - + PopulateAndAddResourceTimingInfo(resource, info, response_end, + encoded_data_length); auto receiver = Context().TakePendingWorkerTimingReceiver( resource->GetResponse().RequestId()); info->SetWorkerTimingReceiver(std::move(receiver)); @@ -1807,7 +1837,6 @@ void ResourceFetcher::HandleLoaderFinish(Resource* resource, resource->GetResponse().DecodedBodyLength(), should_report_corb_blocking); } - resource->ReloadIfLoFiOrPlaceholderImage(this, Resource::kReloadIfNeeded); } void ResourceFetcher::HandleLoaderError(Resource* resource, @@ -1820,7 +1849,14 @@ void ResourceFetcher::HandleLoaderError(Resource* resource, RemoveResourceLoader(resource->Loader()); - resource_timing_info_map_.Take(resource); + if (scoped_refptr<ResourceTimingInfo> info = + resource_timing_info_map_.Take(resource)) { + PopulateAndAddResourceTimingInfo( + resource, info, info->InitialTime(), + resource->GetResponse().EncodedDataLength()); + if (resource->Options().request_initiator_context == kDocumentContext) + Context().AddResourceTiming(*info); + } resource->VirtualTimePauser().UnpauseVirtualTime(); if (error.IsCancellation()) @@ -1840,7 +1876,6 @@ void ResourceFetcher::HandleLoaderError(Resource* resource, resource->Options().initiator_info.name == fetch_initiator_type_names::kInternal)); } - resource->ReloadIfLoFiOrPlaceholderImage(this, Resource::kReloadIfNeeded); } void ResourceFetcher::MoveResourceLoaderToNonBlocking(ResourceLoader* loader) { @@ -1851,11 +1886,13 @@ void ResourceFetcher::MoveResourceLoaderToNonBlocking(ResourceLoader* loader) { } bool ResourceFetcher::StartLoad(Resource* resource) { - return StartLoad(resource, ResourceRequestBody()); + return StartLoad(resource, ResourceRequestBody(), + LoadBlockingPolicy::kDefault); } bool ResourceFetcher::StartLoad(Resource* resource, - ResourceRequestBody request_body) { + ResourceRequestBody request_body, + LoadBlockingPolicy policy) { DCHECK(resource); DCHECK(resource->StillNeedsLoad()); @@ -1907,7 +1944,8 @@ bool ResourceFetcher::StartLoad(Resource* resource, // is not responsible for promoting matched preloads to load-blocking. This // is handled by MakePreloadedResourceBlockOnloadIfNeeded(). if (!resource->IsLinkPreload() && - resource->IsLoadEventBlockingResourceType()) { + resource->IsLoadEventBlockingResourceType() && + policy != LoadBlockingPolicy::kForceNonBlockingLoad) { loaders_.insert(loader); } else { non_blocking_loaders_.insert(loader); @@ -2035,6 +2073,7 @@ void ResourceFetcher::EmulateLoadStartedForInspector( } resource_request.SetReferrerString(Referrer::NoReferrer()); resource_request.SetReferrerPolicy(network::mojom::ReferrerPolicy::kNever); + resource_request.SetInspectorId(CreateUniqueIdentifier()); ResourceLoaderOptions options = resource->Options(); options.initiator_info.name = initiator_name; @@ -2044,8 +2083,7 @@ void ResourceFetcher::EmulateLoadStartedForInspector( last_resource_request.Url(), params.Options(), ReportingDisposition::kReport, last_resource_request.GetRedirectStatus()); - DidLoadResourceFromMemoryCache(resource->InspectorId(), resource, - params.GetResourceRequest(), + DidLoadResourceFromMemoryCache(resource, params.GetResourceRequest(), false /* is_static_data */); } @@ -2113,15 +2151,15 @@ void ResourceFetcher::RevalidateStaleResource(Resource* stale_resource) { } mojom::blink::BlobRegistry* ResourceFetcher::GetBlobRegistry() { - if (!blob_registry_remote_) { + if (!blob_registry_remote_.is_bound()) { Platform::Current()->GetBrowserInterfaceBroker()->GetInterface( blob_registry_remote_.BindNewPipeAndPassReceiver(task_runner_)); } return blob_registry_remote_.get(); } -FrameScheduler* ResourceFetcher::GetFrameScheduler() { - return frame_scheduler_.get(); +FrameOrWorkerScheduler* ResourceFetcher::GetFrameOrWorkerScheduler() { + return frame_or_worker_scheduler_.get(); } void ResourceFetcher::Trace(Visitor* visitor) { @@ -2141,6 +2179,7 @@ void ResourceFetcher::Trace(Visitor* visitor) { visitor->Trace(preloads_); visitor->Trace(matched_preloads_); visitor->Trace(resource_timing_info_map_); + visitor->Trace(blob_registry_remote_); } // static diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h index 75ac2446bee..252c777bec6 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h @@ -31,7 +31,6 @@ #include <utility> #include "base/single_thread_task_runner.h" -#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/blob/blob_registry.mojom-blink.h" #include "third_party/blink/public/mojom/service_worker/controller_service_worker_mode.mojom-blink-forward.h" #include "third_party/blink/renderer/platform/heap/persistent.h" @@ -39,6 +38,8 @@ #include "third_party/blink/renderer/platform/loader/fetch/preload_key.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_load_priority.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/timer.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" @@ -53,7 +54,7 @@ class DetachableConsoleLogger; class DetachableUseCounter; class DetachableResourceFetcherProperties; class FetchContext; -class FrameScheduler; +class FrameOrWorkerScheduler; class MHTMLArchive; class KURL; class Resource; @@ -131,10 +132,10 @@ class PLATFORM_EXPORT ResourceFetcher resource_load_observer_ = observer; } - // Triggers a fetch based on the given FetchParameters (if there isn't a - // suitable Resource already cached) and registers the given ResourceClient - // with the Resource. Guaranteed to return a non-null Resource of the subtype - // specified by ResourceFactory::GetType(). + // Triggers or defers a fetch based on the given FetchParameters (if there + // isn't a suitable Resource already cached) and registers the given + // ResourceClient with the Resource. Guaranteed to return a non-null Resource + // of the subtype specified by ResourceFactory::GetType(). Resource* RequestResource(FetchParameters&, const ResourceFactory&, ResourceClient*); @@ -162,13 +163,18 @@ class PLATFORM_EXPORT ResourceFetcher return cached_resources_map_; } + enum class LoadBlockingPolicy { + kDefault, + kForceNonBlockingLoad, + }; + // Binds the given Resource instance to this ResourceFetcher instance to // start loading the Resource actually. // Usually, RequestResource() calls this method internally, but needs to // call this method explicitly on cases such as ResourceNeedsLoad() returning // false. bool StartLoad(Resource*); - bool StartLoad(Resource*, ResourceRequestBody); + bool StartLoad(Resource*, ResourceRequestBody, LoadBlockingPolicy); void SetAutoLoadImages(bool); void SetImagesEnabled(bool); @@ -254,7 +260,7 @@ class PLATFORM_EXPORT ResourceFetcher mojom::blink::BlobRegistry* GetBlobRegistry(); - FrameScheduler* GetFrameScheduler(); + FrameOrWorkerScheduler* GetFrameOrWorkerScheduler(); ResourceLoadPriority ComputeLoadPriorityForTesting( ResourceType type, @@ -271,6 +277,11 @@ class PLATFORM_EXPORT ResourceFetcher should_log_request_as_invalid_in_imported_document_ = true; } + void SetThrottleOptionOverride( + ResourceLoadScheduler::ThrottleOptionOverride throttle_option_override) { + scheduler_->SetThrottleOptionOverride(throttle_option_override); + } + private: friend class ResourceCacheValidationSuppressor; enum class StopFetchingTarget { @@ -302,7 +313,6 @@ class PLATFORM_EXPORT ResourceFetcher base::Optional<ResourceRequestBlockedReason> PrepareRequest( FetchParameters&, const ResourceFactory&, - uint64_t identifier, WebScopedVirtualTimePauser& virtual_time_pauser); Resource* ResourceForStaticData(const FetchParameters&, @@ -356,8 +366,7 @@ class PLATFORM_EXPORT ResourceFetcher void MoveResourceLoaderToNonBlocking(ResourceLoader*); void RemoveResourceLoader(ResourceLoader*); - void DidLoadResourceFromMemoryCache(uint64_t identifier, - Resource*, + void DidLoadResourceFromMemoryCache(Resource*, const ResourceRequest&, bool is_static_data); @@ -413,14 +422,16 @@ class PLATFORM_EXPORT ResourceFetcher std::unique_ptr<HashSet<String>> preloaded_urls_for_test_; // TODO(altimin): Move FrameScheduler to oilpan. - base::WeakPtr<FrameScheduler> frame_scheduler_; + base::WeakPtr<FrameOrWorkerScheduler> frame_or_worker_scheduler_; // Timeout timer for keepalive requests. TaskHandle keepalive_loaders_task_handle_; uint32_t inflight_keepalive_bytes_ = 0; - mojo::Remote<mojom::blink::BlobRegistry> blob_registry_remote_; + HeapMojoRemote<mojom::blink::BlobRegistry, + HeapMojoWrapperMode::kWithoutContextObserver> + blob_registry_remote_; // This is not in the bit field below because we want to use AutoReset. bool is_in_request_resource_ = false; @@ -485,7 +496,9 @@ struct PLATFORM_EXPORT ResourceFetcherInit final { ResourceLoadScheduler::ThrottlingPolicy initial_throttling_policy = ResourceLoadScheduler::ThrottlingPolicy::kNormal; MHTMLArchive* archive = nullptr; - FrameScheduler* frame_scheduler = nullptr; + FrameOrWorkerScheduler* frame_or_worker_scheduler = nullptr; + ResourceLoadScheduler::ThrottleOptionOverride throttle_option_override = + ResourceLoadScheduler::ThrottleOptionOverride::kNone; DISALLOW_COPY_AND_ASSIGN(ResourceFetcherInit); }; diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.cc index 51da99672f2..382d1de0c5b 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.cc @@ -24,6 +24,7 @@ void DetachableResourceFetcherProperties::Detach() { is_subframe_deprioritization_enabled_ = properties_->IsSubframeDeprioritizationEnabled(); web_bundle_physical_url_ = properties_->WebBundlePhysicalUrl(); + outstanding_throttled_limit_ = properties_->GetOutstandingThrottledLimit(); properties_ = nullptr; } diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h index 61810977848..99ff28be578 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h @@ -87,6 +87,8 @@ class PLATFORM_EXPORT ResourceFetcherProperties // The physical URL of Web Bundle from which this global context is loaded. // Used as an additional identifier for MemoryCache. virtual const KURL& WebBundlePhysicalUrl() const = 0; + + virtual int GetOutstandingThrottledLimit() const = 0; }; // A delegating ResourceFetcherProperties subclass which can be retained @@ -150,6 +152,11 @@ class PLATFORM_EXPORT DetachableResourceFetcherProperties final : web_bundle_physical_url_; } + int GetOutstandingThrottledLimit() const override { + return properties_ ? properties_->GetOutstandingThrottledLimit() + : outstanding_throttled_limit_; + } + private: // |properties_| is null if and only if detached. Member<const ResourceFetcherProperties> properties_; @@ -161,6 +168,7 @@ class PLATFORM_EXPORT DetachableResourceFetcherProperties final bool load_complete_ = false; bool is_subframe_deprioritization_enabled_ = false; KURL web_bundle_physical_url_; + int outstanding_throttled_limit_ = 0; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc index c79595b9005..b73ea743cc7 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc @@ -26,20 +26,6 @@ namespace blink { namespace { -// Field trial name for throttling. -const char kResourceLoadThrottlingTrial[] = "ResourceLoadScheduler"; - -// Field trial parameter names. -// Note: bg_limit is supported on m61+, but bg_sub_limit is only on m63+. -// If bg_sub_limit param is not found, we should use bg_limit to make the -// study result statistically correct. -const char kOutstandingLimitForBackgroundMainFrameName[] = "bg_limit"; -const char kOutstandingLimitForBackgroundSubFrameName[] = "bg_sub_limit"; - -// Field trial default parameters. -constexpr size_t kOutstandingLimitForBackgroundMainFrameDefault = 3u; -constexpr size_t kOutstandingLimitForBackgroundSubFrameDefault = 2u; - constexpr char kRendererSideResourceScheduler[] = "RendererSideResourceScheduler"; @@ -64,10 +50,6 @@ enum class ReportCircumstance { kNumOfCircumstances, }; -base::HistogramBase::Sample ToSample(ReportCircumstance circumstance) { - return static_cast<base::HistogramBase::Sample>(circumstance); -} - uint32_t GetFieldTrialUint32Param(const char* trial_name, const char* parameter_name, uint32_t default_param) { @@ -87,137 +69,25 @@ uint32_t GetFieldTrialUint32Param(const char* trial_name, return param; } -size_t GetOutstandingThrottledLimit( - const DetachableResourceFetcherProperties& properties) { - static const size_t main_frame_limit = GetFieldTrialUint32Param( - kResourceLoadThrottlingTrial, kOutstandingLimitForBackgroundMainFrameName, - kOutstandingLimitForBackgroundMainFrameDefault); - static const size_t sub_frame_limit = GetFieldTrialUint32Param( - kResourceLoadThrottlingTrial, kOutstandingLimitForBackgroundSubFrameName, - kOutstandingLimitForBackgroundSubFrameDefault); - - return properties.IsMainFrame() ? main_frame_limit : sub_frame_limit; -} - -int TakeWholeKilobytes(int64_t& bytes) { - int kilobytes = base::saturated_cast<int>(bytes / 1024); - bytes %= 1024; - return kilobytes; -} - } // namespace -// A class to gather throttling and traffic information to report histograms. -class ResourceLoadScheduler::TrafficMonitor { - public: - explicit TrafficMonitor( - const DetachableResourceFetcherProperties& resource_fetcher_properties); - - // Notified when the ThrottlingState is changed. - void OnLifecycleStateChanged(scheduler::SchedulingLifecycleState); - - // Reports resource request completion. - void Report(const ResourceLoadScheduler::TrafficReportHints&); - - // Reports per-frame reports. - void ReportAll(); - - private: - const Persistent<const DetachableResourceFetcherProperties> - resource_fetcher_properties_; - - scheduler::SchedulingLifecycleState current_state_ = - scheduler::SchedulingLifecycleState::kStopped; - - scheduler::AggregatedMetricReporter<scheduler::FrameStatus, int64_t> - traffic_kilobytes_per_frame_status_; - scheduler::AggregatedMetricReporter<scheduler::FrameStatus, int64_t> - decoded_kilobytes_per_frame_status_; -}; - -ResourceLoadScheduler::TrafficMonitor::TrafficMonitor( - const DetachableResourceFetcherProperties& resource_fetcher_properties) - : resource_fetcher_properties_(resource_fetcher_properties), - traffic_kilobytes_per_frame_status_( - "Blink.ResourceLoadScheduler.TrafficBytes.KBPerFrameStatus", - &TakeWholeKilobytes), - decoded_kilobytes_per_frame_status_( - "Blink.ResourceLoadScheduler.DecodedBytes.KBPerFrameStatus", - &TakeWholeKilobytes) {} - -void ResourceLoadScheduler::TrafficMonitor::OnLifecycleStateChanged( - scheduler::SchedulingLifecycleState state) { - current_state_ = state; -} - -void ResourceLoadScheduler::TrafficMonitor::Report( - const ResourceLoadScheduler::TrafficReportHints& hints) { - // Currently we only care about stats from frames. - if (!IsMainThread()) - return; - if (!hints.IsValid()) - return; - - DEFINE_STATIC_LOCAL(EnumerationHistogram, request_count_by_circumstance, - ("Blink.ResourceLoadScheduler.RequestCount", - ToSample(ReportCircumstance::kNumOfCircumstances))); - - switch (current_state_) { - case scheduler::SchedulingLifecycleState::kThrottled: - case scheduler::SchedulingLifecycleState::kHidden: - if (resource_fetcher_properties_->IsMainFrame()) { - request_count_by_circumstance.Count( - ToSample(ReportCircumstance::kMainframeThrottled)); - } else { - request_count_by_circumstance.Count( - ToSample(ReportCircumstance::kSubframeThrottled)); - } - break; - case scheduler::SchedulingLifecycleState::kNotThrottled: - if (resource_fetcher_properties_->IsMainFrame()) { - request_count_by_circumstance.Count( - ToSample(ReportCircumstance::kMainframeNotThrottled)); - } else { - request_count_by_circumstance.Count( - ToSample(ReportCircumstance::kSubframeNotThrottled)); - } - break; - case scheduler::SchedulingLifecycleState::kStopped: - break; - } - - // Report kilobytes instead of bytes to avoid overflows. - int64_t encoded_kilobytes = hints.encoded_data_length() / 1024; - int64_t decoded_kilobytes = hints.decoded_body_length() / 1024; - - if (encoded_kilobytes) { - traffic_kilobytes_per_frame_status_.RecordTask( - resource_fetcher_properties_->GetFrameStatus(), encoded_kilobytes); - } - if (decoded_kilobytes) { - decoded_kilobytes_per_frame_status_.RecordTask( - resource_fetcher_properties_->GetFrameStatus(), decoded_kilobytes); - } -} - constexpr ResourceLoadScheduler::ClientId ResourceLoadScheduler::kInvalidClientId; ResourceLoadScheduler::ResourceLoadScheduler( ThrottlingPolicy initial_throttling_policy, + ThrottleOptionOverride throttle_option_override, const DetachableResourceFetcherProperties& resource_fetcher_properties, - FrameScheduler* frame_scheduler, + FrameOrWorkerScheduler* frame_or_worker_scheduler, DetachableConsoleLogger& console_logger) : resource_fetcher_properties_(resource_fetcher_properties), policy_(initial_throttling_policy), outstanding_limit_for_throttled_frame_scheduler_( - GetOutstandingThrottledLimit(*resource_fetcher_properties_)), + resource_fetcher_properties_->GetOutstandingThrottledLimit()), console_logger_(console_logger), - clock_(base::DefaultClock::GetInstance()) { - traffic_monitor_ = std::make_unique<ResourceLoadScheduler::TrafficMonitor>( - resource_fetcher_properties); - - if (!frame_scheduler) + clock_(base::DefaultClock::GetInstance()), + throttle_option_override_(throttle_option_override) { + if (!frame_or_worker_scheduler) return; normal_outstanding_limit_ = @@ -229,7 +99,7 @@ ResourceLoadScheduler::ResourceLoadScheduler( kTightLimitForRendererSideResourceSchedulerName, kTightLimitForRendererSideResourceScheduler); - scheduler_observer_handle_ = frame_scheduler->AddLifecycleObserver( + scheduler_observer_handle_ = frame_or_worker_scheduler->AddLifecycleObserver( FrameScheduler::ObserverType::kLoader, this); } @@ -258,9 +128,6 @@ void ResourceLoadScheduler::Shutdown() { return; is_shutdown_ = true; - if (traffic_monitor_) - traffic_monitor_.reset(); - scheduler_observer_handle_.reset(); } @@ -273,6 +140,12 @@ void ResourceLoadScheduler::Request(ResourceLoadSchedulerClient* client, if (is_shutdown_) return; + if (option == ThrottleOption::kStoppable && + throttle_option_override_ == + ThrottleOptionOverride::kStoppableAsThrottleable) { + option = ThrottleOption::kThrottleable; + } + // Check if the request can be throttled. ClientIdWithPriority request_info(*id, priority, intra_priority); if (!IsClientDelayable(option)) { @@ -328,9 +201,6 @@ bool ResourceLoadScheduler::Release( running_requests_.erase(id); running_throttleable_requests_.erase(id); - if (traffic_monitor_) - traffic_monitor_->Report(hints); - if (option == ReleaseOption::kReleaseAndSchedule) MaybeRun(); return true; @@ -372,9 +242,6 @@ void ResourceLoadScheduler::OnLifecycleStateChanged( if (frame_scheduler_lifecycle_state_ == state) return; - if (traffic_monitor_) - traffic_monitor_->OnLifecycleStateChanged(state); - frame_scheduler_lifecycle_state_ = state; if (state == scheduler::SchedulingLifecycleState::kNotThrottled) diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h index eb66476c349..7663076d189 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h @@ -83,7 +83,7 @@ class PLATFORM_EXPORT ResourceLoadSchedulerClient // indefinitely (i.e., threshold is zero in such a circumstance). class PLATFORM_EXPORT ResourceLoadScheduler final : public GarbageCollected<ResourceLoadScheduler>, - public FrameScheduler::Observer { + public FrameOrWorkerScheduler::Observer { public: // An option to use in calling Request(). If kCanNotBeStoppedOrThrottled is // specified, the request should be granted and Run() should be called @@ -96,6 +96,18 @@ class PLATFORM_EXPORT ResourceLoadScheduler final kCanNotBeStoppedOrThrottled = 2, }; + // In some cases we may want to override the default ThrottleOption. For + // example, service workers can only perform requests that are normally + // stoppable, but we want to be able to throttle these requests in some + // cases. This enum is used to indicate what kind of override should be + // applied. + enum class ThrottleOptionOverride { + // Use the default ThrottleOption for the request type. + kNone, + // Treat stoppable requests as throttleable. + kStoppableAsThrottleable, + }; + // An option to use in calling Release(). If kReleaseOnly is specified, // the specified request should be released, but no other requests should // be scheduled within the call. @@ -152,8 +164,9 @@ class PLATFORM_EXPORT ResourceLoadScheduler final std::numeric_limits<size_t>::max(); ResourceLoadScheduler(ThrottlingPolicy initial_throttling_poilcy, + ThrottleOptionOverride throttle_option_override, const DetachableResourceFetcherProperties&, - FrameScheduler*, + FrameOrWorkerScheduler*, DetachableConsoleLogger& console_logger); ~ResourceLoadScheduler() override; @@ -200,16 +213,19 @@ class PLATFORM_EXPORT ResourceLoadScheduler final } void SetOutstandingLimitForTesting(size_t tight_limit, size_t normal_limit); - // FrameScheduler::Observer overrides: + // FrameOrWorkerScheduler::Observer overrides: void OnLifecycleStateChanged(scheduler::SchedulingLifecycleState) override; // The caller is the owner of the |clock|. The |clock| must outlive the // ResourceLoadScheduler. void SetClockForTesting(const base::Clock* clock); - private: - class TrafficMonitor; + void SetThrottleOptionOverride( + ThrottleOptionOverride throttle_option_override) { + throttle_option_override_ = throttle_option_override; + } + private: class ClientIdWithPriority { public: struct Compare { @@ -326,17 +342,16 @@ class PLATFORM_EXPORT ResourceLoadScheduler final // processed. std::map<ThrottleOption, base::Time> pending_queue_update_times_; - // Holds an internal class instance to monitor and report traffic. - std::unique_ptr<TrafficMonitor> traffic_monitor_; - // Handle to throttling observer. - std::unique_ptr<FrameScheduler::LifecycleObserverHandle> + std::unique_ptr<FrameOrWorkerScheduler::LifecycleObserverHandle> scheduler_observer_handle_; const Member<DetachableConsoleLogger> console_logger_; const base::Clock* clock_; + ThrottleOptionOverride throttle_option_override_; + DISALLOW_COPY_AND_ASSIGN(ResourceLoadScheduler); }; diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler_test.cc index ffe0d245cfc..d5bfad70b7a 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler_test.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler_test.cc @@ -95,6 +95,7 @@ class ResourceLoadSchedulerTest : public testing::Test { console_logger_ = MakeGarbageCollected<MockConsoleLogger>(); scheduler_ = MakeGarbageCollected<ResourceLoadScheduler>( ResourceLoadScheduler::ThrottlingPolicy::kTight, + ResourceLoadScheduler::ThrottleOptionOverride::kNone, properties->MakeDetachable(), frame_scheduler.get(), *MakeGarbageCollected<DetachableConsoleLogger>(console_logger_)); Scheduler()->SetOutstandingLimitForTesting(1); diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc index 7f1a04c6fe4..cd2ec6c9b14 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc @@ -41,6 +41,7 @@ #include "services/metrics/public/cpp/ukm_builders.h" #include "services/network/public/cpp/features.h" #include "services/network/public/mojom/fetch_api.mojom-blink.h" +#include "third_party/blink/public/common/client_hints/client_hints.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h" #include "third_party/blink/public/mojom/blob/blob_registry.mojom-blink.h" @@ -403,10 +404,12 @@ ResourceLoader::ResourceLoader(ResourceFetcher* fetcher, auto& request = resource_->GetResourceRequest(); auto request_context = request.GetRequestContext(); if (!RequestContextObserveResponse(request_context)) { - if (FrameScheduler* frame_scheduler = fetcher->GetFrameScheduler()) { - feature_handle_for_scheduler_ = frame_scheduler->RegisterFeature( - GetFeatureFromRequestContextType(request_context), - {SchedulingPolicy::RecordMetricsForBackForwardCache()}); + if (auto* frame_or_worker_scheduler = + fetcher->GetFrameOrWorkerScheduler()) { + feature_handle_for_scheduler_ = + frame_or_worker_scheduler->RegisterFeature( + GetFeatureFromRequestContextType(request_context), + {SchedulingPolicy::RecordMetricsForBackForwardCache()}); } } @@ -552,7 +555,7 @@ void ResourceLoader::DidFinishLoadingBody() { } void ResourceLoader::DidFailLoadingBody() { - DidFail(ResourceError::Failure(resource_->Url()), 0, 0, 0); + DidFail(WebURLError(ResourceError::Failure(resource_->Url())), 0, 0, 0); } void ResourceLoader::DidCancelLoadingBody() { @@ -703,8 +706,13 @@ bool ResourceLoader::WillFollowRedirect( network::mojom::ReferrerPolicy new_referrer_policy, const WebString& new_method, const WebURLResponse& passed_redirect_response, - bool& report_raw_headers) { + bool& report_raw_headers, + std::vector<std::string>* removed_headers) { DCHECK(!passed_redirect_response.IsNull()); + if (removed_headers) { + FindClientHintsToRemove(Context().GetFeaturePolicy(), + GURL(new_url.GetString().Utf8()), removed_headers); + } if (is_cache_aware_loading_activated_) { // Fail as cache miss if cached response is a redirect. @@ -730,6 +738,8 @@ bool ResourceLoader::WillFollowRedirect( // The following parameters never change during the lifetime of a request. mojom::RequestContextType request_context = initial_request.GetRequestContext(); + network::mojom::RequestDestination request_destination = + initial_request.GetRequestDestination(); network::mojom::RequestMode request_mode = initial_request.GetMode(); network::mojom::CredentialsMode credentials_mode = initial_request.GetCredentialsMode(); @@ -750,7 +760,8 @@ bool ResourceLoader::WillFollowRedirect( // CanRequest() checks only enforced CSP, so check report-only here to // ensure that violations are sent. Context().CheckCSPForRequest( - request_context, new_url, options, reporting_disposition, + request_context, request_destination, new_url, options, + reporting_disposition, ResourceRequest::RedirectStatus::kFollowedRedirect); base::Optional<ResourceRequestBlockedReason> blocked_reason = @@ -759,7 +770,8 @@ bool ResourceLoader::WillFollowRedirect( reporting_disposition, ResourceRequest::RedirectStatus::kFollowedRedirect); - if (Context().CalculateIfAdSubresource(*new_request, resource_type)) + if (Context().CalculateIfAdSubresource(*new_request, resource_type, + options.initiator_info)) new_request->SetIsAdResource(); if (blocked_reason) { @@ -956,6 +968,8 @@ void ResourceLoader::DidReceiveResponseInternal( // The following parameters never change during the lifetime of a request. mojom::RequestContextType request_context = initial_request.GetRequestContext(); + network::mojom::RequestDestination request_destination = + initial_request.GetRequestDestination(); network::mojom::RequestMode request_mode = initial_request.GetMode(); const ResourceLoaderOptions& options = resource_->Options(); @@ -1032,7 +1046,8 @@ void ResourceLoader::DidReceiveResponseInternal( // CanRequest() below only checks enforced policies: check report-only // here to ensure violations are sent. Context().CheckCSPForRequest( - request_context, response_url, options, ReportingDisposition::kReport, + request_context, request_destination, response_url, options, + ReportingDisposition::kReport, ResourceRequest::RedirectStatus::kFollowedRedirect); base::Optional<ResourceRequestBlockedReason> blocked_reason = @@ -1089,14 +1104,14 @@ void ResourceLoader::DidReceiveResponseInternal( response.ResponseTime(), should_use_isolated_code_cache_, this); } - if (FrameScheduler* frame_scheduler = fetcher_->GetFrameScheduler()) { + if (auto* frame_or_worker_scheduler = fetcher_->GetFrameOrWorkerScheduler()) { if (response.CacheControlContainsNoCache()) { - frame_scheduler->RegisterStickyFeature( + frame_or_worker_scheduler->RegisterStickyFeature( SchedulingPolicy::Feature::kSubresourceHasCacheControlNoCache, {SchedulingPolicy::RecordMetricsForBackForwardCache()}); } if (response.CacheControlContainsNoStore()) { - frame_scheduler->RegisterStickyFeature( + frame_or_worker_scheduler->RegisterStickyFeature( SchedulingPolicy::Feature::kSubresourceHasCacheControlNoStore, {SchedulingPolicy::RecordMetricsForBackForwardCache()}); } diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.h index ba73d21ca9d..2ecfb827b55 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.h @@ -120,7 +120,8 @@ class PLATFORM_EXPORT ResourceLoader final network::mojom::ReferrerPolicy new_referrer_policy, const WebString& new_method, const WebURLResponse& passed_redirect_response, - bool& report_raw_headers) override; + bool& report_raw_headers, + std::vector<std::string>* removed_headers) override; void DidSendData(uint64_t bytes_sent, uint64_t total_bytes_to_be_sent) override; void DidReceiveResponse(const WebURLResponse&) override; diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.cc index 58cc557ec78..7650c988f53 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.cc @@ -37,6 +37,8 @@ class SourceKeyedCachedMetadataHandler::SingleKeyHandler final } void ClearCachedMetadata(ClearCacheType cache_type) override { + if (cache_type == kDiscardLocally) + return; parent_->cached_metadata_map_.erase(key_); if (cache_type == CachedMetadataHandler::kClearPersistentStorage) parent_->SendToPlatform(); @@ -104,6 +106,8 @@ SingleCachedMetadataHandler* SourceKeyedCachedMetadataHandler::HandlerForSource( void SourceKeyedCachedMetadataHandler::ClearCachedMetadata( CachedMetadataHandler::ClearCacheType cache_type) { + if (cache_type == kDiscardLocally) + return; cached_metadata_map_.clear(); if (cache_type == CachedMetadataHandler::kClearPersistentStorage) SendToPlatform(); diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/DEPS b/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/DEPS new file mode 100644 index 00000000000..42c1728f6cd --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/DEPS @@ -0,0 +1,5 @@ +specific_include_rules = { + "request_conversion.cc" : [ + "+media/media_buildflags.h" + ], +} diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc index e3fe5379677..c0ddc73d986 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.h" +#include "media/media_buildflags.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/system/data_pipe.h" @@ -18,6 +19,7 @@ #include "services/network/public/mojom/data_pipe_getter.mojom.h" #include "services/network/public/mojom/trust_tokens.mojom-blink.h" #include "services/network/public/mojom/trust_tokens.mojom.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/blob/blob.mojom.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-shared.h" #include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h" @@ -35,7 +37,20 @@ namespace blink { namespace { constexpr char kStylesheetAcceptHeader[] = "text/css,*/*;q=0.1"; -constexpr char kImageAcceptHeader[] = "image/webp,image/apng,image/*,*/*;q=0.8"; + +const char* ImageAcceptHeader() { + static constexpr char kImageAcceptHeaderWithAvif[] = + "image/avif,image/webp,image/apng,image/*,*/*;q=0.8"; + static constexpr size_t kOffset = sizeof("image/avif,") - 1; +#if BUILDFLAG(ENABLE_AV1_DECODER) + static const char* header = base::FeatureList::IsEnabled(features::kAVIF) + ? kImageAcceptHeaderWithAvif + : kImageAcceptHeaderWithAvif + kOffset; +#else + static const char* header = kImageAcceptHeaderWithAvif + kOffset; +#endif + return header; +} // TODO(yhirano): Unify these with variables in // content/public/common/content_constants.h. @@ -177,8 +192,6 @@ mojom::ResourceType RequestContextToResourceType( } } -} // namespace - void PopulateResourceRequestBody(const EncodedFormData& src, network::ResourceRequestBody* dest) { for (const auto& element : src.Elements()) { @@ -228,6 +241,8 @@ void PopulateResourceRequestBody(const EncodedFormData& src, } } +} // namespace + void PopulateResourceRequest(const ResourceRequestHead& src, ResourceRequestBody src_body, network::ResourceRequest* dest) { @@ -291,8 +306,7 @@ void PopulateResourceRequest(const ResourceRequestHead& src, mojom::ResourceType resource_type = RequestContextToResourceType(src.GetRequestContext()); - // TODO(kinuko): Deprecate these. - dest->fetch_request_context_type = static_cast<int>(src.GetRequestContext()); + // TODO(kinuko): Deprecate this. dest->resource_type = static_cast<int>(resource_type); if (resource_type == mojom::ResourceType::kXhr && @@ -341,7 +355,7 @@ void PopulateResourceRequest(const ResourceRequestHead& src, } else if (resource_type == mojom::ResourceType::kImage || resource_type == mojom::ResourceType::kFavicon) { dest->headers.SetHeader(net::HttpRequestHeaders::kAccept, - kImageAcceptHeader); + ImageAcceptHeader()); } else { // Calling SetHeaderIfMissing() instead of SetHeader() because JS can // manually set an accept header on an XHR. diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.h b/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.h index a94fba68d4c..1845a5edeac 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.h @@ -8,7 +8,6 @@ // This file consists of request conversion functions between blink and network. namespace network { -class ResourceRequestBody; struct ResourceRequest; } // namespace network @@ -16,10 +15,6 @@ namespace blink { class ResourceRequestHead; class ResourceRequestBody; -class EncodedFormData; - -void PopulateResourceRequestBody(const EncodedFormData& src, - network::ResourceRequestBody* dest); void PopulateResourceRequest(const ResourceRequestHead& src, ResourceRequestBody src_body, |