Commit 37877801 authored by Reilly Grant's avatar Reilly Grant Committed by Commit Bot

Implement signin header modifications with a URLLoaderThrottle

This change replaces the header modification logic implemented in
ChromeResourceDispatchHostDelegate with a URLLoaderThrottle that is
configured for all navigation requests.

To support modifying headers (in addition to removing them) before
following a redirect a |modified_request_headers| parameter has been
added to URLLoaderThrottle::WillRedirectRequest().

Bug: 789670
Cq-Include-Trybots: luci.chromium.try:linux_mojo
Change-Id: Ibd58b0367bbe2a519dfb1cf85a4e5e6ec7eeeffa
Reviewed-on: https://chromium-review.googlesource.com/1139089
Commit-Queue: Reilly Grant <reillyg@chromium.org>
Reviewed-by: default avatarMihai Sardarescu <msarda@chromium.org>
Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#584270}
parent 0f4df01b
...@@ -1395,6 +1395,10 @@ jumbo_split_static_library("browser") { ...@@ -1395,6 +1395,10 @@ jumbo_split_static_library("browser") {
"signin/chrome_signin_client_factory.h", "signin/chrome_signin_client_factory.h",
"signin/chrome_signin_helper.cc", "signin/chrome_signin_helper.cc",
"signin/chrome_signin_helper.h", "signin/chrome_signin_helper.h",
"signin/chrome_signin_url_loader_throttle.cc",
"signin/chrome_signin_url_loader_throttle.h",
"signin/chrome_signin_url_loader_throttle_delegate_impl.cc",
"signin/chrome_signin_url_loader_throttle_delegate_impl.h",
"signin/gaia_cookie_manager_service_factory.cc", "signin/gaia_cookie_manager_service_factory.cc",
"signin/gaia_cookie_manager_service_factory.h", "signin/gaia_cookie_manager_service_factory.h",
"signin/identity_manager_factory.cc", "signin/identity_manager_factory.cc",
......
...@@ -102,6 +102,8 @@ ...@@ -102,6 +102,8 @@
#include "chrome/browser/safe_browsing/url_checker_delegate_impl.h" #include "chrome/browser/safe_browsing/url_checker_delegate_impl.h"
#include "chrome/browser/search/search.h" #include "chrome/browser/search/search.h"
#include "chrome/browser/sessions/session_tab_helper.h" #include "chrome/browser/sessions/session_tab_helper.h"
#include "chrome/browser/signin/chrome_signin_url_loader_throttle.h"
#include "chrome/browser/signin/chrome_signin_url_loader_throttle_delegate_impl.h"
#include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/speech/chrome_speech_recognition_manager_delegate.h" #include "chrome/browser/speech/chrome_speech_recognition_manager_delegate.h"
#include "chrome/browser/speech/tts_controller.h" #include "chrome/browser/speech/tts_controller.h"
...@@ -4309,6 +4311,15 @@ ChromeContentBrowserClient::CreateURLLoaderThrottles( ...@@ -4309,6 +4311,15 @@ ChromeContentBrowserClient::CreateURLLoaderThrottles(
resource_context, request.resource_type, frame_tree_node_id)); resource_context, request.resource_type, frame_tree_node_id));
} }
#endif #endif
if (network_service_enabled) {
auto delegate = std::make_unique<signin::URLLoaderThrottleDelegateImpl>(
resource_context);
auto signin_throttle = signin::URLLoaderThrottle::MaybeCreate(
std::move(delegate), navigation_ui_data, wc_getter);
if (signin_throttle)
result.push_back(std::move(signin_throttle));
}
return result; return result;
} }
......
// 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 "chrome/browser/signin/chrome_signin_url_loader_throttle.h"
#include "chrome/browser/signin/chrome_signin_helper.h"
#include "components/signin/core/browser/signin_header_helper.h"
namespace signin {
class URLLoaderThrottle::ThrottleRequestAdapter : public ChromeRequestAdapter {
public:
ThrottleRequestAdapter(URLLoaderThrottle* throttle,
const net::HttpRequestHeaders& original_headers,
net::HttpRequestHeaders* modified_headers,
std::vector<std::string>* headers_to_remove)
: ChromeRequestAdapter(nullptr),
throttle_(throttle),
original_headers_(original_headers),
modified_headers_(modified_headers),
headers_to_remove_(headers_to_remove) {}
~ThrottleRequestAdapter() override = default;
// ChromeRequestAdapter
bool IsMainRequestContext(ProfileIOData* io_data) override {
// The <webview> check in URLLoaderThrottle::MaybeCreate means this is
// always true.
return true;
}
content::ResourceRequestInfo::WebContentsGetter GetWebContentsGetter()
const override {
return throttle_->web_contents_getter_;
}
content::ResourceType GetResourceType() const override {
return throttle_->request_resource_type_;
}
GURL GetReferrerOrigin() const override {
return throttle_->request_referrer_.GetOrigin();
}
void SetDestructionCallback(base::OnceClosure closure) override {
if (!throttle_->destruction_callback_)
throttle_->destruction_callback_ = std::move(closure);
}
// RequestAdapter
const GURL& GetUrl() override { return throttle_->request_url_; }
bool HasHeader(const std::string& name) override {
return (original_headers_.HasHeader(name) ||
modified_headers_->HasHeader(name)) &&
!base::ContainsValue(*headers_to_remove_, name);
}
void RemoveRequestHeaderByName(const std::string& name) override {
if (!base::ContainsValue(*headers_to_remove_, name))
headers_to_remove_->push_back(name);
}
void SetExtraHeaderByName(const std::string& name,
const std::string& value) override {
modified_headers_->SetHeader(name, value);
auto it =
std::find(headers_to_remove_->begin(), headers_to_remove_->end(), name);
if (it != headers_to_remove_->end())
headers_to_remove_->erase(it);
}
private:
URLLoaderThrottle* const throttle_;
const net::HttpRequestHeaders& original_headers_;
net::HttpRequestHeaders* const modified_headers_;
std::vector<std::string>* const headers_to_remove_;
DISALLOW_COPY_AND_ASSIGN(ThrottleRequestAdapter);
};
class URLLoaderThrottle::ThrottleResponseAdapter : public ResponseAdapter {
public:
ThrottleResponseAdapter(URLLoaderThrottle* throttle,
net::HttpResponseHeaders* headers)
: ResponseAdapter(nullptr), throttle_(throttle), headers_(headers) {}
~ThrottleResponseAdapter() override = default;
// ResponseAdapter
content::ResourceRequestInfo::WebContentsGetter GetWebContentsGetter()
const override {
return throttle_->web_contents_getter_;
}
bool IsMainFrame() const override { return throttle_->is_main_frame_; }
GURL GetOrigin() const override {
return throttle_->request_url_.GetOrigin();
}
const net::HttpResponseHeaders* GetHeaders() const override {
return headers_;
}
void RemoveHeader(const std::string& name) override {
headers_->RemoveHeader(name);
}
private:
URLLoaderThrottle* const throttle_;
net::HttpResponseHeaders* headers_;
DISALLOW_COPY_AND_ASSIGN(ThrottleResponseAdapter);
};
URLLoaderThrottle::Delegate::Delegate() = default;
URLLoaderThrottle::Delegate::~Delegate() = default;
// static
std::unique_ptr<URLLoaderThrottle> URLLoaderThrottle::MaybeCreate(
std::unique_ptr<Delegate> delegate,
content::NavigationUIData* navigation_ui_data,
content::ResourceRequestInfo::WebContentsGetter web_contents_getter) {
if (!delegate->ShouldIntercept(navigation_ui_data))
return nullptr;
return base::WrapUnique(new URLLoaderThrottle(
std::move(delegate), std::move(web_contents_getter)));
}
URLLoaderThrottle::~URLLoaderThrottle() {
if (destruction_callback_)
std::move(destruction_callback_).Run();
}
void URLLoaderThrottle::WillStartRequest(network::ResourceRequest* request,
bool* defer) {
request_url_ = request->url;
request_referrer_ = request->referrer;
request_resource_type_ =
static_cast<content::ResourceType>(request->resource_type);
is_main_frame_ = request->is_main_frame;
net::HttpRequestHeaders modified_request_headers;
std::vector<std::string> to_be_removed_request_headers;
ThrottleRequestAdapter adapter(this, request->headers,
&modified_request_headers,
&to_be_removed_request_headers);
delegate_->ProcessRequest(&adapter, GURL() /* redirect_url */);
request->headers.MergeFrom(modified_request_headers);
for (const std::string& name : to_be_removed_request_headers)
request->headers.RemoveHeader(name);
// We need to keep a full copy of the request headers for later calls to
// FixAccountConsistencyRequestHeader. Perhaps this could be replaced with
// more specific per-request state.
request_headers_.CopyFrom(request->headers);
}
void URLLoaderThrottle::WillRedirectRequest(
const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head,
bool* /* defer */,
std::vector<std::string>* to_be_removed_request_headers,
net::HttpRequestHeaders* modified_request_headers) {
ThrottleRequestAdapter request_adapter(this, request_headers_,
modified_request_headers,
to_be_removed_request_headers);
delegate_->ProcessRequest(&request_adapter, redirect_info.new_url);
request_headers_.MergeFrom(*modified_request_headers);
for (const std::string& name : *to_be_removed_request_headers)
request_headers_.RemoveHeader(name);
// Modifications to |response_head.headers| will be passed to the
// URLLoaderClient even though |response_head| is const.
ThrottleResponseAdapter response_adapter(this, response_head.headers.get());
delegate_->ProcessResponse(&response_adapter, redirect_info.new_url);
request_url_ = redirect_info.new_url;
request_referrer_ = GURL(redirect_info.new_referrer);
}
void URLLoaderThrottle::WillProcessResponse(
const GURL& response_url,
network::ResourceResponseHead* response_head,
bool* defer) {
ThrottleResponseAdapter adapter(this, response_head->headers.get());
delegate_->ProcessResponse(&adapter, GURL() /* redirect_url */);
}
URLLoaderThrottle::URLLoaderThrottle(
std::unique_ptr<Delegate> delegate,
content::ResourceRequestInfo::WebContentsGetter web_contents_getter)
: delegate_(std::move(delegate)),
web_contents_getter_(std::move(web_contents_getter)) {}
} // namespace signin
// 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 CHROME_BROWSER_SIGNIN_CHROME_SIGNIN_URL_LOADER_THROTTLE_H_
#define CHROME_BROWSER_SIGNIN_CHROME_SIGNIN_URL_LOADER_THROTTLE_H_
#include "base/macros.h"
#include "content/public/browser/resource_request_info.h"
#include "content/public/common/url_loader_throttle.h"
namespace content {
class NavigationUIData;
} // namespace content
namespace signin {
class ChromeRequestAdapter;
class ResponseAdapter;
// This class is used to modify the main frame request made when loading the
// GAIA signin realm.
class URLLoaderThrottle : public content::URLLoaderThrottle {
public:
class Delegate {
public:
Delegate();
virtual ~Delegate();
virtual bool ShouldIntercept(
content::NavigationUIData* navigation_ui_data) = 0;
virtual void ProcessRequest(ChromeRequestAdapter* request_adapter,
const GURL& redirect_url) = 0;
virtual void ProcessResponse(ResponseAdapter* response_adapter,
const GURL& redirect_url) = 0;
};
// Creates a new throttle if |delegate| says that this request should be
// intercepted.
static std::unique_ptr<URLLoaderThrottle> MaybeCreate(
std::unique_ptr<Delegate> delegate,
content::NavigationUIData* navigation_ui_data,
content::ResourceRequestInfo::WebContentsGetter web_contents_getter);
~URLLoaderThrottle() override;
// content::URLLoaderThrottle
void WillStartRequest(network::ResourceRequest* request,
bool* defer) override;
void WillRedirectRequest(const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head,
bool* defer,
std::vector<std::string>* headers_to_remove,
net::HttpRequestHeaders* modified_headers) override;
void WillProcessResponse(const GURL& response_url,
network::ResourceResponseHead* response_head,
bool* defer) override;
private:
class ThrottleRequestAdapter;
class ThrottleResponseAdapter;
URLLoaderThrottle(
std::unique_ptr<Delegate> delegate,
content::ResourceRequestInfo::WebContentsGetter web_contents_getter);
const std::unique_ptr<Delegate> delegate_;
const content::ResourceRequestInfo::WebContentsGetter web_contents_getter_;
// Information about the current request.
GURL request_url_;
GURL request_referrer_;
net::HttpRequestHeaders request_headers_;
content::ResourceType request_resource_type_;
bool is_main_frame_ = false;
base::OnceClosure destruction_callback_;
DISALLOW_COPY_AND_ASSIGN(URLLoaderThrottle);
};
} // namespace signin
#endif // CHROME_BROWSER_SIGNIN_CHROME_SIGNIN_URL_LOADER_THROTTLE_H_
// 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 "chrome/browser/signin/chrome_signin_url_loader_throttle_delegate_impl.h"
#include "chrome/browser/profiles/profile_io_data.h"
#include "chrome/browser/renderer_host/chrome_navigation_ui_data.h"
#include "chrome/browser/signin/chrome_signin_helper.h"
#include "extensions/browser/extension_navigation_ui_data.h"
namespace signin {
URLLoaderThrottleDelegateImpl::URLLoaderThrottleDelegateImpl(
content::ResourceContext* resource_context)
: io_data_(ProfileIOData::FromResourceContext(resource_context)) {}
URLLoaderThrottleDelegateImpl::~URLLoaderThrottleDelegateImpl() = default;
bool URLLoaderThrottleDelegateImpl::ShouldIntercept(
content::NavigationUIData* navigation_ui_data) {
if (io_data_->IsOffTheRecord())
return false;
#if BUILDFLAG(ENABLE_EXTENSIONS)
// Note: InlineLoginUI uses an isolated request context and thus should
// bypass the account consistency flow. See http://crbug.com/428396
ChromeNavigationUIData* chrome_navigation_ui_data =
static_cast<ChromeNavigationUIData*>(navigation_ui_data);
if (chrome_navigation_ui_data) {
extensions::ExtensionNavigationUIData* extension_navigation_ui_data =
chrome_navigation_ui_data->GetExtensionNavigationUIData();
if (extension_navigation_ui_data &&
extension_navigation_ui_data->is_web_view()) {
return false;
}
}
#endif
return true;
}
void URLLoaderThrottleDelegateImpl::ProcessRequest(
ChromeRequestAdapter* request_adapter,
const GURL& redirect_url) {
FixAccountConsistencyRequestHeader(request_adapter, redirect_url, io_data_);
}
void URLLoaderThrottleDelegateImpl::ProcessResponse(
ResponseAdapter* response_adapter,
const GURL& redirect_url) {
ProcessAccountConsistencyResponseHeaders(response_adapter, redirect_url,
io_data_->IsOffTheRecord());
}
} // namespace signin
// 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 CHROME_BROWSER_SIGNIN_CHROME_SIGNIN_URL_LOADER_THROTTLE_DELEGATE_IMPL_H_
#define CHROME_BROWSER_SIGNIN_CHROME_SIGNIN_URL_LOADER_THROTTLE_DELEGATE_IMPL_H_
#include "chrome/browser/signin/chrome_signin_url_loader_throttle.h"
class ProfileIOData;
namespace signin {
class URLLoaderThrottleDelegateImpl : public URLLoaderThrottle::Delegate {
public:
explicit URLLoaderThrottleDelegateImpl(
content::ResourceContext* resource_context);
~URLLoaderThrottleDelegateImpl() override;
// URLLoaderThrottle::Delegate
bool ShouldIntercept(content::NavigationUIData* navigation_ui_data) override;
void ProcessRequest(ChromeRequestAdapter* request_adapter,
const GURL& redirect_url) override;
void ProcessResponse(ResponseAdapter* response_adapter,
const GURL& redirect_url) override;
private:
ProfileIOData* const io_data_;
DISALLOW_COPY_AND_ASSIGN(URLLoaderThrottleDelegateImpl);
};
} // namespace signin
#endif // CHROME_BROWSER_SIGNIN_CHROME_SIGNIN_URL_LOADER_THROTTLE_DELEGATE_IMPL_H_
...@@ -62,9 +62,10 @@ void GoogleURLLoaderThrottle::WillStartRequest( ...@@ -62,9 +62,10 @@ void GoogleURLLoaderThrottle::WillStartRequest(
void GoogleURLLoaderThrottle::WillRedirectRequest( void GoogleURLLoaderThrottle::WillRedirectRequest(
const net::RedirectInfo& redirect_info, const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head, const network::ResourceResponseHead& /* response_head */,
bool* defer, bool* /* defer */,
std::vector<std::string>* to_be_removed_headers) { std::vector<std::string>* to_be_removed_headers,
net::HttpRequestHeaders* /* modified_headers */) {
if (!variations::ShouldAppendVariationHeaders(redirect_info.new_url)) if (!variations::ShouldAppendVariationHeaders(redirect_info.new_url))
to_be_removed_headers->push_back(variations::kClientDataHeader); to_be_removed_headers->push_back(variations::kClientDataHeader);
} }
......
...@@ -27,11 +27,11 @@ class GoogleURLLoaderThrottle ...@@ -27,11 +27,11 @@ class GoogleURLLoaderThrottle
void DetachFromCurrentSequence() override; void DetachFromCurrentSequence() override;
void WillStartRequest(network::ResourceRequest* request, void WillStartRequest(network::ResourceRequest* request,
bool* defer) override; bool* defer) override;
void WillRedirectRequest( void WillRedirectRequest(const net::RedirectInfo& redirect_info,
const net::RedirectInfo& redirect_info, const network::ResourceResponseHead& response_head,
const network::ResourceResponseHead& response_head, bool* defer,
bool* defer, std::vector<std::string>* to_be_removed_headers,
std::vector<std::string>* to_be_removed_headers) override; net::HttpRequestHeaders* modified_headers) override;
#if BUILDFLAG(ENABLE_EXTENSIONS) #if BUILDFLAG(ENABLE_EXTENSIONS)
void WillProcessResponse(const GURL& response_url, void WillProcessResponse(const GURL& response_url,
network::ResourceResponseHead* response_head, network::ResourceResponseHead* response_head,
......
...@@ -143,7 +143,8 @@ void PrerenderURLLoaderThrottle::WillRedirectRequest( ...@@ -143,7 +143,8 @@ void PrerenderURLLoaderThrottle::WillRedirectRequest(
const net::RedirectInfo& redirect_info, const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head, const network::ResourceResponseHead& response_head,
bool* defer, bool* defer,
std::vector<std::string>* to_be_removed_headers) { std::vector<std::string>* /* to_be_removed_headers */,
net::HttpRequestHeaders* /* modified_headers */) {
redirect_count_++; redirect_count_++;
if (mode_ == PREFETCH_ONLY) { if (mode_ == PREFETCH_ONLY) {
RecordPrefetchResponseReceived( RecordPrefetchResponseReceived(
......
...@@ -46,11 +46,11 @@ class PrerenderURLLoaderThrottle ...@@ -46,11 +46,11 @@ class PrerenderURLLoaderThrottle
void DetachFromCurrentSequence() override; void DetachFromCurrentSequence() override;
void WillStartRequest(network::ResourceRequest* request, void WillStartRequest(network::ResourceRequest* request,
bool* defer) override; bool* defer) override;
void WillRedirectRequest( void WillRedirectRequest(const net::RedirectInfo& redirect_info,
const net::RedirectInfo& redirect_info, const network::ResourceResponseHead& response_head,
const network::ResourceResponseHead& response_head, bool* defer,
bool* defer, std::vector<std::string>* to_be_removed_headers,
std::vector<std::string>* to_be_removed_headers) override; net::HttpRequestHeaders* modified_headers) override;
void WillProcessResponse(const GURL& response_url, void WillProcessResponse(const GURL& response_url,
network::ResourceResponseHead* response_head, network::ResourceResponseHead* response_head,
bool* defer) override; bool* defer) override;
......
...@@ -2655,6 +2655,7 @@ test("unit_tests") { ...@@ -2655,6 +2655,7 @@ test("unit_tests") {
"../browser/signin/chrome_signin_client_unittest.cc", "../browser/signin/chrome_signin_client_unittest.cc",
"../browser/signin/chrome_signin_helper_unittest.cc", "../browser/signin/chrome_signin_helper_unittest.cc",
"../browser/signin/chrome_signin_status_metrics_provider_delegate_unittest.cc", "../browser/signin/chrome_signin_status_metrics_provider_delegate_unittest.cc",
"../browser/signin/chrome_signin_url_loader_throttle_unittest.cc",
"../browser/signin/local_auth_unittest.cc", "../browser/signin/local_auth_unittest.cc",
"../browser/signin/signin_status_metrics_provider_chromeos_unittest.cc", "../browser/signin/signin_status_metrics_provider_chromeos_unittest.cc",
"../browser/signin/signin_tracker_unittest.cc", "../browser/signin/signin_tracker_unittest.cc",
......
...@@ -140,12 +140,15 @@ void BaseParallelResourceThrottle::WillRedirectRequest( ...@@ -140,12 +140,15 @@ void BaseParallelResourceThrottle::WillRedirectRequest(
return; return;
} }
// The safe browsing URLLoaderThrottle doesn't use ResourceResponse, so pass // The safe browsing URLLoaderThrottle doesn't use the |resource_head|,
// |to_be_modified_headers| or |modified_headers| parameters, so pass
// in an empty struct to avoid changing ResourceThrottle signature. // in an empty struct to avoid changing ResourceThrottle signature.
network::ResourceResponseHead resource_response; network::ResourceResponseHead resource_head;
std::vector<std::string> to_be_removed_headers; std::vector<std::string> to_be_removed_headers;
net::HttpRequestHeaders modified_headers;
url_loader_throttle_holder_->throttle()->WillRedirectRequest( url_loader_throttle_holder_->throttle()->WillRedirectRequest(
redirect_info, resource_response, defer, &to_be_removed_headers); redirect_info, resource_head, defer, &to_be_removed_headers,
&modified_headers);
DCHECK(!*defer); DCHECK(!*defer);
throttle_in_band_ = false; throttle_in_band_ = false;
} }
......
...@@ -68,9 +68,10 @@ void BrowserURLLoaderThrottle::WillStartRequest( ...@@ -68,9 +68,10 @@ void BrowserURLLoaderThrottle::WillStartRequest(
void BrowserURLLoaderThrottle::WillRedirectRequest( void BrowserURLLoaderThrottle::WillRedirectRequest(
const net::RedirectInfo& redirect_info, const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head, const network::ResourceResponseHead& /* response_head */,
bool* defer, bool* defer,
std::vector<std::string>* to_be_removed_headers) { std::vector<std::string>* /* to_be_removed_headers */,
net::HttpRequestHeaders* /* modified_headers */) {
if (blocked_) { if (blocked_) {
// OnCheckUrlResult() has set |blocked_| to true and called // OnCheckUrlResult() has set |blocked_| to true and called
// |delegate_->CancelWithError|, but this method is called before the // |delegate_->CancelWithError|, but this method is called before the
......
...@@ -43,11 +43,11 @@ class BrowserURLLoaderThrottle : public content::URLLoaderThrottle { ...@@ -43,11 +43,11 @@ class BrowserURLLoaderThrottle : public content::URLLoaderThrottle {
// content::URLLoaderThrottle implementation. // content::URLLoaderThrottle implementation.
void WillStartRequest(network::ResourceRequest* request, void WillStartRequest(network::ResourceRequest* request,
bool* defer) override; bool* defer) override;
void WillRedirectRequest( void WillRedirectRequest(const net::RedirectInfo& redirect_info,
const net::RedirectInfo& redirect_info, const network::ResourceResponseHead& response_head,
const network::ResourceResponseHead& response_head, bool* defer,
bool* defer, std::vector<std::string>* to_be_removed_headers,
std::vector<std::string>* to_be_removed_headers) override; net::HttpRequestHeaders* modified_headers) override;
void WillProcessResponse(const GURL& response_url, void WillProcessResponse(const GURL& response_url,
network::ResourceResponseHead* response_head, network::ResourceResponseHead* response_head,
bool* defer) override; bool* defer) override;
......
...@@ -71,9 +71,10 @@ void RendererURLLoaderThrottle::WillStartRequest( ...@@ -71,9 +71,10 @@ void RendererURLLoaderThrottle::WillStartRequest(
void RendererURLLoaderThrottle::WillRedirectRequest( void RendererURLLoaderThrottle::WillRedirectRequest(
const net::RedirectInfo& redirect_info, const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head, const network::ResourceResponseHead& /* response_head */,
bool* defer, bool* /* defer */,
std::vector<std::string>* to_be_removed_headers) { std::vector<std::string>* /* to_be_removed_headers */,
net::HttpRequestHeaders* /* modified_headers */) {
// If |blocked_| is true, the resource load has been canceled and there // If |blocked_| is true, the resource load has been canceled and there
// shouldn't be such a notification. // shouldn't be such a notification.
DCHECK(!blocked_); DCHECK(!blocked_);
......
...@@ -34,11 +34,11 @@ class RendererURLLoaderThrottle : public content::URLLoaderThrottle, ...@@ -34,11 +34,11 @@ class RendererURLLoaderThrottle : public content::URLLoaderThrottle,
void DetachFromCurrentSequence() override; void DetachFromCurrentSequence() override;
void WillStartRequest(network::ResourceRequest* request, void WillStartRequest(network::ResourceRequest* request,
bool* defer) override; bool* defer) override;
void WillRedirectRequest( void WillRedirectRequest(const net::RedirectInfo& redirect_info,
const net::RedirectInfo& redirect_info, const network::ResourceResponseHead& response_head,
const network::ResourceResponseHead& response_head, bool* defer,
bool* defer, std::vector<std::string>* to_be_removed_headers,
std::vector<std::string>* to_be_removed_headers) override; net::HttpRequestHeaders* modified_headers) override;
void WillProcessResponse(const GURL& response_url, void WillProcessResponse(const GURL& response_url,
network::ResourceResponseHead* response_head, network::ResourceResponseHead* response_head,
bool* defer) override; bool* defer) override;
......
...@@ -155,9 +155,10 @@ void AdDelayThrottle::WillStartRequest(network::ResourceRequest* request, ...@@ -155,9 +155,10 @@ void AdDelayThrottle::WillStartRequest(network::ResourceRequest* request,
void AdDelayThrottle::WillRedirectRequest( void AdDelayThrottle::WillRedirectRequest(
const net::RedirectInfo& redirect_info, const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head, const network::ResourceResponseHead& /* response_head */,
bool* defer, bool* defer,
std::vector<std::string>* to_be_removed_headers) { std::vector<std::string>* /* to_be_removed_headers */,
net::HttpRequestHeaders* /* modified_headers */) {
// Note: some MetadataProviders may not be able to distinguish requests that // Note: some MetadataProviders may not be able to distinguish requests that
// are only tagged as ads after a redirect. // are only tagged as ads after a redirect.
*defer = MaybeDefer(redirect_info.new_url); *defer = MaybeDefer(redirect_info.new_url);
......
...@@ -138,11 +138,11 @@ class AdDelayThrottle : public content::URLLoaderThrottle { ...@@ -138,11 +138,11 @@ class AdDelayThrottle : public content::URLLoaderThrottle {
void DetachFromCurrentSequence() override; void DetachFromCurrentSequence() override;
void WillStartRequest(network::ResourceRequest* request, void WillStartRequest(network::ResourceRequest* request,
bool* defer) override; bool* defer) override;
void WillRedirectRequest( void WillRedirectRequest(const net::RedirectInfo& redirect_info,
const net::RedirectInfo& redirect_info, const network::ResourceResponseHead& response_head,
const network::ResourceResponseHead& response_head, bool* defer,
bool* defer, std::vector<std::string>* to_be_removed_headers,
std::vector<std::string>* to_be_removed_headers) override; net::HttpRequestHeaders* modified_headers) override;
// Returns whether the request to |url| should be deferred. // Returns whether the request to |url| should be deferred.
bool MaybeDefer(const GURL& url); bool MaybeDefer(const GURL& url);
......
...@@ -40,10 +40,11 @@ class DeferringURLLoaderThrottle final : public URLLoaderThrottle { ...@@ -40,10 +40,11 @@ class DeferringURLLoaderThrottle final : public URLLoaderThrottle {
} }
void WillRedirectRequest( void WillRedirectRequest(
const net::RedirectInfo& redirect_info, const net::RedirectInfo& /* redirect_info */,
const network::ResourceResponseHead& response_head, const network::ResourceResponseHead& /* response_head */,
bool* defer, bool* defer,
std::vector<std::string>* to_be_removed_headers) override { std::vector<std::string>* /* to_be_removed_headers */,
net::HttpRequestHeaders* /* modified_headers */) override {
will_redirect_request_called_ = true; will_redirect_request_called_ = true;
*defer = true; *defer = true;
} }
......
...@@ -189,35 +189,48 @@ ThrottlingURLLoader::~ThrottlingURLLoader() { ...@@ -189,35 +189,48 @@ ThrottlingURLLoader::~ThrottlingURLLoader() {
} }
void ThrottlingURLLoader::FollowRedirect( void ThrottlingURLLoader::FollowRedirect(
const base::Optional<net::HttpRequestHeaders>& modified_request_headers) { const base::Optional<net::HttpRequestHeaders>& modified_headers) {
const base::Optional<net::HttpRequestHeaders>* modified_headers_to_send =
&modified_headers;
if (modified_request_headers_) {
if (modified_headers)
modified_request_headers_->MergeFrom(*modified_headers);
modified_headers_to_send = &modified_request_headers_;
}
if (!throttle_redirect_url_.is_empty()) { if (!throttle_redirect_url_.is_empty()) {
throttle_redirect_url_ = GURL(); throttle_redirect_url_ = GURL();
// This is a synthesized redirect, so no need to tell the URLLoader. // This is a synthesized redirect, so no need to tell the URLLoader.
DCHECK(!modified_request_headers.has_value()) DCHECK(!modified_headers_to_send->has_value())
<< "ThrottlingURLLoader doesn't support modified_request_headers for " << "ThrottlingURLLoader doesn't support modifying headers for "
"synthesized requests."; "synthesized requests.";
StartNow(); StartNow();
return; return;
} }
if (url_loader_) { if (url_loader_) {
if (to_be_removed_request_headers_.empty()) { url_loader_->FollowRedirect(to_be_removed_request_headers_,
url_loader_->FollowRedirect(base::nullopt, modified_request_headers); *modified_headers_to_send);
} else {
url_loader_->FollowRedirect(to_be_removed_request_headers_,
modified_request_headers);
}
to_be_removed_request_headers_.clear();
} }
to_be_removed_request_headers_.reset();
modified_request_headers_.reset();
} }
void ThrottlingURLLoader::FollowRedirectForcingRestart() { void ThrottlingURLLoader::FollowRedirectForcingRestart() {
url_loader_.reset(); url_loader_.reset();
client_binding_.Close(); client_binding_.Close();
for (const std::string& key : to_be_removed_request_headers_) if (to_be_removed_request_headers_) {
start_info_->url_request.headers.RemoveHeader(key); for (const std::string& key : *to_be_removed_request_headers_)
to_be_removed_request_headers_.clear(); start_info_->url_request.headers.RemoveHeader(key);
to_be_removed_request_headers_.reset();
}
if (modified_request_headers_) {
start_info_->url_request.headers.MergeFrom(*modified_request_headers_);
modified_request_headers_.reset();
}
StartNow(); StartNow();
} }
...@@ -417,16 +430,33 @@ void ThrottlingURLLoader::OnReceiveRedirect( ...@@ -417,16 +430,33 @@ void ThrottlingURLLoader::OnReceiveRedirect(
auto* throttle = entry.throttle.get(); auto* throttle = entry.throttle.get();
bool throttle_deferred = false; bool throttle_deferred = false;
auto weak_ptr = weak_factory_.GetWeakPtr(); auto weak_ptr = weak_factory_.GetWeakPtr();
std::vector<std::string> headers; std::vector<std::string> to_be_removed_headers;
net::HttpRequestHeaders modified_headers;
throttle->WillRedirectRequest(redirect_info, response_head, throttle->WillRedirectRequest(redirect_info, response_head,
&throttle_deferred, &headers); &throttle_deferred, &to_be_removed_headers,
&modified_headers);
if (!weak_ptr) if (!weak_ptr)
return; return;
if (!HandleThrottleResult(throttle, throttle_deferred, &deferred)) if (!HandleThrottleResult(throttle, throttle_deferred, &deferred))
return; return;
to_be_removed_request_headers_.insert( if (!to_be_removed_headers.empty()) {
to_be_removed_request_headers_.end(), headers.begin(), headers.end()); if (to_be_removed_request_headers_) {
for (auto& header : to_be_removed_headers) {
if (!base::ContainsValue(*to_be_removed_request_headers_, header))
to_be_removed_request_headers_->push_back(std::move(header));
}
} else {
to_be_removed_request_headers_ = std::move(to_be_removed_headers);
}
}
if (!modified_headers.IsEmpty()) {
if (modified_request_headers_)
modified_request_headers_->MergeFrom(modified_headers);
else
modified_request_headers_ = std::move(modified_headers);
}
} }
if (deferred) { if (deferred) {
......
...@@ -235,7 +235,8 @@ class CONTENT_EXPORT ThrottlingURLLoader ...@@ -235,7 +235,8 @@ class CONTENT_EXPORT ThrottlingURLLoader
bool response_intercepted_ = false; bool response_intercepted_ = false;
std::vector<std::string> to_be_removed_request_headers_; base::Optional<std::vector<std::string>> to_be_removed_request_headers_;
base::Optional<net::HttpRequestHeaders> modified_request_headers_;
base::WeakPtrFactory<ThrottlingURLLoader> weak_factory_; base::WeakPtrFactory<ThrottlingURLLoader> weak_factory_;
......
...@@ -37,7 +37,8 @@ void URLLoaderThrottle::WillRedirectRequest( ...@@ -37,7 +37,8 @@ void URLLoaderThrottle::WillRedirectRequest(
const net::RedirectInfo& redirect_info, const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head, const network::ResourceResponseHead& response_head,
bool* defer, bool* defer,
std::vector<std::string>* to_be_removed_request_headers) {} std::vector<std::string>* to_be_removed_request_headers,
net::HttpRequestHeaders* modified_request_headers) {}
void URLLoaderThrottle::WillProcessResponse( void URLLoaderThrottle::WillProcessResponse(
const GURL& response_url, const GURL& response_url,
......
...@@ -101,11 +101,17 @@ class CONTENT_EXPORT URLLoaderThrottle { ...@@ -101,11 +101,17 @@ class CONTENT_EXPORT URLLoaderThrottle {
// redirect responses's HTTP status code and some information about the new // redirect responses's HTTP status code and some information about the new
// request that will be sent if the redirect is followed, including the new // request that will be sent if the redirect is followed, including the new
// URL and new method. // URL and new method.
//
// Request headers added to |to_be_removed_request_headers| will be removed
// before the redirect is followed. Headers added to
// |modified_request_headers| will be merged into the existing request headers
// before the redirect is followed.
virtual void WillRedirectRequest( virtual void WillRedirectRequest(
const net::RedirectInfo& redirect_info, const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head, const network::ResourceResponseHead& response_head,
bool* defer, bool* defer,
std::vector<std::string>* to_be_removed_request_headers); std::vector<std::string>* to_be_removed_request_headers,
net::HttpRequestHeaders* modified_request_headers);
// Called when the response headers and meta data are available. // Called when the response headers and meta data are available.
// TODO(776312): Migrate this URL to ResourceResponseHead. // TODO(776312): Migrate this URL to ResourceResponseHead.
......
...@@ -33,12 +33,14 @@ void ExtensionURLLoaderThrottle::WillStartRequest( ...@@ -33,12 +33,14 @@ void ExtensionURLLoaderThrottle::WillStartRequest(
void ExtensionURLLoaderThrottle::WillRedirectRequest( void ExtensionURLLoaderThrottle::WillRedirectRequest(
const net::RedirectInfo& redirect_info, const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head, const network::ResourceResponseHead& /* response_head */,
bool* defer, bool* /* defer */,
std::vector<std::string>* to_be_removed_request_headers) { std::vector<std::string>* /* to_be_removed_request_headers */,
net::HttpRequestHeaders* /* modified_request_headers */) {
if (manager_->ShouldRejectRedirect(start_request_url_, request_load_flags_, if (manager_->ShouldRejectRedirect(start_request_url_, request_load_flags_,
redirect_info)) redirect_info)) {
delegate_->CancelWithError(net::ERR_TEMPORARILY_THROTTLED, kCancelReason); delegate_->CancelWithError(net::ERR_TEMPORARILY_THROTTLED, kCancelReason);
}
} }
void ExtensionURLLoaderThrottle::WillProcessResponse( void ExtensionURLLoaderThrottle::WillProcessResponse(
......
...@@ -32,7 +32,8 @@ class ExtensionURLLoaderThrottle : public content::URLLoaderThrottle { ...@@ -32,7 +32,8 @@ class ExtensionURLLoaderThrottle : public content::URLLoaderThrottle {
const net::RedirectInfo& redirect_info, const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head, const network::ResourceResponseHead& response_head,
bool* defer, bool* defer,
std::vector<std::string>* to_be_removed_request_headers) override; std::vector<std::string>* to_be_removed_request_headers,
net::HttpRequestHeaders* modified_request_headers) override;
void WillProcessResponse(const GURL& response_url, void WillProcessResponse(const GURL& response_url,
network::ResourceResponseHead* response_head, network::ResourceResponseHead* response_head,
bool* defer) override; bool* defer) override;
......
...@@ -88,18 +88,8 @@ ...@@ -88,18 +88,8 @@
-DnsProbeBrowserTest.CorrectionsLoadStopped -DnsProbeBrowserTest.CorrectionsLoadStopped
-DnsProbeBrowserTest.NoInternetProbeResultWithSlowBrokenCorrections -DnsProbeBrowserTest.NoInternetProbeResultWithSlowBrokenCorrections
# https://crbug.com/789670 # crbug.com/859594 Migrate storage::FileWriterDelegate to use SimpleURLLoader
-DiceBrowserTest.Reauth -SBNavigationObserverBrowserTest.DownloadViaHTML5FileApi
-DiceBrowserTest.Signin
-DiceBrowserTest.SignoutAllAccounts
-DiceBrowserTest.SignoutMainAccount
-DiceBrowserTest.SignoutSecondaryAccount
-DiceFixAuthErrorsBrowserTest.ReauthFixAuthError
-DiceFixAuthErrorsBrowserTest.SigninAccountMismatch
-DicePrepareMigrationBrowserTest.EnableSyncAfterToken
-DicePrepareMigrationBrowserTest.EnableSyncBeforeToken
-DicePrepareMigrationBrowserTest.Signout
-ChromeResourceDispatcherHostDelegateMirrorBrowserTest.MirrorRequestHeader
# https://crbug.com/778793 # https://crbug.com/778793
# Started failing in r514649. # Started failing in r514649.
......
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