Commit 294b742e authored by Charlie Harrison's avatar Charlie Harrison Committed by Commit Bot

[ad-delay] Delay insecure ad subresources

This CL adds a URLLoaderThrottle to renderer subresource requests
that delays the navigation by a fixed amount (default 50ms) if it
detects that the resource request is an insecure (e.g. http) ad
request.

The URLLoaderThrottle will be re-used in the browser process for
subframe navigations, so care has been made to fit it in the
content/common layer.

Some other misc changes to make this happen / testable:
 - Add IsAdResource() to blink::WebURLRequest
 - URLLoaderThrottleProvider changed to take a full blink::WebURLRequest
   instead of a blink::WebURL.
 - TestURLLoaderFactory extended to support redirects.
 - ThrottlingURLLoader partly exposed to content/public/test.

Bug: 829042
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo
Change-Id: Ia98891ed8c07a3c85e1f9986c29d841698ed9228
Reviewed-on: https://chromium-review.googlesource.com/994152
Commit-Queue: Charlie Harrison <csharrison@chromium.org>
Reviewed-by: default avatarJosh Karlin <jkarlin@chromium.org>
Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#549300}
parent 5bdaddb5
...@@ -37,7 +37,7 @@ AwURLLoaderThrottleProvider::~AwURLLoaderThrottleProvider() { ...@@ -37,7 +37,7 @@ AwURLLoaderThrottleProvider::~AwURLLoaderThrottleProvider() {
std::vector<std::unique_ptr<content::URLLoaderThrottle>> std::vector<std::unique_ptr<content::URLLoaderThrottle>>
AwURLLoaderThrottleProvider::CreateThrottles( AwURLLoaderThrottleProvider::CreateThrottles(
int render_frame_id, int render_frame_id,
const blink::WebURL& url, const blink::WebURLRequest& request,
content::ResourceType resource_type) { content::ResourceType resource_type) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
......
...@@ -23,7 +23,7 @@ class AwURLLoaderThrottleProvider : public content::URLLoaderThrottleProvider { ...@@ -23,7 +23,7 @@ class AwURLLoaderThrottleProvider : public content::URLLoaderThrottleProvider {
// content::URLLoaderThrottleProvider implementation. // content::URLLoaderThrottleProvider implementation.
std::vector<std::unique_ptr<content::URLLoaderThrottle>> CreateThrottles( std::vector<std::unique_ptr<content::URLLoaderThrottle>> CreateThrottles(
int render_frame_id, int render_frame_id,
const blink::WebURL& url, const blink::WebURLRequest& request,
content::ResourceType resource_type) override; content::ResourceType resource_type) override;
private: private:
......
// Copyright 2018 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 <string>
#include "base/metrics/field_trial_params.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_feature_list.h"
#include "base/timer/elapsed_timer.h"
#include "chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/subresource_filter/content/common/ad_delay_throttle.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
class AdDelayBrowserTest
: public subresource_filter::SubresourceFilterBrowserTest {
public:
AdDelayBrowserTest() : subresource_filter::SubresourceFilterBrowserTest() {}
~AdDelayBrowserTest() override {}
void SetUp() override {
scoped_features_.InitAndEnableFeatureWithParameters(
subresource_filter::AdDelayThrottle::kFeature,
{{"insecure_delay", DelayParamToUse()}});
subresource_filter::SubresourceFilterBrowserTest::SetUp();
}
// Calls fetchResources on the page, which issues fetch()es for two resources.
//
// Returns the name of the file whose fetch complete event triggered the
// callback.
// - If |policy| is kBothFetches, the returned file will be the last file
// loaded.
// - If |policy| is kOneFetch, the returned file will be the first file
// loaded.
enum class WaitForPolicy { kOneFetch, kBothFetches };
std::string FetchResources(WaitForPolicy policy) {
std::string ret;
EXPECT_TRUE(content::ExecuteScriptAndExtractString(
browser()->tab_strip_model()->GetActiveWebContents(),
base::StringPrintf(
"fetchResources(%s);",
policy == WaitForPolicy::kBothFetches ? "true" : "false"),
&ret));
return ret;
}
base::TimeDelta GetExpectedDelay() const {
return base::TimeDelta::FromMilliseconds(
base::GetFieldTrialParamByFeatureAsInt(
subresource_filter::AdDelayThrottle::kFeature, "insecure_delay",
subresource_filter::AdDelayThrottle::kDefaultDelay
.InMilliseconds()));
}
protected:
// 10 minutes.
virtual std::string DelayParamToUse() { return "600000"; }
private:
base::test::ScopedFeatureList scoped_features_;
};
class MinimalAdDelayBrowserTest : public AdDelayBrowserTest {
std::string DelayParamToUse() override { return "100"; }
};
IN_PROC_BROWSER_TEST_F(AdDelayBrowserTest, NoAd_NoDelay) {
GURL url(embedded_test_server()->GetURL(
"/subresource_filter/frame_with_multiple_fetches.html"));
ui_test_utils::NavigateToURL(browser(), url);
base::ElapsedTimer timer;
FetchResources(WaitForPolicy::kBothFetches);
EXPECT_GT(GetExpectedDelay(), timer.Elapsed());
}
IN_PROC_BROWSER_TEST_F(AdDelayBrowserTest, AdRequest_IsDelayed) {
ASSERT_NO_FATAL_FAILURE(
SetRulesetToDisallowURLsWithPathSuffix("included_script.js"));
GURL url(embedded_test_server()->GetURL(
"/subresource_filter/frame_with_multiple_fetches.html"));
ui_test_utils::NavigateToURL(browser(), url);
// If the included_script.js is delayed, assert that the
// included_allowed_script will always load before it. Because the allowed
// script is fetched second, this is a reasonably strong statement.
base::ElapsedTimer timer;
std::string first_resource = FetchResources(WaitForPolicy::kOneFetch);
EXPECT_GE(GetExpectedDelay(), timer.Elapsed());
EXPECT_EQ("included_allowed_script.js", first_resource);
}
IN_PROC_BROWSER_TEST_F(MinimalAdDelayBrowserTest, AdRequest_IsNotBlackholed) {
ASSERT_NO_FATAL_FAILURE(
SetRulesetToDisallowURLsWithPathSuffix("included_script.js"));
GURL url(embedded_test_server()->GetURL(
"/subresource_filter/frame_with_multiple_fetches.html"));
ui_test_utils::NavigateToURL(browser(), url);
// The test succeeds if it does not time out.
base::ElapsedTimer timer;
FetchResources(WaitForPolicy::kBothFetches);
EXPECT_LE(GetExpectedDelay(), timer.Elapsed());
}
...@@ -34,6 +34,7 @@ include_rules = [ ...@@ -34,6 +34,7 @@ include_rules = [
"+components/spellcheck", "+components/spellcheck",
"+components/startup_metric_utils/common", "+components/startup_metric_utils/common",
"+components/strings/grit", "+components/strings/grit",
"+components/subresource_filter/content/common",
"+components/subresource_filter/content/renderer", "+components/subresource_filter/content/renderer",
"+components/task_scheduler_util/common", "+components/task_scheduler_util/common",
"+components/translate/content/common", "+components/translate/content/common",
......
...@@ -4,8 +4,6 @@ ...@@ -4,8 +4,6 @@
#include "chrome/renderer/url_loader_throttle_provider_impl.h" #include "chrome/renderer/url_loader_throttle_provider_impl.h"
#include <memory>
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "chrome/common/prerender.mojom.h" #include "chrome/common/prerender.mojom.h"
...@@ -15,6 +13,7 @@ ...@@ -15,6 +13,7 @@
#include "chrome/renderer/prerender/prerender_helper.h" #include "chrome/renderer/prerender/prerender_helper.h"
#include "components/safe_browsing/features.h" #include "components/safe_browsing/features.h"
#include "components/safe_browsing/renderer/renderer_url_loader_throttle.h" #include "components/safe_browsing/renderer/renderer_url_loader_throttle.h"
#include "components/subresource_filter/content/renderer/ad_delay_renderer_metadata_provider.h"
#include "content/public/common/content_features.h" #include "content/public/common/content_features.h"
#include "content/public/common/service_names.mojom.h" #include "content/public/common/service_names.mojom.h"
#include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_frame.h"
...@@ -70,7 +69,7 @@ URLLoaderThrottleProviderImpl::~URLLoaderThrottleProviderImpl() { ...@@ -70,7 +69,7 @@ URLLoaderThrottleProviderImpl::~URLLoaderThrottleProviderImpl() {
std::vector<std::unique_ptr<content::URLLoaderThrottle>> std::vector<std::unique_ptr<content::URLLoaderThrottle>>
URLLoaderThrottleProviderImpl::CreateThrottles( URLLoaderThrottleProviderImpl::CreateThrottles(
int render_frame_id, int render_frame_id,
const blink::WebURL& url, const blink::WebURLRequest& request,
content::ResourceType resource_type) { content::ResourceType resource_type) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
...@@ -131,7 +130,7 @@ URLLoaderThrottleProviderImpl::CreateThrottles( ...@@ -131,7 +130,7 @@ URLLoaderThrottleProviderImpl::CreateThrottles(
content::RenderFrame::FromRoutingID(render_frame_id); content::RenderFrame::FromRoutingID(render_frame_id);
auto mime_handlers = auto mime_handlers =
extensions::MimeHandlerViewContainer::FromRenderFrame(render_frame); extensions::MimeHandlerViewContainer::FromRenderFrame(render_frame);
GURL gurl(url); GURL gurl(request.Url());
for (auto* handler : mime_handlers) { for (auto* handler : mime_handlers) {
auto throttle = handler->MaybeCreatePluginThrottle(gurl); auto throttle = handler->MaybeCreatePluginThrottle(gurl);
if (throttle) { if (throttle) {
...@@ -142,5 +141,18 @@ URLLoaderThrottleProviderImpl::CreateThrottles( ...@@ -142,5 +141,18 @@ URLLoaderThrottleProviderImpl::CreateThrottles(
} }
#endif #endif
// Initialize the factory here rather than in the constructor, since metrics
// does not support registering field trials (as opposed to Features) before
// Blink is initialized (after this class).
if (!ad_delay_factory_) {
ad_delay_factory_ =
std::make_unique<subresource_filter::AdDelayThrottle::Factory>();
}
if (auto ad_throttle = ad_delay_factory_->MaybeCreate(
std::make_unique<subresource_filter::AdDelayRendererMetadataProvider>(
request))) {
throttles.push_back(std::move(ad_throttle));
}
return throttles; return throttles;
} }
...@@ -5,8 +5,11 @@ ...@@ -5,8 +5,11 @@
#ifndef CHROME_RENDERER_URL_LOADER_THROTTLE_PROVIDER_IMPL_H_ #ifndef CHROME_RENDERER_URL_LOADER_THROTTLE_PROVIDER_IMPL_H_
#define CHROME_RENDERER_URL_LOADER_THROTTLE_PROVIDER_IMPL_H_ #define CHROME_RENDERER_URL_LOADER_THROTTLE_PROVIDER_IMPL_H_
#include <memory>
#include "base/threading/thread_checker.h" #include "base/threading/thread_checker.h"
#include "components/safe_browsing/common/safe_browsing.mojom.h" #include "components/safe_browsing/common/safe_browsing.mojom.h"
#include "components/subresource_filter/content/common/ad_delay_throttle.h"
#include "content/public/renderer/url_loader_throttle_provider.h" #include "content/public/renderer/url_loader_throttle_provider.h"
class ChromeContentRendererClient; class ChromeContentRendererClient;
...@@ -25,10 +28,13 @@ class URLLoaderThrottleProviderImpl ...@@ -25,10 +28,13 @@ class URLLoaderThrottleProviderImpl
// content::URLLoaderThrottleProvider implementation. // content::URLLoaderThrottleProvider implementation.
std::vector<std::unique_ptr<content::URLLoaderThrottle>> CreateThrottles( std::vector<std::unique_ptr<content::URLLoaderThrottle>> CreateThrottles(
int render_frame_id, int render_frame_id,
const blink::WebURL& url, const blink::WebURLRequest& request,
content::ResourceType resource_type) override; content::ResourceType resource_type) override;
private: private:
std::unique_ptr<subresource_filter::AdDelayThrottle::Factory>
ad_delay_factory_;
content::URLLoaderThrottleProviderType type_; content::URLLoaderThrottleProviderType type_;
ChromeContentRendererClient* const chrome_content_renderer_client_; ChromeContentRendererClient* const chrome_content_renderer_client_;
......
...@@ -737,6 +737,7 @@ test("browser_tests") { ...@@ -737,6 +737,7 @@ test("browser_tests") {
"../browser/ssl/ssl_client_certificate_selector_test.h", "../browser/ssl/ssl_client_certificate_selector_test.h",
"../browser/ssl/typed_navigation_timing_throttle_browsertest.cc", "../browser/ssl/typed_navigation_timing_throttle_browsertest.cc",
"../browser/storage/durable_storage_browsertest.cc", "../browser/storage/durable_storage_browsertest.cc",
"../browser/subresource_filter/ad_delay_browsertest.cc",
"../browser/subresource_filter/subresource_filter_browser_test_harness.cc", "../browser/subresource_filter/subresource_filter_browser_test_harness.cc",
"../browser/subresource_filter/subresource_filter_browser_test_harness.h", "../browser/subresource_filter/subresource_filter_browser_test_harness.h",
"../browser/subresource_filter/subresource_filter_browsertest.cc", "../browser/subresource_filter/subresource_filter_browsertest.cc",
......
<script>
function fetchResources(wait_for_both) {
included_script_loaded = false;
included_allowed_script_loaded = false;
fetch("/subresource_filter/included_script.js").then(() => {
included_script_loaded = true;
if (wait_for_both && !included_allowed_script_loaded)
return
window.domAutomationController.send("included_script.js");
});
fetch("/subresource_filter/included_allowed_script.js").then(() => {
included_allowed_script_loaded = true;
if (wait_for_both && !included_script_loaded)
return
window.domAutomationController.send("included_allowed_script.js");
});
}
</script>
...@@ -2,10 +2,14 @@ include_rules = [ ...@@ -2,10 +2,14 @@ include_rules = [
"+components/subresource_filter/content/common", "+components/subresource_filter/content/common",
"+content/public/common", "+content/public/common",
"+ipc", "+ipc",
"+services/network/public/cpp",
] ]
specific_include_rules = { specific_include_rules = {
'.*_[a-z]*test\.cc': [ '.*_[a-z]*test\.cc': [
"+content/public/test", "+content/public/test",
"+services/network/test",
"+services/network/public/mojom",
"+net",
], ],
} }
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
static_library("common") { static_library("common") {
sources = [ sources = [
"ad_delay_throttle.cc",
"ad_delay_throttle.h",
"ruleset_dealer.cc", "ruleset_dealer.cc",
"ruleset_dealer.h", "ruleset_dealer.h",
"subresource_filter_message_generator.cc", "subresource_filter_message_generator.cc",
...@@ -17,6 +19,7 @@ static_library("common") { ...@@ -17,6 +19,7 @@ static_library("common") {
"//components/subresource_filter/core/common", "//components/subresource_filter/core/common",
"//content/public/common", "//content/public/common",
"//ipc", "//ipc",
"//services/network/public/cpp",
"//url", "//url",
] ]
} }
...@@ -24,13 +27,18 @@ static_library("common") { ...@@ -24,13 +27,18 @@ static_library("common") {
source_set("unit_tests") { source_set("unit_tests") {
testonly = true testonly = true
sources = [ sources = [
"ad_delay_throttle_unittest.cc",
"ruleset_dealer_unittest.cc", "ruleset_dealer_unittest.cc",
] ]
deps = [ deps = [
":common", ":common",
"//base", "//base",
"//base/test:test_support",
"//components/subresource_filter/core/common", "//components/subresource_filter/core/common",
"//components/subresource_filter/core/common:test_support", "//components/subresource_filter/core/common:test_support",
"//content/test:test_support",
"//net:test_support",
"//services/network:test_support",
"//testing/gmock", "//testing/gmock",
"//testing/gtest", "//testing/gtest",
] ]
......
// Copyright 2018 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 "components/subresource_filter/content/common/ad_delay_throttle.h"
#include <utility>
#include "base/bind.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/field_trial_params.h"
#include "base/sequenced_task_runner.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "url/gurl.h"
#include "url/url_constants.h"
namespace subresource_filter {
const base::Feature AdDelayThrottle::kFeature{
"DelayUnsafeAds", base::FEATURE_DISABLED_BY_DEFAULT};
constexpr base::TimeDelta AdDelayThrottle::kDefaultDelay;
AdDelayThrottle::Factory::Factory()
: insecure_delay_(base::TimeDelta::FromMilliseconds(
base::GetFieldTrialParamByFeatureAsInt(
kFeature,
"insecure_delay",
kDefaultDelay.InMilliseconds()))),
// TODO(csharrison): Also check for AdTagging here to avoid reporting on
// groups without that experiment.
enabled_(base::FeatureList::IsEnabled(kFeature)) {}
// TODO(csharrison): Log metrics for the # of requests delayed.
AdDelayThrottle::Factory::~Factory() = default;
std::unique_ptr<AdDelayThrottle> AdDelayThrottle::Factory::MaybeCreate(
std::unique_ptr<AdDelayThrottle::MetadataProvider> provider) const {
DCHECK(provider);
if (!enabled_)
return nullptr;
return base::WrapUnique(
new AdDelayThrottle(std::move(provider), insecure_delay_));
}
AdDelayThrottle::~AdDelayThrottle() = default;
void AdDelayThrottle::WillStartRequest(network::ResourceRequest* request,
bool* defer) {
*defer = MaybeDefer(request->url);
}
void AdDelayThrottle::WillRedirectRequest(
const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head,
bool* defer) {
// Note: some MetadataProviders may not be able to distinguish requests that
// are only tagged as ads after a redirect.
*defer = MaybeDefer(redirect_info.new_url);
}
bool AdDelayThrottle::MaybeDefer(const GURL& url) {
if (has_deferred_)
return false;
// Note: this should probably be using content::IsOriginSecure which accounts
// for things like whitelisted origins, localhost, etc. This isn't used here
// because that function is quite expensive for insecure schemes, involving
// many allocations and string scans.
was_ever_insecure_ |= url.SchemeIs(url::kHttpScheme);
if (!was_ever_insecure_ || !provider_->IsAdRequest())
return false;
// TODO(csharrison): Consider logging to the console here that Chrome
// delayed this request.
has_deferred_ = true;
base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(&AdDelayThrottle::Resume, weak_factory_.GetWeakPtr()),
insecure_delay_);
return true;
}
void AdDelayThrottle::Resume() {
delegate_->Resume();
}
AdDelayThrottle::AdDelayThrottle(std::unique_ptr<MetadataProvider> provider,
base::TimeDelta insecure_delay)
: content::URLLoaderThrottle(),
provider_(std::move(provider)),
insecure_delay_(insecure_delay),
weak_factory_(this) {}
} // namespace subresource_filter
// Copyright 2018 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 COMPONENTS_SUBRESOURCE_FILTER_CONTENT_COMMON_AD_DELAY_THROTTLE_H_
#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_COMMON_AD_DELAY_THROTTLE_H_
#include <memory>
#include "base/feature_list.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "content/public/common/url_loader_throttle.h"
#include "services/network/public/cpp/resource_request.h"
class GURL;
namespace subresource_filter {
// This class delays ad requests satisfying certain conditions.
// - The ad is insecure (e.g. uses http).
// TODO(csharrison): Add delays for when the request is in a same-origin iframe.
class AdDelayThrottle : public content::URLLoaderThrottle {
public:
static const base::Feature kFeature;
static constexpr base::TimeDelta kDefaultDelay =
base::TimeDelta::FromMilliseconds(50);
class MetadataProvider {
public:
virtual ~MetadataProvider() {}
virtual bool IsAdRequest() = 0;
// TODO(csharrison): Add an interface for querying same-origin iframe
// status.
};
// Mainly used for caching values that we don't want to compute for every
// resource request.
class Factory {
public:
Factory();
~Factory();
std::unique_ptr<AdDelayThrottle> MaybeCreate(
std::unique_ptr<MetadataProvider> provider) const;
private:
const base::TimeDelta insecure_delay_;
const bool enabled_ = false;
DISALLOW_COPY_AND_ASSIGN(Factory);
};
~AdDelayThrottle() override;
private:
// content::URLLoaderThrottle:
void WillStartRequest(network::ResourceRequest* request,
bool* defer) override;
void WillRedirectRequest(const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head,
bool* defer) override;
// Returns whether the request to |url| should be deferred.
bool MaybeDefer(const GURL& url);
void Resume();
AdDelayThrottle(std::unique_ptr<MetadataProvider> provider,
base::TimeDelta insecure_delay);
// Will never be nullptr.
std::unique_ptr<MetadataProvider> provider_;
// How long to delay an ad request that is insecure.
base::TimeDelta insecure_delay_;
// Only defer at most once per request.
bool has_deferred_ = false;
// Tracks whether this request was ever insecure, across all its redirects.
bool was_ever_insecure_ = false;
base::WeakPtrFactory<AdDelayThrottle> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(AdDelayThrottle);
};
} // namespace subresource_filter
#endif // COMPONENTS_SUBRESOURCE_FILTER_CONTENT_COMMON_AD_DELAY_THROTTLE_H_
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
static_library("renderer") { static_library("renderer") {
sources = [ sources = [
"ad_delay_renderer_metadata_provider.cc",
"ad_delay_renderer_metadata_provider.h",
"subresource_filter_agent.cc", "subresource_filter_agent.cc",
"subresource_filter_agent.h", "subresource_filter_agent.h",
"unverified_ruleset_dealer.cc", "unverified_ruleset_dealer.cc",
......
// Copyright 2018 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 "components/subresource_filter/content/renderer/ad_delay_renderer_metadata_provider.h"
#include "third_party/blink/public/platform/web_url_request.h"
namespace subresource_filter {
AdDelayRendererMetadataProvider::AdDelayRendererMetadataProvider(
const blink::WebURLRequest& request)
: is_ad_request_(request.IsAdResource()) {}
AdDelayRendererMetadataProvider::~AdDelayRendererMetadataProvider() = default;
// TODO(csharrison): Update |is_ad_request_| across redirects.
bool AdDelayRendererMetadataProvider::IsAdRequest() {
return is_ad_request_;
}
} // namespace subresource_filter
// Copyright 2018 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 COMPONENTS_SUBRESOURCE_FILTER_CONTENT_RENDERER_AD_DELAY_RENDERER_METADATA_PROVIDER_H_
#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_RENDERER_AD_DELAY_RENDERER_METADATA_PROVIDER_H_
#include "base/macros.h"
#include "components/subresource_filter/content/common/ad_delay_throttle.h"
namespace blink {
class WebURLRequest;
} // namespace blink
namespace subresource_filter {
class AdDelayRendererMetadataProvider
: public AdDelayThrottle::MetadataProvider {
public:
explicit AdDelayRendererMetadataProvider(const blink::WebURLRequest& request);
~AdDelayRendererMetadataProvider() override;
// AdDelayThrottle::MetadataProvider:
bool IsAdRequest() override;
private:
const bool is_ad_request_ = false;
DISALLOW_COPY_AND_ASSIGN(AdDelayRendererMetadataProvider);
};
} // namespace subresource_filter
#endif // COMPONENTS_SUBRESOURCE_FILTER_CONTENT_RENDERER_AD_DELAY_RENDERER_METADATA_PROVIDER_H_
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "content/public/common/resource_type.h" #include "content/public/common/resource_type.h"
#include "content/public/common/url_loader_throttle.h" #include "content/public/common/url_loader_throttle.h"
#include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/platform/web_url_request.h"
namespace content { namespace content {
...@@ -33,7 +33,7 @@ class CONTENT_EXPORT URLLoaderThrottleProvider { ...@@ -33,7 +33,7 @@ class CONTENT_EXPORT URLLoaderThrottleProvider {
// service workers, |render_frame_id| should be set to MSG_ROUTING_NONE. // service workers, |render_frame_id| should be set to MSG_ROUTING_NONE.
virtual std::vector<std::unique_ptr<URLLoaderThrottle>> CreateThrottles( virtual std::vector<std::unique_ptr<URLLoaderThrottle>> CreateThrottles(
int render_frame_id, int render_frame_id,
const blink::WebURL& url, const blink::WebURLRequest& request,
ResourceType resource_type) = 0; ResourceType resource_type) = 0;
}; };
......
// Copyright 2018 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 "content/public/test/throttling_url_loader_test_util.h"
#include <utility>
#include "content/common/throttling_url_loader.h"
namespace content {
std::unique_ptr<network::mojom::URLLoaderClient> CreateThrottlingLoaderAndStart(
scoped_refptr<network::SharedURLLoaderFactory> factory,
std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
int32_t routing_id,
int32_t request_id,
uint32_t options,
network::ResourceRequest* url_request,
network::mojom::URLLoaderClient* client,
const net::NetworkTrafficAnnotationTag& traffic_annotation,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
return ThrottlingURLLoader::CreateLoaderAndStart(
std::move(factory), std::move(throttles), routing_id, request_id, options,
url_request, client, traffic_annotation, std::move(task_runner));
}
} // namespace content
// Copyright 2018 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 CONTENT_PUBLIC_TEST_THROTTLING_URL_LOADER_TEST_UTIL_H_
#define CONTENT_PUBLIC_TEST_THROTTLING_URL_LOADER_TEST_UTIL_H_
#include <memory>
#include <vector>
#include "base/memory/scoped_refptr.h"
#include "base/single_thread_task_runner.h"
#include "content/public/common/url_loader_throttle.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
namespace content {
// Allows tests outside of content to interface with a ThrottlingURLLoader.
std::unique_ptr<network::mojom::URLLoaderClient> CreateThrottlingLoaderAndStart(
scoped_refptr<network::SharedURLLoaderFactory> factory,
std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
int32_t routing_id,
int32_t request_id,
uint32_t options,
network::ResourceRequest* url_request,
network::mojom::URLLoaderClient* client,
const net::NetworkTrafficAnnotationTag& traffic_annotation,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
} // namespace content
#endif // CONTENT_PUBLIC_TEST_THROTTLING_URL_LOADER_TEST_UTIL_H_
...@@ -4932,7 +4932,7 @@ void RenderFrameImpl::WillSendRequest(blink::WebURLRequest& request) { ...@@ -4932,7 +4932,7 @@ void RenderFrameImpl::WillSendRequest(blink::WebURLRequest& request) {
if (render_thread && render_thread->url_loader_throttle_provider()) { if (render_thread && render_thread->url_loader_throttle_provider()) {
extra_data->set_url_loader_throttles( extra_data->set_url_loader_throttles(
render_thread->url_loader_throttle_provider()->CreateThrottles( render_thread->url_loader_throttle_provider()->CreateThrottles(
routing_id_, request.Url(), resource_type)); routing_id_, request, resource_type));
} }
if (request.GetPreviewsState() == WebURLRequest::kPreviewsUnspecified) { if (request.GetPreviewsState() == WebURLRequest::kPreviewsUnspecified) {
......
...@@ -70,7 +70,7 @@ void ServiceWorkerFetchContextImpl::WillSendRequest( ...@@ -70,7 +70,7 @@ void ServiceWorkerFetchContextImpl::WillSendRequest(
extra_data->set_initiated_in_secure_context(true); extra_data->set_initiated_in_secure_context(true);
if (throttle_provider_) { if (throttle_provider_) {
extra_data->set_url_loader_throttles(throttle_provider_->CreateThrottles( extra_data->set_url_loader_throttles(throttle_provider_->CreateThrottles(
MSG_ROUTING_NONE, request.Url(), WebURLRequestToResourceType(request))); MSG_ROUTING_NONE, request, WebURLRequestToResourceType(request)));
} }
request.SetExtraData(std::move(extra_data)); request.SetExtraData(std::move(extra_data));
} }
......
...@@ -185,7 +185,7 @@ void WorkerFetchContextImpl::WillSendRequest(blink::WebURLRequest& request) { ...@@ -185,7 +185,7 @@ void WorkerFetchContextImpl::WillSendRequest(blink::WebURLRequest& request) {
extra_data->set_initiated_in_secure_context(is_secure_context_); extra_data->set_initiated_in_secure_context(is_secure_context_);
if (throttle_provider_) { if (throttle_provider_) {
extra_data->set_url_loader_throttles(throttle_provider_->CreateThrottles( extra_data->set_url_loader_throttles(throttle_provider_->CreateThrottles(
parent_frame_id_, request.Url(), WebURLRequestToResourceType(request))); parent_frame_id_, request, WebURLRequestToResourceType(request)));
} }
request.SetExtraData(std::move(extra_data)); request.SetExtraData(std::move(extra_data));
request.SetAppCacheHostID(appcache_host_id_); request.SetAppCacheHostID(appcache_host_id_);
......
...@@ -165,6 +165,8 @@ jumbo_static_library("test_support") { ...@@ -165,6 +165,8 @@ jumbo_static_library("test_support") {
"../public/test/text_input_test_utils.cc", "../public/test/text_input_test_utils.cc",
"../public/test/text_input_test_utils.h", "../public/test/text_input_test_utils.h",
"../public/test/text_input_test_utils_mac.mm", "../public/test/text_input_test_utils_mac.mm",
"../public/test/throttling_url_loader_test_util.cc",
"../public/test/throttling_url_loader_test_util.h",
"../public/test/unittest_test_suite.cc", "../public/test/unittest_test_suite.cc",
"../public/test/unittest_test_suite.h", "../public/test/unittest_test_suite.h",
"../public/test/url_loader_interceptor.cc", "../public/test/url_loader_interceptor.cc",
......
...@@ -95,7 +95,9 @@ bool TestURLLoaderFactory::CreateLoaderAndStartInternal( ...@@ -95,7 +95,9 @@ bool TestURLLoaderFactory::CreateLoaderAndStartInternal(
if (it == responses_.end()) if (it == responses_.end())
return false; return false;
CHECK(it->second.redirects.empty()) << "TODO(jam): handle redirects"; for (const auto& redirect : it->second.redirects) {
client->OnReceiveRedirect(redirect.first, redirect.second);
}
if (it->second.status.error_code == net::OK) { if (it->second.status.error_code == net::OK) {
client->OnReceiveResponse(it->second.head, nullptr); client->OnReceiveResponse(it->second.head, nullptr);
......
...@@ -79,4 +79,25 @@ TEST_F(TestURLLoaderFactoryTest, MultipleSameURL) { ...@@ -79,4 +79,25 @@ TEST_F(TestURLLoaderFactoryTest, MultipleSameURL) {
EXPECT_EQ(GetData(client()), data2); EXPECT_EQ(GetData(client()), data2);
} }
TEST_F(TestURLLoaderFactoryTest, Redirects) {
GURL url("http://example.test/");
net::RedirectInfo redirect_info;
redirect_info.status_code = 301;
redirect_info.new_url = GURL("http://example2.test/");
network::TestURLLoaderFactory::Redirects redirects{
{redirect_info, network::ResourceResponseHead()}};
URLLoaderCompletionStatus status;
std::string content = "foo";
status.decoded_body_length = content.size();
factory()->AddResponse(url, network::ResourceResponseHead(), content, status,
redirects);
StartRequest(url.spec());
client()->RunUntilComplete();
EXPECT_EQ(GetData(client()), content);
EXPECT_TRUE(client()->has_received_redirect());
EXPECT_EQ(redirect_info.new_url, client()->redirect_info().new_url);
}
} // namespace network } // namespace network
...@@ -348,6 +348,10 @@ class WebURLRequest { ...@@ -348,6 +348,10 @@ class WebURLRequest {
// is the value provided there. // is the value provided there.
BLINK_PLATFORM_EXPORT base::Optional<WebString> GetSuggestedFilename() const; BLINK_PLATFORM_EXPORT base::Optional<WebString> GetSuggestedFilename() const;
// Returns true if this request is tagged as an ad. This is done using various
// heuristics so it is not expected to be 100% accurate.
BLINK_PLATFORM_EXPORT bool IsAdResource() const;
#if INSIDE_BLINK #if INSIDE_BLINK
BLINK_PLATFORM_EXPORT ResourceRequest& ToMutableResourceRequest(); BLINK_PLATFORM_EXPORT ResourceRequest& ToMutableResourceRequest();
BLINK_PLATFORM_EXPORT const ResourceRequest& ToResourceRequest() const; BLINK_PLATFORM_EXPORT const ResourceRequest& ToResourceRequest() const;
......
...@@ -419,6 +419,10 @@ base::Optional<WebString> WebURLRequest::GetSuggestedFilename() const { ...@@ -419,6 +419,10 @@ base::Optional<WebString> WebURLRequest::GetSuggestedFilename() const {
resource_request_->GetSuggestedFilename().value()); resource_request_->GetSuggestedFilename().value());
} }
bool WebURLRequest::IsAdResource() const {
return resource_request_->IsAdResource();
}
const ResourceRequest& WebURLRequest::ToResourceRequest() const { const ResourceRequest& WebURLRequest::ToResourceRequest() const {
DCHECK(resource_request_); DCHECK(resource_request_);
return *resource_request_; return *resource_request_;
......
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