Commit 674a1af2 authored by rajendrant's avatar rajendrant Committed by Commit Bot

Refactor subresource redirect renderer code

This CL refactors the existing subresource redirect code to make the
robots rules and login based image compression implementation easy.

* Separate out the url loader throttle that does redirect and timeout
handling from the public image hints decider logic. The robots decider can
be subclassed and used.

* Make public image hints agent as renderframeobserver. This reduces
cluttter in ResourceLoadingHintsAgent. The upcoming robots checker agent
could also observe renderframeobserver directly.

No change in behavior is expected.

Change-Id: Ic555a4402016a645b8820fa87dd5157c7112fb71
Bug: 1144836
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2514068
Commit-Queue: rajendrant <rajendrant@chromium.org>
Reviewed-by: default avatarMichael Crouse <mcrouse@chromium.org>
Cr-Commit-Position: refs/heads/master@{#825115}
parent c13db779
...@@ -95,6 +95,8 @@ static_library("renderer") { ...@@ -95,6 +95,8 @@ static_library("renderer") {
"plugins/plugin_uma.h", "plugins/plugin_uma.h",
"previews/resource_loading_hints_agent.cc", "previews/resource_loading_hints_agent.cc",
"previews/resource_loading_hints_agent.h", "previews/resource_loading_hints_agent.h",
"subresource_redirect/public_image_hints_url_loader_throttle.cc",
"subresource_redirect/public_image_hints_url_loader_throttle.h",
"subresource_redirect/subresource_redirect_hints_agent.cc", "subresource_redirect/subresource_redirect_hints_agent.cc",
"subresource_redirect/subresource_redirect_hints_agent.h", "subresource_redirect/subresource_redirect_hints_agent.h",
"subresource_redirect/subresource_redirect_params.cc", "subresource_redirect/subresource_redirect_params.cc",
......
...@@ -60,6 +60,8 @@ ...@@ -60,6 +60,8 @@
#include "chrome/renderer/plugins/pdf_plugin_placeholder.h" #include "chrome/renderer/plugins/pdf_plugin_placeholder.h"
#include "chrome/renderer/plugins/plugin_uma.h" #include "chrome/renderer/plugins/plugin_uma.h"
#include "chrome/renderer/previews/resource_loading_hints_agent.h" #include "chrome/renderer/previews/resource_loading_hints_agent.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_params.h"
#include "chrome/renderer/sync_encryption_keys_extension.h" #include "chrome/renderer/sync_encryption_keys_extension.h"
#include "chrome/renderer/url_loader_throttle_provider_impl.h" #include "chrome/renderer/url_loader_throttle_provider_impl.h"
#include "chrome/renderer/v8_unwinder.h" #include "chrome/renderer/v8_unwinder.h"
...@@ -601,8 +603,10 @@ void ChromeContentRendererClient::RenderFrameCreated( ...@@ -601,8 +603,10 @@ void ChromeContentRendererClient::RenderFrameCreated(
if (lite_video::IsLiteVideoEnabled()) if (lite_video::IsLiteVideoEnabled())
new lite_video::LiteVideoHintAgent(render_frame); new lite_video::LiteVideoHintAgent(render_frame);
new previews::ResourceLoadingHintsAgent( new previews::ResourceLoadingHintsAgent(associated_interfaces, render_frame);
render_frame_observer->associated_interfaces(), render_frame);
if (subresource_redirect::IsPublicImageHintsBasedCompressionEnabled())
new subresource_redirect::SubresourceRedirectHintsAgent(render_frame);
if (translate::IsSubFrameTranslationEnabled()) { if (translate::IsSubFrameTranslationEnabled()) {
new translate::PerFrameTranslateAgent( new translate::PerFrameTranslateAgent(
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/metrics/histogram_macros_local.h" #include "base/metrics/histogram_macros_local.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.h"
#include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_frame.h"
#include "third_party/blink/public/platform/web_loading_hints_provider.h" #include "third_party/blink/public/platform/web_loading_hints_provider.h"
#include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_string.h"
...@@ -35,9 +36,7 @@ const blink::WebVector<blink::WebString> convert_to_web_vector( ...@@ -35,9 +36,7 @@ const blink::WebVector<blink::WebString> convert_to_web_vector(
ResourceLoadingHintsAgent::ResourceLoadingHintsAgent( ResourceLoadingHintsAgent::ResourceLoadingHintsAgent(
blink::AssociatedInterfaceRegistry* associated_interfaces, blink::AssociatedInterfaceRegistry* associated_interfaces,
content::RenderFrame* render_frame) content::RenderFrame* render_frame)
: content::RenderFrameObserver(render_frame), : content::RenderFrameObserver(render_frame) {
content::RenderFrameObserverTracker<ResourceLoadingHintsAgent>(
render_frame) {
DCHECK(render_frame); DCHECK(render_frame);
associated_interfaces->AddInterface(base::BindRepeating( associated_interfaces->AddInterface(base::BindRepeating(
&ResourceLoadingHintsAgent::SetReceiver, base::Unretained(this))); &ResourceLoadingHintsAgent::SetReceiver, base::Unretained(this)));
...@@ -47,23 +46,6 @@ GURL ResourceLoadingHintsAgent::GetDocumentURL() const { ...@@ -47,23 +46,6 @@ GURL ResourceLoadingHintsAgent::GetDocumentURL() const {
return render_frame()->GetWebFrame()->GetDocument().Url(); return render_frame()->GetWebFrame()->GetDocument().Url();
} }
void ResourceLoadingHintsAgent::DidStartNavigation(
const GURL& url,
base::Optional<blink::WebNavigationType> navigation_type) {
if (!IsMainFrame())
return;
subresource_redirect_hints_agent_.DidStartNavigation();
}
void ResourceLoadingHintsAgent::ReadyToCommitNavigation(
blink::WebDocumentLoader* document_loader) {
if (!IsMainFrame())
return;
subresource_redirect_hints_agent_.ReadyToCommitNavigation(
render_frame()->GetRoutingID());
}
void ResourceLoadingHintsAgent::DidCreateNewDocument() { void ResourceLoadingHintsAgent::DidCreateNewDocument() {
if (!IsMainFrame()) if (!IsMainFrame())
return; return;
...@@ -144,20 +126,12 @@ void ResourceLoadingHintsAgent::SetResourceLoadingHints( ...@@ -144,20 +126,12 @@ void ResourceLoadingHintsAgent::SetResourceLoadingHints(
void ResourceLoadingHintsAgent::SetCompressPublicImagesHints( void ResourceLoadingHintsAgent::SetCompressPublicImagesHints(
blink::mojom::CompressPublicImagesHintsPtr images_hints) { blink::mojom::CompressPublicImagesHintsPtr images_hints) {
if (!IsMainFrame()) if (auto* subresource_redirect_hints_agent =
return; subresource_redirect::SubresourceRedirectHintsAgent::Get(
subresource_redirect_hints_agent_.SetCompressPublicImagesHints( render_frame())) {
subresource_redirect_hints_agent->SetCompressPublicImagesHints(
std::move(images_hints)); std::move(images_hints));
}
void ResourceLoadingHintsAgent::NotifyHttpsImageCompressionFetchFailed(
base::TimeDelta retry_after) {
if (!subresource_redirect_service_remote_) {
render_frame()->GetRemoteAssociatedInterfaces()->GetInterface(
&subresource_redirect_service_remote_);
} }
subresource_redirect_service_remote_->NotifyCompressedImageFetchFailed(
retry_after);
} }
void ResourceLoadingHintsAgent::SetLiteVideoHint( void ResourceLoadingHintsAgent::SetLiteVideoHint(
......
...@@ -10,11 +10,8 @@ ...@@ -10,11 +10,8 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/optional.h" #include "base/optional.h"
#include "chrome/common/subresource_redirect_service.mojom.h"
#include "chrome/renderer/lite_video/lite_video_hint_agent.h" #include "chrome/renderer/lite_video/lite_video_hint_agent.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.h"
#include "content/public/renderer/render_frame_observer.h" #include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_frame_observer_tracker.h"
#include "mojo/public/cpp/bindings/associated_receiver.h" #include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h" #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "services/service_manager/public/cpp/interface_provider.h" #include "services/service_manager/public/cpp/interface_provider.h"
...@@ -32,29 +29,15 @@ namespace previews { ...@@ -32,29 +29,15 @@ namespace previews {
class ResourceLoadingHintsAgent class ResourceLoadingHintsAgent
: public content::RenderFrameObserver, : public content::RenderFrameObserver,
public blink::mojom::PreviewsResourceLoadingHintsReceiver, public blink::mojom::PreviewsResourceLoadingHintsReceiver,
public base::SupportsWeakPtr<ResourceLoadingHintsAgent>, public base::SupportsWeakPtr<ResourceLoadingHintsAgent> {
public content::RenderFrameObserverTracker<ResourceLoadingHintsAgent> {
public: public:
ResourceLoadingHintsAgent( ResourceLoadingHintsAgent(
blink::AssociatedInterfaceRegistry* associated_interfaces, blink::AssociatedInterfaceRegistry* associated_interfaces,
content::RenderFrame* render_frame); content::RenderFrame* render_frame);
~ResourceLoadingHintsAgent() override; ~ResourceLoadingHintsAgent() override;
subresource_redirect::SubresourceRedirectHintsAgent&
subresource_redirect_hints_agent() {
return subresource_redirect_hints_agent_;
}
// Notifies the browser process that https image compression fetch had failed.
void NotifyHttpsImageCompressionFetchFailed(base::TimeDelta retry_after);
private: private:
// content::RenderFrameObserver: // content::RenderFrameObserver:
void DidStartNavigation(
const GURL& url,
base::Optional<blink::WebNavigationType> navigation_type) override;
void ReadyToCommitNavigation(
blink::WebDocumentLoader* document_loader) override;
void DidCreateNewDocument() override; void DidCreateNewDocument() override;
void OnDestruct() override; void OnDestruct() override;
...@@ -83,13 +66,6 @@ class ResourceLoadingHintsAgent ...@@ -83,13 +66,6 @@ class ResourceLoadingHintsAgent
mojo::AssociatedReceiver<blink::mojom::PreviewsResourceLoadingHintsReceiver> mojo::AssociatedReceiver<blink::mojom::PreviewsResourceLoadingHintsReceiver>
receiver_{this}; receiver_{this};
mojo::AssociatedRemote<
subresource_redirect::mojom::SubresourceRedirectService>
subresource_redirect_service_remote_;
subresource_redirect::SubresourceRedirectHintsAgent
subresource_redirect_hints_agent_;
blink::mojom::BlinkOptimizationGuideHintsPtr blink_optimization_guide_hints_; blink::mojom::BlinkOptimizationGuideHintsPtr blink_optimization_guide_hints_;
DISALLOW_COPY_AND_ASSIGN(ResourceLoadingHintsAgent); DISALLOW_COPY_AND_ASSIGN(ResourceLoadingHintsAgent);
......
// 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.
#include "chrome/renderer/subresource_redirect/public_image_hints_url_loader_throttle.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "chrome/renderer/previews/resource_loading_hints_agent.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_params.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_util.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
#include "content/public/renderer/render_frame.h"
#include "net/base/escape.h"
#include "net/base/load_flags.h"
#include "net/http/http_status_code.h"
#include "net/http/http_util.h"
#include "services/network/public/mojom/fetch_api.mojom-shared.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/loader/previews_state.h"
#include "third_party/blink/public/platform/web_network_state_notifier.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/platform/web_url_request.h"
namespace subresource_redirect {
PublicImageHintsURLLoaderThrottle::PublicImageHintsURLLoaderThrottle(
int render_frame_id,
bool allowed_to_redirect)
: SubresourceRedirectURLLoaderThrottle(render_frame_id) {
redirect_result_ =
allowed_to_redirect
? SubresourceRedirectHintsAgent::RedirectResult::kRedirectable
: SubresourceRedirectHintsAgent::RedirectResult::
kIneligibleOtherImage;
}
PublicImageHintsURLLoaderThrottle::~PublicImageHintsURLLoaderThrottle() =
default;
SubresourceRedirectHintsAgent*
PublicImageHintsURLLoaderThrottle::GetSubresourceRedirectHintsAgent() {
return subresource_redirect::SubresourceRedirectHintsAgent::Get(
GetRenderFrame());
}
bool PublicImageHintsURLLoaderThrottle::ShouldRedirectImage(const GURL& url) {
if (redirect_result_ !=
SubresourceRedirectHintsAgent::RedirectResult::kRedirectable) {
return false;
}
auto* subresource_redirect_hints_agent = GetSubresourceRedirectHintsAgent();
if (!subresource_redirect_hints_agent)
return false;
redirect_result_ = subresource_redirect_hints_agent->ShouldRedirectImage(url);
if (redirect_result_ !=
SubresourceRedirectHintsAgent::RedirectResult::kRedirectable) {
return false;
}
return true;
}
void PublicImageHintsURLLoaderThrottle::OnRedirectedLoadCompleteWithError() {
redirect_result_ =
SubresourceRedirectHintsAgent::RedirectResult::kIneligibleOtherImage;
}
void PublicImageHintsURLLoaderThrottle::RecordMetricsOnLoadFinished(
const GURL& url,
int64_t content_length) {
auto* subresource_redirect_hints_agent = GetSubresourceRedirectHintsAgent();
if (subresource_redirect_hints_agent) {
subresource_redirect_hints_agent->RecordMetricsOnLoadFinished(
url, content_length, redirect_result_);
}
}
} // namespace subresource_redirect
// 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 CHROME_RENDERER_SUBRESOURCE_REDIRECT_PUBLIC_IMAGE_HINTS_URL_LOADER_THROTTLE_H_
#define CHROME_RENDERER_SUBRESOURCE_REDIRECT_PUBLIC_IMAGE_HINTS_URL_LOADER_THROTTLE_H_
#include "base/macros.h"
#include "base/timer/timer.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
namespace subresource_redirect {
// This class handles internal redirects for public subresouces on HTTPS sites
// to compressed versions of subresources.
class PublicImageHintsURLLoaderThrottle
: public SubresourceRedirectURLLoaderThrottle {
public:
PublicImageHintsURLLoaderThrottle(int render_frame_id,
bool allowed_to_redirect);
~PublicImageHintsURLLoaderThrottle() override;
// SubresourceRedirectURLLoaderThrottle:
bool ShouldRedirectImage(const GURL& url) override;
void OnRedirectedLoadCompleteWithError() override;
void RecordMetricsOnLoadFinished(const GURL& url,
int64_t content_length) override;
private:
friend class TestPublicImageHintsURLLoaderThrottle;
SubresourceRedirectHintsAgent* GetSubresourceRedirectHintsAgent();
// Whether the subresource can be redirected or not and what was the reason if
// its not eligible.
SubresourceRedirectHintsAgent::RedirectResult redirect_result_;
};
} // namespace subresource_redirect
#endif // CHROME_RENDERER_SUBRESOURCE_REDIRECT_PUBLIC_IMAGE_HINTS_URL_LOADER_THROTTLE_H_
...@@ -5,9 +5,13 @@ ...@@ -5,9 +5,13 @@
#include "chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.h" #include "chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.h"
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h" #include "chrome/renderer/subresource_redirect/public_image_hints_url_loader_throttle.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.h" #include "chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_util.h" #include "chrome/renderer/subresource_redirect/subresource_redirect_util.h"
#include "chrome/test/base/chrome_render_view_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_view.h"
#include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/fetch_api.mojom-shared.h" #include "services/network/public/mojom/fetch_api.mojom-shared.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -21,49 +25,59 @@ namespace subresource_redirect { ...@@ -21,49 +25,59 @@ namespace subresource_redirect {
int kRenderFrameID = 1; int kRenderFrameID = 1;
class TestSubresourceRedirectURLLoaderThrottle namespace {
: public SubresourceRedirectURLLoaderThrottle {
class SubresourceRedirectPublicImageHintsURLLoaderThrottleTest
: public ChromeRenderViewTest {
public: public:
TestSubresourceRedirectURLLoaderThrottle( void DisableSubresourceRedirectFeature() {
std::vector<std::string> public_image_urls, scoped_feature_list_.Reset();
bool allowed_to_redirect) scoped_feature_list_.InitAndDisableFeature(
: SubresourceRedirectURLLoaderThrottle(kRenderFrameID, blink::features::kSubresourceRedirect);
allowed_to_redirect) {
subresource_redirect_hints_agent_.SetCompressPublicImagesHints(
blink::mojom::CompressPublicImagesHints::New(public_image_urls));
} }
SubresourceRedirectHintsAgent* GetSubresourceRedirectHintsAgent() override { void SetCompressPublicImagesHints(
return &subresource_redirect_hints_agent_; const std::vector<std::string>& public_image_urls) {
subresource_redirect_hints_agent_->SetCompressPublicImagesHints(
blink::mojom::CompressPublicImagesHints::New(public_image_urls));
} }
private: std::unique_ptr<PublicImageHintsURLLoaderThrottle>
base::test::SingleThreadTaskEnvironment task_environment_; CreatePublicImageHintsURLLoaderThrottle(
SubresourceRedirectHintsAgent subresource_redirect_hints_agent_;
};
namespace {
std::unique_ptr<SubresourceRedirectURLLoaderThrottle>
CreateSubresourceRedirectURLLoaderThrottle(
const GURL& url, const GURL& url,
network::mojom::RequestDestination request_destination, network::mojom::RequestDestination request_destination,
int previews_state, int previews_state) {
const std::vector<std::string>& public_image_urls) {
blink::WebURLRequest request; blink::WebURLRequest request;
request.SetUrl(url); request.SetUrl(url);
request.SetPreviewsState(previews_state); request.SetPreviewsState(previews_state);
request.SetRequestDestination(request_destination); request.SetRequestDestination(request_destination);
DCHECK(SubresourceRedirectURLLoaderThrottle::MaybeCreateThrottle( DCHECK(SubresourceRedirectURLLoaderThrottle::MaybeCreateThrottle(
request, kRenderFrameID) request, view_->GetMainRenderFrame()->GetRoutingID())
.get() != nullptr); .get() != nullptr);
return std::make_unique<TestSubresourceRedirectURLLoaderThrottle>( return std::make_unique<PublicImageHintsURLLoaderThrottle>(
public_image_urls, view_->GetMainRenderFrame()->GetRoutingID(),
previews_state & blink::PreviewsTypes::SUBRESOURCE_REDIRECT_ON); previews_state & blink::PreviewsTypes::SUBRESOURCE_REDIRECT_ON);
} }
protected:
void SetUp() override {
ChromeRenderViewTest::SetUp();
scoped_feature_list_.InitWithFeaturesAndParameters(
{{blink::features::kSubresourceRedirect,
{{"enable_subresource_server_redirect", "true"}}}},
{});
subresource_redirect_hints_agent_ =
new SubresourceRedirectHintsAgent(view_->GetMainRenderFrame());
}
private:
SubresourceRedirectHintsAgent* subresource_redirect_hints_agent_;
base::test::ScopedFeatureList scoped_feature_list_;
};
TEST(SubresourceRedirectURLLoaderThrottleTest, TestMaybeCreateThrottle) { TEST_F(SubresourceRedirectPublicImageHintsURLLoaderThrottleTest,
TestMaybeCreateThrottle) {
struct TestCase { struct TestCase {
bool data_saver_enabled; bool data_saver_enabled;
bool is_subresource_redirect_feature_enabled; bool is_subresource_redirect_feature_enabled;
...@@ -96,15 +110,8 @@ TEST(SubresourceRedirectURLLoaderThrottleTest, TestMaybeCreateThrottle) { ...@@ -96,15 +110,8 @@ TEST(SubresourceRedirectURLLoaderThrottleTest, TestMaybeCreateThrottle) {
for (const TestCase& test_case : kTestCases) { for (const TestCase& test_case : kTestCases) {
blink::WebNetworkStateNotifier::SetSaveDataEnabled( blink::WebNetworkStateNotifier::SetSaveDataEnabled(
test_case.data_saver_enabled); test_case.data_saver_enabled);
base::test::ScopedFeatureList scoped_feature_list; if (!test_case.is_subresource_redirect_feature_enabled) {
if (test_case.is_subresource_redirect_feature_enabled) { DisableSubresourceRedirectFeature();
scoped_feature_list.InitWithFeaturesAndParameters(
{{blink::features::kSubresourceRedirect,
{{"enable_subresource_server_redirect", "true"}}}},
{});
} else {
scoped_feature_list.InitAndDisableFeature(
blink::features::kSubresourceRedirect);
} }
blink::WebURLRequest request; blink::WebURLRequest request;
...@@ -117,7 +124,8 @@ TEST(SubresourceRedirectURLLoaderThrottleTest, TestMaybeCreateThrottle) { ...@@ -117,7 +124,8 @@ TEST(SubresourceRedirectURLLoaderThrottleTest, TestMaybeCreateThrottle) {
} }
} }
TEST(SubresourceRedirectURLLoaderThrottleTest, TestGetSubresourceURL) { TEST_F(SubresourceRedirectPublicImageHintsURLLoaderThrottleTest,
TestGetSubresourceURL) {
struct TestCase { struct TestCase {
int previews_state; int previews_state;
GURL original_url; GURL original_url;
...@@ -158,19 +166,16 @@ TEST(SubresourceRedirectURLLoaderThrottleTest, TestGetSubresourceURL) { ...@@ -158,19 +166,16 @@ TEST(SubresourceRedirectURLLoaderThrottleTest, TestGetSubresourceURL) {
}, },
}; };
blink::WebNetworkStateNotifier::SetSaveDataEnabled(true); blink::WebNetworkStateNotifier::SetSaveDataEnabled(true);
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeaturesAndParameters(
{{blink::features::kSubresourceRedirect,
{{"enable_subresource_server_redirect", "true"}}}},
{});
for (const TestCase& test_case : kTestCases) { SetCompressPublicImagesHints(
auto throttle = CreateSubresourceRedirectURLLoaderThrottle(
test_case.original_url, network::mojom::RequestDestination::kImage,
test_case.previews_state,
{"https://www.test.com/public_img.jpg", {"https://www.test.com/public_img.jpg",
"https://www.test.com/public_img.jpg#anchor", "https://www.test.com/public_img.jpg#anchor",
"https://www.test.com/public_img.jpg?public_arg1=bar&public_arg2"}); "https://www.test.com/public_img.jpg?public_arg1=bar&public_arg2"});
for (const TestCase& test_case : kTestCases) {
auto throttle = CreatePublicImageHintsURLLoaderThrottle(
test_case.original_url, network::mojom::RequestDestination::kImage,
test_case.previews_state);
network::ResourceRequest request; network::ResourceRequest request;
request.url = test_case.original_url; request.url = test_case.original_url;
request.destination = network::mojom::RequestDestination::kImage; request.destination = network::mojom::RequestDestination::kImage;
...@@ -187,19 +192,16 @@ TEST(SubresourceRedirectURLLoaderThrottleTest, TestGetSubresourceURL) { ...@@ -187,19 +192,16 @@ TEST(SubresourceRedirectURLLoaderThrottleTest, TestGetSubresourceURL) {
} }
} }
TEST(SubresourceRedirectURLLoaderThrottleTest, DeferOverridenToFalse) { TEST_F(SubresourceRedirectPublicImageHintsURLLoaderThrottleTest,
DeferOverridenToFalse) {
blink::WebNetworkStateNotifier::SetSaveDataEnabled(true); blink::WebNetworkStateNotifier::SetSaveDataEnabled(true);
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeaturesAndParameters(
{{blink::features::kSubresourceRedirect,
{{"enable_subresource_server_redirect", "true"}}}},
{});
auto throttle = CreateSubresourceRedirectURLLoaderThrottle( SetCompressPublicImagesHints({"https://www.test.com/test.jpg"});
auto throttle = CreatePublicImageHintsURLLoaderThrottle(
GURL("https://www.test.com/test.jpg"), GURL("https://www.test.com/test.jpg"),
network::mojom::RequestDestination::kImage, network::mojom::RequestDestination::kImage,
blink::PreviewsTypes::SUBRESOURCE_REDIRECT_ON, blink::PreviewsTypes::SUBRESOURCE_REDIRECT_ON);
{"https://www.test.com/test.jpg"});
network::ResourceRequest request; network::ResourceRequest request;
request.url = GURL("https://www.test.com/test.jpg"); request.url = GURL("https://www.test.com/test.jpg");
request.destination = network::mojom::RequestDestination::kImage; request.destination = network::mojom::RequestDestination::kImage;
......
...@@ -3,36 +3,39 @@ ...@@ -3,36 +3,39 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.h" #include "chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.h"
#include "base/metrics/field_trial_params.h" #include "base/metrics/field_trial_params.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_params.h"
#include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_thread.h"
#include "services/metrics/public/cpp/metrics_utils.h" #include "services/metrics/public/cpp/metrics_utils.h"
#include "services/metrics/public/cpp/mojo_ukm_recorder.h" #include "services/metrics/public/cpp/mojo_ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_builders.h" #include "services/metrics/public/cpp/ukm_builders.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_local_frame.h"
namespace subresource_redirect { namespace subresource_redirect {
namespace { SubresourceRedirectHintsAgent::SubresourceRedirectHintsAgent(
content::RenderFrame* render_frame)
// Default timeout for the hints to be received from the time navigation starts. : content::RenderFrameObserver(render_frame),
const int64_t kHintsReceiveDefaultTimeoutSeconds = 5; content::RenderFrameObserverTracker<SubresourceRedirectHintsAgent>(
render_frame) {
// Returns the hinte receive timeout value from field trial. DCHECK(render_frame);
int64_t GetHintsReceiveTimeout() { DCHECK(IsPublicImageHintsBasedCompressionEnabled());
return base::GetFieldTrialParamByFeatureAsInt(
blink::features::kSubresourceRedirect, "hints_receive_timeout",
kHintsReceiveDefaultTimeoutSeconds);
} }
} // namespace
SubresourceRedirectHintsAgent::SubresourceRedirectHintsAgent() = default;
SubresourceRedirectHintsAgent::~SubresourceRedirectHintsAgent() = default; SubresourceRedirectHintsAgent::~SubresourceRedirectHintsAgent() = default;
void SubresourceRedirectHintsAgent::DidStartNavigation() { bool SubresourceRedirectHintsAgent::IsMainFrame() const {
return render_frame()->IsMainFrame();
}
void SubresourceRedirectHintsAgent::DidStartNavigation(
const GURL& url,
base::Optional<blink::WebNavigationType> navigation_type) {
if (!IsMainFrame())
return;
// Clear the hints when a navigation starts, so that hints from previous // Clear the hints when a navigation starts, so that hints from previous
// navigation do not apply in case the same renderframe is reused. // navigation do not apply in case the same renderframe is reused.
public_image_urls_.clear(); public_image_urls_.clear();
...@@ -40,7 +43,9 @@ void SubresourceRedirectHintsAgent::DidStartNavigation() { ...@@ -40,7 +43,9 @@ void SubresourceRedirectHintsAgent::DidStartNavigation() {
} }
void SubresourceRedirectHintsAgent::ReadyToCommitNavigation( void SubresourceRedirectHintsAgent::ReadyToCommitNavigation(
int render_frame_id) { blink::WebDocumentLoader* document_loader) {
if (!IsMainFrame())
return;
// Its ok to use base::Unretained(this) here since the timer object is owned // Its ok to use base::Unretained(this) here since the timer object is owned
// by |this|, and the timer and its callback will get deleted when |this| is // by |this|, and the timer and its callback will get deleted when |this| is
// destroyed. // destroyed.
...@@ -48,11 +53,16 @@ void SubresourceRedirectHintsAgent::ReadyToCommitNavigation( ...@@ -48,11 +53,16 @@ void SubresourceRedirectHintsAgent::ReadyToCommitNavigation(
FROM_HERE, base::TimeDelta::FromSeconds(GetHintsReceiveTimeout()), FROM_HERE, base::TimeDelta::FromSeconds(GetHintsReceiveTimeout()),
base::BindOnce(&SubresourceRedirectHintsAgent::OnHintsReceiveTimeout, base::BindOnce(&SubresourceRedirectHintsAgent::OnHintsReceiveTimeout,
base::Unretained(this))); base::Unretained(this)));
render_frame_id_ = render_frame_id; }
void SubresourceRedirectHintsAgent::OnDestruct() {
delete this;
} }
void SubresourceRedirectHintsAgent::SetCompressPublicImagesHints( void SubresourceRedirectHintsAgent::SetCompressPublicImagesHints(
blink::mojom::CompressPublicImagesHintsPtr images_hints) { blink::mojom::CompressPublicImagesHintsPtr images_hints) {
if (!IsMainFrame())
return;
DCHECK(public_image_urls_.empty()); DCHECK(public_image_urls_.empty());
DCHECK(!public_image_urls_received_); DCHECK(!public_image_urls_received_);
public_image_urls_ = images_hints->image_urls; public_image_urls_ = images_hints->image_urls;
...@@ -99,14 +109,12 @@ void SubresourceRedirectHintsAgent::ClearImageHints() { ...@@ -99,14 +109,12 @@ void SubresourceRedirectHintsAgent::ClearImageHints() {
void SubresourceRedirectHintsAgent::RecordMetrics( void SubresourceRedirectHintsAgent::RecordMetrics(
int64_t content_length, int64_t content_length,
RedirectResult redirect_result) const { RedirectResult redirect_result) const {
content::RenderFrame* render_frame = if (!render_frame() || !render_frame()->GetWebFrame())
content::RenderFrame::FromRoutingID(render_frame_id_);
if (!render_frame || !render_frame->GetWebFrame())
return; return;
ukm::builders::PublicImageCompressionDataUse ukm::builders::PublicImageCompressionDataUse
public_image_compression_data_use( public_image_compression_data_use(
render_frame->GetWebFrame()->GetDocument().GetUkmSourceId()); render_frame()->GetWebFrame()->GetDocument().GetUkmSourceId());
content_length = ukm::GetExponentialBucketMin(content_length, 1.3); content_length = ukm::GetExponentialBucketMin(content_length, 1.3);
switch (redirect_result) { switch (redirect_result) {
...@@ -166,4 +174,15 @@ void SubresourceRedirectHintsAgent::RecordImageHintsUnavailableMetrics() { ...@@ -166,4 +174,15 @@ void SubresourceRedirectHintsAgent::RecordImageHintsUnavailableMetrics() {
unavailable_image_hints_urls_.clear(); unavailable_image_hints_urls_.clear();
} }
void SubresourceRedirectHintsAgent::NotifyHttpsImageCompressionFetchFailed(
base::TimeDelta retry_after) {
if (!subresource_redirect_service_remote_) {
render_frame()->GetRemoteAssociatedInterfaces()->GetInterface(
&subresource_redirect_service_remote_);
}
subresource_redirect_service_remote_->NotifyCompressedImageFetchFailed(
retry_after);
ClearImageHints();
}
} // namespace subresource_redirect } // namespace subresource_redirect
...@@ -7,16 +7,24 @@ ...@@ -7,16 +7,24 @@
#include "base/containers/flat_set.h" #include "base/containers/flat_set.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/optional.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "chrome/common/subresource_redirect_service.mojom.h" #include "chrome/common/subresource_redirect_service.mojom.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_frame_observer_tracker.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "third_party/blink/public/mojom/loader/previews_resource_loading_hints.mojom.h" #include "third_party/blink/public/mojom/loader/previews_resource_loading_hints.mojom.h"
#include "url/gurl.h" #include "url/gurl.h"
namespace subresource_redirect { namespace subresource_redirect {
// Holds the public image URL hints to be queried by URL loader throttles. Only // Holds the public image URL hints to be queried by URL loader throttles. Only
// created for mainframes. // redirects public images for mainframes.
class SubresourceRedirectHintsAgent { class SubresourceRedirectHintsAgent
: public content::RenderFrameObserver,
public content::RenderFrameObserverTracker<
SubresourceRedirectHintsAgent> {
public: public:
enum class RedirectResult { enum class RedirectResult {
// The image was found in the image hints and is eligible to be redirected // The image was found in the image hints and is eligible to be redirected
...@@ -47,21 +55,13 @@ class SubresourceRedirectHintsAgent { ...@@ -47,21 +55,13 @@ class SubresourceRedirectHintsAgent {
kIneligibleOtherImage kIneligibleOtherImage
}; };
SubresourceRedirectHintsAgent(); explicit SubresourceRedirectHintsAgent(content::RenderFrame* render_frame);
~SubresourceRedirectHintsAgent(); ~SubresourceRedirectHintsAgent() override;
SubresourceRedirectHintsAgent(const SubresourceRedirectHintsAgent&) = delete; SubresourceRedirectHintsAgent(const SubresourceRedirectHintsAgent&) = delete;
SubresourceRedirectHintsAgent& operator=( SubresourceRedirectHintsAgent& operator=(
const SubresourceRedirectHintsAgent&) = delete; const SubresourceRedirectHintsAgent&) = delete;
// Called when a navigation starts to clear the state from previous
// navigation.
void DidStartNavigation();
void ReadyToCommitNavigation(int render_frame_id);
void SetCompressPublicImagesHints(
blink::mojom::CompressPublicImagesHintsPtr images_hints);
RedirectResult ShouldRedirectImage(const GURL& url) const; RedirectResult ShouldRedirectImage(const GURL& url) const;
// Record metrics when the resource load is finished. // Record metrics when the resource load is finished.
...@@ -69,11 +69,28 @@ class SubresourceRedirectHintsAgent { ...@@ -69,11 +69,28 @@ class SubresourceRedirectHintsAgent {
int64_t content_length, int64_t content_length,
RedirectResult redirect_result); RedirectResult redirect_result);
void SetCompressPublicImagesHints(
blink::mojom::CompressPublicImagesHintsPtr images_hints);
// Notifies the browser process that https image compression fetch had failed.
void NotifyHttpsImageCompressionFetchFailed(base::TimeDelta retry_after);
// Clears the image hint urls. // Clears the image hint urls.
void ClearImageHints(); void ClearImageHints();
private: private:
// content::RenderFrameObserver:
void DidStartNavigation(
const GURL& url,
base::Optional<blink::WebNavigationType> navigation_type) override;
void ReadyToCommitNavigation(
blink::WebDocumentLoader* document_loader) override;
void OnDestruct() override;
bool IsMainFrame() const;
void OnHintsReceiveTimeout(); void OnHintsReceiveTimeout();
void RecordMetrics(int64_t content_length, void RecordMetrics(int64_t content_length,
RedirectResult redirect_result) const; RedirectResult redirect_result) const;
...@@ -94,9 +111,9 @@ class SubresourceRedirectHintsAgent { ...@@ -94,9 +111,9 @@ class SubresourceRedirectHintsAgent {
// until hints are received or it times out and used to record metrics. // until hints are received or it times out and used to record metrics.
base::flat_set<std::pair<std::string, int64_t>> unavailable_image_hints_urls_; base::flat_set<std::pair<std::string, int64_t>> unavailable_image_hints_urls_;
// ID of the current render frame (will be main frame). Populated when the mojo::AssociatedRemote<
// navigation commits. Used to record ukm against. subresource_redirect::mojom::SubresourceRedirectService>
int render_frame_id_; subresource_redirect_service_remote_;
}; };
} // namespace subresource_redirect } // namespace subresource_redirect
......
...@@ -12,6 +12,16 @@ ...@@ -12,6 +12,16 @@
namespace subresource_redirect { namespace subresource_redirect {
namespace {
// Default timeout for the hints to be received from the time navigation starts.
const int64_t kHintsReceiveDefaultTimeoutSeconds = 5;
bool IsSubresourceRedirectEnabled() {
return base::FeatureList::IsEnabled(blink::features::kSubresourceRedirect);
}
} // namespace
url::Origin GetSubresourceRedirectOrigin() { url::Origin GetSubresourceRedirectOrigin() {
auto lite_page_subresource_origin = base::GetFieldTrialParamValueByFeature( auto lite_page_subresource_origin = base::GetFieldTrialParamValueByFeature(
blink::features::kSubresourceRedirect, "lite_page_subresource_origin"); blink::features::kSubresourceRedirect, "lite_page_subresource_origin");
...@@ -20,4 +30,30 @@ url::Origin GetSubresourceRedirectOrigin() { ...@@ -20,4 +30,30 @@ url::Origin GetSubresourceRedirectOrigin() {
return url::Origin::Create(GURL(lite_page_subresource_origin)); return url::Origin::Create(GURL(lite_page_subresource_origin));
} }
bool IsPublicImageHintsBasedCompressionEnabled() {
return IsSubresourceRedirectEnabled() &&
base::GetFieldTrialParamByFeatureAsBool(
blink::features::kSubresourceRedirect,
"enable_public_image_hints_based_compression", true);
}
bool ShouldCompressionServerRedirectSubresource() {
return base::GetFieldTrialParamByFeatureAsBool(
blink::features::kSubresourceRedirect,
"enable_subresource_server_redirect", true);
}
base::TimeDelta GetCompressionRedirectTimeout() {
return base::TimeDelta::FromMilliseconds(
base::GetFieldTrialParamByFeatureAsInt(
blink::features::kSubresourceRedirect, "subresource_redirect_timeout",
5000));
}
int64_t GetHintsReceiveTimeout() {
return base::GetFieldTrialParamByFeatureAsInt(
blink::features::kSubresourceRedirect, "hints_receive_timeout",
kHintsReceiveDefaultTimeoutSeconds);
}
} // namespace subresource_redirect } // namespace subresource_redirect
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <string> #include <string>
#include "base/time/time.h"
#include "url/origin.h" #include "url/origin.h"
namespace subresource_redirect { namespace subresource_redirect {
...@@ -15,6 +16,21 @@ namespace subresource_redirect { ...@@ -15,6 +16,21 @@ namespace subresource_redirect {
// default. // default.
url::Origin GetSubresourceRedirectOrigin(); url::Origin GetSubresourceRedirectOrigin();
// Returns if the public image hints based subresource compression is enabled.
bool IsPublicImageHintsBasedCompressionEnabled();
// Should the subresource be redirected to its compressed version. This returns
// false if only coverage metrics need to be recorded and actual redirection
// should not happen.
bool ShouldCompressionServerRedirectSubresource();
// Returns the timeout for the compressed subresource redirect, after which the
// subresource should be fetched directly from the origin.
base::TimeDelta GetCompressionRedirectTimeout();
// Returns the public image hinte receive timeout value from field trial.
int64_t GetHintsReceiveTimeout();
} // namespace subresource_redirect } // namespace subresource_redirect
#endif // CHROME_RENDERER_SUBRESOURCE_REDIRECT_SUBRESOURCE_REDIRECT_PARAMS_H_ #endif // CHROME_RENDERER_SUBRESOURCE_REDIRECT_SUBRESOURCE_REDIRECT_PARAMS_H_
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "chrome/renderer/previews/resource_loading_hints_agent.h" #include "chrome/renderer/previews/resource_loading_hints_agent.h"
#include "chrome/renderer/subresource_redirect/public_image_hints_url_loader_throttle.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_params.h" #include "chrome/renderer/subresource_redirect/subresource_redirect_params.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_util.h" #include "chrome/renderer/subresource_redirect/subresource_redirect_util.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
...@@ -19,7 +20,6 @@ ...@@ -19,7 +20,6 @@
#include "net/http/http_util.h" #include "net/http/http_util.h"
#include "services/network/public/mojom/fetch_api.mojom-shared.h" #include "services/network/public/mojom/fetch_api.mojom-shared.h"
#include "services/network/public/mojom/url_response_head.mojom.h" #include "services/network/public/mojom/url_response_head.mojom.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/loader/previews_state.h" #include "third_party/blink/public/common/loader/previews_state.h"
#include "third_party/blink/public/platform/web_network_state_notifier.h" #include "third_party/blink/public/platform/web_network_state_notifier.h"
#include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/platform/web_url.h"
...@@ -37,22 +37,6 @@ bool IsCompressionServerOrigin(const GURL& url) { ...@@ -37,22 +37,6 @@ bool IsCompressionServerOrigin(const GURL& url) {
(url.scheme() == compression_server.scheme()); (url.scheme() == compression_server.scheme());
} }
// Should the subresource be redirected to its compressed version. This returns
// false if only coverage metrics need to be recorded and actual redirection
// should not happen.
bool ShouldCompressionServerRedirectSubresource() {
return base::GetFieldTrialParamByFeatureAsBool(
blink::features::kSubresourceRedirect,
"enable_subresource_server_redirect", true);
}
base::TimeDelta GetCompressionRedirectTimeout() {
return base::TimeDelta::FromMilliseconds(
base::GetFieldTrialParamByFeatureAsInt(
blink::features::kSubresourceRedirect, "subresource_redirect_timeout",
5000));
}
} // namespace } // namespace
// static // static
...@@ -60,7 +44,7 @@ std::unique_ptr<SubresourceRedirectURLLoaderThrottle> ...@@ -60,7 +44,7 @@ std::unique_ptr<SubresourceRedirectURLLoaderThrottle>
SubresourceRedirectURLLoaderThrottle::MaybeCreateThrottle( SubresourceRedirectURLLoaderThrottle::MaybeCreateThrottle(
const blink::WebURLRequest& request, const blink::WebURLRequest& request,
int render_frame_id) { int render_frame_id) {
if (base::FeatureList::IsEnabled(blink::features::kSubresourceRedirect) && if (IsPublicImageHintsBasedCompressionEnabled() &&
request.GetRequestDestination() == request.GetRequestDestination() ==
network::mojom::RequestDestination::kImage && network::mojom::RequestDestination::kImage &&
request.Url().ProtocolIs(url::kHttpsScheme) && request.Url().ProtocolIs(url::kHttpsScheme) &&
...@@ -68,7 +52,7 @@ SubresourceRedirectURLLoaderThrottle::MaybeCreateThrottle( ...@@ -68,7 +52,7 @@ SubresourceRedirectURLLoaderThrottle::MaybeCreateThrottle(
request.GetRequestContext() != request.GetRequestContext() !=
blink::mojom::RequestContextType::FAVICON) { blink::mojom::RequestContextType::FAVICON) {
return base::WrapUnique<SubresourceRedirectURLLoaderThrottle>( return base::WrapUnique<SubresourceRedirectURLLoaderThrottle>(
new SubresourceRedirectURLLoaderThrottle( new PublicImageHintsURLLoaderThrottle(
render_frame_id, request.GetPreviewsState() & render_frame_id, request.GetPreviewsState() &
blink::PreviewsTypes::kSubresourceRedirectOn)); blink::PreviewsTypes::kSubresourceRedirectOn));
} }
...@@ -76,15 +60,8 @@ SubresourceRedirectURLLoaderThrottle::MaybeCreateThrottle( ...@@ -76,15 +60,8 @@ SubresourceRedirectURLLoaderThrottle::MaybeCreateThrottle(
} }
SubresourceRedirectURLLoaderThrottle::SubresourceRedirectURLLoaderThrottle( SubresourceRedirectURLLoaderThrottle::SubresourceRedirectURLLoaderThrottle(
int render_frame_id, int render_frame_id)
bool allowed_to_redirect) : render_frame_id_(render_frame_id) {}
: render_frame_id_(render_frame_id) {
redirect_result_ =
allowed_to_redirect
? SubresourceRedirectHintsAgent::RedirectResult::kRedirectable
: SubresourceRedirectHintsAgent::RedirectResult::
kIneligibleOtherImage;
}
SubresourceRedirectURLLoaderThrottle::~SubresourceRedirectURLLoaderThrottle() = SubresourceRedirectURLLoaderThrottle::~SubresourceRedirectURLLoaderThrottle() =
default; default;
...@@ -92,33 +69,17 @@ SubresourceRedirectURLLoaderThrottle::~SubresourceRedirectURLLoaderThrottle() = ...@@ -92,33 +69,17 @@ SubresourceRedirectURLLoaderThrottle::~SubresourceRedirectURLLoaderThrottle() =
void SubresourceRedirectURLLoaderThrottle::WillStartRequest( void SubresourceRedirectURLLoaderThrottle::WillStartRequest(
network::ResourceRequest* request, network::ResourceRequest* request,
bool* defer) { bool* defer) {
DCHECK(base::FeatureList::IsEnabled(blink::features::kSubresourceRedirect)); DCHECK(IsPublicImageHintsBasedCompressionEnabled());
DCHECK_EQ(request->destination, network::mojom::RequestDestination::kImage); DCHECK_EQ(request->destination, network::mojom::RequestDestination::kImage);
DCHECK(
request->previews_state & blink::PreviewsTypes::SUBRESOURCE_REDIRECT_ON ||
redirect_result_ ==
SubresourceRedirectHintsAgent::RedirectResult::kIneligibleOtherImage);
DCHECK(request->url.SchemeIs(url::kHttpsScheme)); DCHECK(request->url.SchemeIs(url::kHttpsScheme));
// Do not redirect if its already a litepage subresource. // Do not redirect if its already a litepage subresource.
if (IsCompressionServerOrigin(request->url)) if (IsCompressionServerOrigin(request->url))
return; return;
if (redirect_result_ != if (!ShouldRedirectImage(request->url))
SubresourceRedirectHintsAgent::RedirectResult::kRedirectable) {
return;
}
auto* subresource_redirect_hints_agent = GetSubresourceRedirectHintsAgent();
if (!subresource_redirect_hints_agent)
return; return;
redirect_result_ =
subresource_redirect_hints_agent->ShouldRedirectImage(request->url);
if (redirect_result_ !=
SubresourceRedirectHintsAgent::RedirectResult::kRedirectable) {
return;
}
if (!ShouldCompressionServerRedirectSubresource()) if (!ShouldCompressionServerRedirectSubresource())
return; return;
...@@ -134,24 +95,6 @@ void SubresourceRedirectURLLoaderThrottle::WillStartRequest( ...@@ -134,24 +95,6 @@ void SubresourceRedirectURLLoaderThrottle::WillStartRequest(
base::Unretained(this))); base::Unretained(this)));
} }
previews::ResourceLoadingHintsAgent*
SubresourceRedirectURLLoaderThrottle::GetResourceLoadingHintsAgent() {
// The ResourceLoadingHintsAgent is main-frame only.
if (content::RenderFrame* render_frame =
content::RenderFrame::FromRoutingID(render_frame_id_)) {
return previews::ResourceLoadingHintsAgent::Get(render_frame);
}
return nullptr;
}
SubresourceRedirectHintsAgent*
SubresourceRedirectURLLoaderThrottle::GetSubresourceRedirectHintsAgent() {
if (auto* resource_loading_hints_agent = GetResourceLoadingHintsAgent()) {
return &resource_loading_hints_agent->subresource_redirect_hints_agent();
}
return nullptr;
}
void SubresourceRedirectURLLoaderThrottle::WillRedirectRequest( void SubresourceRedirectURLLoaderThrottle::WillRedirectRequest(
net::RedirectInfo* redirect_info, net::RedirectInfo* redirect_info,
const network::mojom::URLResponseHead& response_head, const network::mojom::URLResponseHead& response_head,
...@@ -196,8 +139,7 @@ void SubresourceRedirectURLLoaderThrottle::BeforeWillProcessResponse( ...@@ -196,8 +139,7 @@ void SubresourceRedirectURLLoaderThrottle::BeforeWillProcessResponse(
response_head.headers->response_code() == 304) { response_head.headers->response_code() == 304) {
return; return;
} }
redirect_result_ = OnRedirectedLoadCompleteWithError();
SubresourceRedirectHintsAgent::RedirectResult::kIneligibleOtherImage;
// 503 response code indicates loadshed from the compression server. Notify // 503 response code indicates loadshed from the compression server. Notify
// the browser process which will bypass subresource redirect for subsequent // the browser process which will bypass subresource redirect for subsequent
...@@ -211,8 +153,9 @@ void SubresourceRedirectURLLoaderThrottle::BeforeWillProcessResponse( ...@@ -211,8 +153,9 @@ void SubresourceRedirectURLLoaderThrottle::BeforeWillProcessResponse(
net::HttpUtil::ParseRetryAfterHeader(retry_after_string, net::HttpUtil::ParseRetryAfterHeader(retry_after_string,
base::Time::Now(), &retry_after); base::Time::Now(), &retry_after);
} }
if (auto* resource_loading_hints_agent = GetResourceLoadingHintsAgent()) { if (auto* subresource_redirect_hints_agent =
resource_loading_hints_agent->NotifyHttpsImageCompressionFetchFailed( SubresourceRedirectHintsAgent::Get(GetRenderFrame())) {
subresource_redirect_hints_agent->NotifyHttpsImageCompressionFetchFailed(
retry_after); retry_after);
} }
} }
...@@ -236,11 +179,7 @@ void SubresourceRedirectURLLoaderThrottle::WillProcessResponse( ...@@ -236,11 +179,7 @@ void SubresourceRedirectURLLoaderThrottle::WillProcessResponse(
if (content_length < 0) if (content_length < 0)
return; return;
auto* subresource_redirect_hints_agent = GetSubresourceRedirectHintsAgent(); RecordMetricsOnLoadFinished(response_url, content_length);
if (subresource_redirect_hints_agent) {
subresource_redirect_hints_agent->RecordMetricsOnLoadFinished(
response_url, content_length, redirect_result_);
}
if (!did_redirect_compressed_origin_) if (!did_redirect_compressed_origin_)
return; return;
...@@ -276,8 +215,7 @@ void SubresourceRedirectURLLoaderThrottle::WillOnCompleteWithError( ...@@ -276,8 +215,7 @@ void SubresourceRedirectURLLoaderThrottle::WillOnCompleteWithError(
if (!did_redirect_compressed_origin_) if (!did_redirect_compressed_origin_)
return; return;
DCHECK(ShouldCompressionServerRedirectSubresource()); DCHECK(ShouldCompressionServerRedirectSubresource());
redirect_result_ = OnRedirectedLoadCompleteWithError();
SubresourceRedirectHintsAgent::RedirectResult::kIneligibleOtherImage;
// If the server fails, restart the request to the original resource, and // If the server fails, restart the request to the original resource, and
// record it. // record it.
...@@ -292,11 +230,10 @@ void SubresourceRedirectURLLoaderThrottle::OnRedirectTimeout() { ...@@ -292,11 +230,10 @@ void SubresourceRedirectURLLoaderThrottle::OnRedirectTimeout() {
DCHECK(did_redirect_compressed_origin_); DCHECK(did_redirect_compressed_origin_);
did_redirect_compressed_origin_ = false; did_redirect_compressed_origin_ = false;
delegate_->RestartWithURLResetAndFlagsNow(net::LOAD_NORMAL); delegate_->RestartWithURLResetAndFlagsNow(net::LOAD_NORMAL);
if (auto* resource_loading_hints_agent = GetResourceLoadingHintsAgent()) { if (auto* subresource_redirect_hints_agent =
resource_loading_hints_agent->NotifyHttpsImageCompressionFetchFailed( SubresourceRedirectHintsAgent::Get(GetRenderFrame())) {
subresource_redirect_hints_agent->NotifyHttpsImageCompressionFetchFailed(
base::TimeDelta()); base::TimeDelta());
resource_loading_hints_agent->subresource_redirect_hints_agent()
.ClearImageHints();
} }
UMA_HISTOGRAM_BOOLEAN("SubresourceRedirect.CompressionFetchTimeout", true); UMA_HISTOGRAM_BOOLEAN("SubresourceRedirect.CompressionFetchTimeout", true);
} }
......
...@@ -7,36 +7,27 @@ ...@@ -7,36 +7,27 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.h" #include "content/public/renderer/render_frame.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h" #include "third_party/blink/public/common/loader/url_loader_throttle.h"
namespace blink { namespace blink {
class WebURLRequest; class WebURLRequest;
} // namespace blink } // namespace blink
namespace previews {
class ResourceLoadingHintsAgent;
} // namespace previews
namespace subresource_redirect { namespace subresource_redirect {
class SubresourceRedirectHintsAgent; // This class handles internal redirects for HTTPS public subresources
// (currently only for images) compressed versions of subresources. When the
// This class handles internal redirects for subresouces on HTTPS sites to // redirect fails/timesout the original image is fetched directly. Subclasses
// compressed versions of subresources. // should implement the decider logic if an URL should be compressed.
class SubresourceRedirectURLLoaderThrottle : public blink::URLLoaderThrottle { class SubresourceRedirectURLLoaderThrottle : public blink::URLLoaderThrottle {
public: public:
static std::unique_ptr<SubresourceRedirectURLLoaderThrottle> static std::unique_ptr<SubresourceRedirectURLLoaderThrottle>
MaybeCreateThrottle(const blink::WebURLRequest& request, MaybeCreateThrottle(const blink::WebURLRequest& request, int render_frame_id);
int render_frame_id);
explicit SubresourceRedirectURLLoaderThrottle(int render_frame_id);
~SubresourceRedirectURLLoaderThrottle() override; ~SubresourceRedirectURLLoaderThrottle() override;
previews::ResourceLoadingHintsAgent* GetResourceLoadingHintsAgent();
// virtual for testing.
virtual SubresourceRedirectHintsAgent* GetSubresourceRedirectHintsAgent();
// blink::URLLoaderThrottle: // blink::URLLoaderThrottle:
void WillStartRequest(network::ResourceRequest* request, void WillStartRequest(network::ResourceRequest* request,
bool* defer) override; bool* defer) override;
...@@ -59,11 +50,24 @@ class SubresourceRedirectURLLoaderThrottle : public blink::URLLoaderThrottle { ...@@ -59,11 +50,24 @@ class SubresourceRedirectURLLoaderThrottle : public blink::URLLoaderThrottle {
// Overridden to do nothing as the default implementation is NOT_REACHED() // Overridden to do nothing as the default implementation is NOT_REACHED()
void DetachFromCurrentSequence() override; void DetachFromCurrentSequence() override;
private: // Return whether the image url should be redirected.
friend class TestSubresourceRedirectURLLoaderThrottle; virtual bool ShouldRedirectImage(const GURL& url) = 0;
SubresourceRedirectURLLoaderThrottle(int render_frame_id, // Indicates the subresource redirect failed, and the image will be fetched
bool allowed_to_redirect); // directly from the origin instead. The failures can be due to non-2xx http
// responses or other net errors
virtual void OnRedirectedLoadCompleteWithError() = 0;
// Notifies the image load finished.
virtual void RecordMetricsOnLoadFinished(const GURL& url,
int64_t content_length) = 0;
content::RenderFrame* GetRenderFrame() const {
return content::RenderFrame::FromRoutingID(render_frame_id_);
}
private:
friend class TestPublicImageHintsURLLoaderThrottle;
// Callback invoked when the redirect fetch times out. // Callback invoked when the redirect fetch times out.
void OnRedirectTimeout(); void OnRedirectTimeout();
...@@ -71,10 +75,6 @@ class SubresourceRedirectURLLoaderThrottle : public blink::URLLoaderThrottle { ...@@ -71,10 +75,6 @@ class SubresourceRedirectURLLoaderThrottle : public blink::URLLoaderThrottle {
// Render frame id to get the hints agent of the render frame. // Render frame id to get the hints agent of the render frame.
const int render_frame_id_; const int render_frame_id_;
// Whether the subresource can be redirected or not and what was the reason if
// its not eligible.
SubresourceRedirectHintsAgent::RedirectResult redirect_result_;
// Whether this resource was actually redirected to compressed server origin. // Whether this resource was actually redirected to compressed server origin.
// This will be true when the redirect was attempted. Will be false when // This will be true when the redirect was attempted. Will be false when
// redirect failed due to neterrors, or redirect was not attempted (but // redirect failed due to neterrors, or redirect was not attempted (but
......
...@@ -1550,6 +1550,7 @@ if (!is_android) { ...@@ -1550,6 +1550,7 @@ if (!is_android) {
"../renderer/chrome_content_settings_agent_delegate_browsertest.cc", "../renderer/chrome_content_settings_agent_delegate_browsertest.cc",
"../renderer/chrome_render_frame_observer_browsertest.cc", "../renderer/chrome_render_frame_observer_browsertest.cc",
"../renderer/lite_video/lite_video_hint_agent_browsertest.cc", "../renderer/lite_video/lite_video_hint_agent_browsertest.cc",
"../renderer/subresource_redirect/public_image_hints_url_loader_throttle_browsertest.cc",
"../renderer/translate/per_frame_translate_agent_browsertest.cc", "../renderer/translate/per_frame_translate_agent_browsertest.cc",
"../renderer/translate/translate_agent_browsertest.cc", "../renderer/translate/translate_agent_browsertest.cc",
"../renderer/translate/translate_script_browsertest.cc", "../renderer/translate/translate_script_browsertest.cc",
...@@ -3779,7 +3780,6 @@ test("unit_tests") { ...@@ -3779,7 +3780,6 @@ test("unit_tests") {
"../renderer/media/flash_embed_rewrite_unittest.cc", "../renderer/media/flash_embed_rewrite_unittest.cc",
"../renderer/net/net_error_helper_core_unittest.cc", "../renderer/net/net_error_helper_core_unittest.cc",
"../renderer/plugins/plugin_uma_unittest.cc", "../renderer/plugins/plugin_uma_unittest.cc",
"../renderer/subresource_redirect/subresource_redirect_url_loader_throttle_unittest.cc",
"../renderer/subresource_redirect/subresource_redirect_util_unittest.cc", "../renderer/subresource_redirect/subresource_redirect_util_unittest.cc",
"../renderer/v8_unwinder_unittest.cc", "../renderer/v8_unwinder_unittest.cc",
"../test/base/chrome_render_view_test.cc", "../test/base/chrome_render_view_test.cc",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment