Commit 7a815364 authored by Reilly Grant's avatar Reilly Grant Committed by Commit Bot

Add wrappers around signin access to net::URLRequest

This patch is preparation for allowing signin to work with the Network
Service as in that path there will be no direct access to the
net::URLRequest object. These wrapper classes expose the minimum
interface needed by the signin module to modify headers.

Bug: 789670
Change-Id: I06bc2d99dba2de8359ab2f93d9a220f6c6e3b502
Reviewed-on: https://chromium-review.googlesource.com/1098377
Commit-Queue: Reilly Grant <reillyg@chromium.org>
Reviewed-by: default avatarDavid Roger <droger@chromium.org>
Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#569339}
parent d370bf67
...@@ -430,8 +430,9 @@ void ChromeResourceDispatcherHostDelegate::RequestBeginning( ...@@ -430,8 +430,9 @@ void ChromeResourceDispatcherHostDelegate::RequestBeginning(
if (io_data->policy_header_helper()) if (io_data->policy_header_helper())
io_data->policy_header_helper()->AddPolicyHeaders(request->url(), request); io_data->policy_header_helper()->AddPolicyHeaders(request->url(), request);
signin::FixAccountConsistencyRequestHeader(request, GURL() /* redirect_url */, signin::ChromeRequestAdapter signin_request_adapter(request);
io_data); signin::FixAccountConsistencyRequestHeader(
&signin_request_adapter, GURL() /* redirect_url */, io_data);
AppendStandardResourceThrottles(request, AppendStandardResourceThrottles(request,
resource_context, resource_context,
...@@ -600,8 +601,9 @@ void ChromeResourceDispatcherHostDelegate::OnResponseStarted( ...@@ -600,8 +601,9 @@ void ChromeResourceDispatcherHostDelegate::OnResponseStarted(
const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context); ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context);
signin::ProcessAccountConsistencyResponseHeaders(request, GURL(), signin::ResponseAdapter signin_response_adapter(request);
io_data->IsOffTheRecord()); signin::ProcessAccountConsistencyResponseHeaders(
&signin_response_adapter, GURL(), io_data->IsOffTheRecord());
// Built-in additional protection for the chrome web store origin. // Built-in additional protection for the chrome web store origin.
#if BUILDFLAG(ENABLE_EXTENSIONS) #if BUILDFLAG(ENABLE_EXTENSIONS)
...@@ -676,9 +678,12 @@ void ChromeResourceDispatcherHostDelegate::OnRequestRedirected( ...@@ -676,9 +678,12 @@ void ChromeResourceDispatcherHostDelegate::OnRequestRedirected(
// X-Chrome-Connected header to all Gaia requests from a connected profile so // X-Chrome-Connected header to all Gaia requests from a connected profile so
// Gaia could return a 204 response and let Chrome handle the action with // Gaia could return a 204 response and let Chrome handle the action with
// native UI. // native UI.
signin::FixAccountConsistencyRequestHeader(request, redirect_url, io_data); signin::ChromeRequestAdapter signin_request_adapter(request);
signin::ProcessAccountConsistencyResponseHeaders(request, redirect_url, signin::FixAccountConsistencyRequestHeader(&signin_request_adapter,
io_data->IsOffTheRecord()); redirect_url, io_data);
signin::ResponseAdapter signin_response_adapter(request);
signin::ProcessAccountConsistencyResponseHeaders(
&signin_response_adapter, redirect_url, io_data->IsOffTheRecord());
if (io_data->policy_header_helper()) if (io_data->policy_header_helper())
io_data->policy_header_helper()->AddPolicyHeaders(redirect_url, request); io_data->policy_header_helper()->AddPolicyHeaders(redirect_url, request);
......
...@@ -64,8 +64,9 @@ const char kChromeManageAccountsHeader[] = "X-Chrome-Manage-Accounts"; ...@@ -64,8 +64,9 @@ const char kChromeManageAccountsHeader[] = "X-Chrome-Manage-Accounts";
const char kGoogleSignoutResponseHeader[] = "Google-Accounts-SignOut"; const char kGoogleSignoutResponseHeader[] = "Google-Accounts-SignOut";
#endif #endif
// Key for DiceURLRequestUserData. // Key for RequestDestructionObserverUserData.
const void* const kDiceURLRequestUserDataKey = &kDiceURLRequestUserDataKey; const void* const kRequestDestructionObserverUserDataKey =
&kRequestDestructionObserverUserDataKey;
// TODO(droger): Remove this delay when the Dice implementation is finished on // TODO(droger): Remove this delay when the Dice implementation is finished on
// the server side. // the server side.
...@@ -109,75 +110,45 @@ class AccountReconcilorLockWrapper ...@@ -109,75 +110,45 @@ class AccountReconcilorLockWrapper
DISALLOW_COPY_AND_ASSIGN(AccountReconcilorLockWrapper); DISALLOW_COPY_AND_ASSIGN(AccountReconcilorLockWrapper);
}; };
// The AccountReconcilor is suspended while a Dice request is in flight. This void DestroyLockWrapperAfterDelay(
// allows the DiceResponseHandler to see the response before the scoped_refptr<AccountReconcilorLockWrapper> lock_wrapper) {
// AccountReconcilor starts. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
class DiceURLRequestUserData : public base::SupportsUserData::Data { FROM_HERE,
public: base::BindOnce(
// Attaches a DiceURLRequestUserData to the request if it needs to block the base::DoNothing::Once<scoped_refptr<AccountReconcilorLockWrapper>>(),
// AccountReconcilor. std::move(lock_wrapper)),
static void AttachToRequest(net::URLRequest* request) { base::TimeDelta::FromMilliseconds(
if (ShouldBlockReconcilorForRequest(request) && g_dice_account_reconcilor_blocked_delay_ms));
!request->GetUserData(kDiceURLRequestUserDataKey)) { }
const content::ResourceRequestInfo* info =
content::ResourceRequestInfo::ForRequest(request);
request->SetUserData(kDiceURLRequestUserDataKey,
std::make_unique<DiceURLRequestUserData>(
info->GetWebContentsGetterForRequest()));
}
}
explicit DiceURLRequestUserData( // Returns true if the account reconcilor needs be be blocked while a Gaia
const content::ResourceRequestInfo::WebContentsGetter& // sign-in request is in progress.
web_contents_getter) //
: account_reconcilor_lock_wrapper_(new AccountReconcilorLockWrapper) { // The account reconcilor must be blocked on all request that may change the
// The task takes a reference on the wrapper, because DiceRequestUserData // Gaia authentication cookies. This includes:
// may be deleted before the task is run. // * Main frame requests.
content::BrowserThread::PostTask( // * XHR requests having Gaia URL as referrer.
content::BrowserThread::UI, FROM_HERE, bool ShouldBlockReconcilorForRequest(ChromeRequestAdapter* request) {
base::BindOnce(&AccountReconcilorLockWrapper::CreateLockOnUI, content::ResourceType resource_type = request->GetResourceType();
account_reconcilor_lock_wrapper_, web_contents_getter));
} if (resource_type == content::RESOURCE_TYPE_MAIN_FRAME)
return true;
return (resource_type == content::RESOURCE_TYPE_XHR) &&
gaia::IsGaiaSignonRealm(request->GetReferrerOrigin());
}
// The Gaia cookie is received in one request, and the Dice response in class RequestDestructionObserverUserData : public base::SupportsUserData::Data {
// another request that is immediately following. public:
// Start locking the reconcilor on the first request, and keep it locked for a explicit RequestDestructionObserverUserData(base::OnceClosure closure)
// short time afterwards, to give the second request some time to start and : closure_(std::move(closure)) {}
// lock the reconcilor from there.
~DiceURLRequestUserData() override { ~RequestDestructionObserverUserData() override { std::move(closure_).Run(); }
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(&DiceURLRequestUserData::DoNothing,
account_reconcilor_lock_wrapper_),
base::TimeDelta::FromMilliseconds(
g_dice_account_reconcilor_blocked_delay_ms));
}
private: private:
// Returns true if the account reconcilor needs be be blocked while a Gaia base::OnceClosure closure_;
// sign-in request is in progress.
//
// The account reconcilor must be blocked on all request that may change the
// Gaia authentication cookies. This includes:
// * Main frame requests.
// * XHR requests having Gaia URL as referrer.
static bool ShouldBlockReconcilorForRequest(net::URLRequest* request) {
const content::ResourceRequestInfo* info =
content::ResourceRequestInfo::ForRequest(request);
content::ResourceType resource_type = info->GetResourceType();
if (resource_type == content::RESOURCE_TYPE_MAIN_FRAME)
return true;
return (resource_type == content::RESOURCE_TYPE_XHR) &&
gaia::IsGaiaSignonRealm(GURL(request->referrer()).GetOrigin());
}
// Dummy function used to extend the lifetime of the wrapper by keeping a
// reference on it.
static void DoNothing(scoped_refptr<AccountReconcilorLockWrapper> wrapper) {}
scoped_refptr<AccountReconcilorLockWrapper> account_reconcilor_lock_wrapper_; DISALLOW_COPY_AND_ASSIGN(RequestDestructionObserverUserData);
DISALLOW_COPY_AND_ASSIGN(DiceURLRequestUserData);
}; };
// Processes the mirror response header on the UI thread. Currently depending // Processes the mirror response header on the UI thread. Currently depending
...@@ -340,19 +311,17 @@ void ProcessDiceHeaderUIThread( ...@@ -340,19 +311,17 @@ void ProcessDiceHeaderUIThread(
// Looks for the X-Chrome-Manage-Accounts response header, and if found, // Looks for the X-Chrome-Manage-Accounts response header, and if found,
// tries to show the avatar bubble in the browser identified by the // tries to show the avatar bubble in the browser identified by the
// child/route id. Must be called on IO thread. // child/route id. Must be called on IO thread.
void ProcessMirrorResponseHeaderIfExists(net::URLRequest* request, void ProcessMirrorResponseHeaderIfExists(ResponseAdapter* response,
bool is_off_the_record) { bool is_off_the_record) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
const content::ResourceRequestInfo* info = if (!response->IsMainFrame())
content::ResourceRequestInfo::ForRequest(request);
if (!info || (info->GetResourceType() != content::RESOURCE_TYPE_MAIN_FRAME))
return; return;
if (!gaia::IsGaiaSignonRealm(request->url().GetOrigin())) if (!gaia::IsGaiaSignonRealm(response->GetOrigin()))
return; return;
net::HttpResponseHeaders* response_headers = request->response_headers(); const net::HttpResponseHeaders* response_headers = response->GetHeaders();
if (!response_headers) if (!response_headers)
return; return;
...@@ -377,21 +346,21 @@ void ProcessMirrorResponseHeaderIfExists(net::URLRequest* request, ...@@ -377,21 +346,21 @@ void ProcessMirrorResponseHeaderIfExists(net::URLRequest* request,
content::BrowserThread::PostTask( content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE, content::BrowserThread::UI, FROM_HERE,
base::BindOnce(ProcessMirrorHeaderUIThread, params, base::BindOnce(ProcessMirrorHeaderUIThread, params,
info->GetWebContentsGetterForRequest())); response->GetWebContentsGetter()));
} }
#if BUILDFLAG(ENABLE_DICE_SUPPORT) #if BUILDFLAG(ENABLE_DICE_SUPPORT)
void ProcessDiceResponseHeaderIfExists(net::URLRequest* request, void ProcessDiceResponseHeaderIfExists(ResponseAdapter* response,
bool is_off_the_record) { bool is_off_the_record) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
if (is_off_the_record) if (is_off_the_record)
return; return;
if (!gaia::IsGaiaSignonRealm(request->url().GetOrigin())) if (!gaia::IsGaiaSignonRealm(response->GetOrigin()))
return; return;
net::HttpResponseHeaders* response_headers = request->response_headers(); const net::HttpResponseHeaders* response_headers = response->GetHeaders();
if (!response_headers) if (!response_headers)
return; return;
...@@ -402,7 +371,7 @@ void ProcessDiceResponseHeaderIfExists(net::URLRequest* request, ...@@ -402,7 +371,7 @@ void ProcessDiceResponseHeaderIfExists(net::URLRequest* request,
params = BuildDiceSigninResponseParams(header_value); params = BuildDiceSigninResponseParams(header_value);
// The header must be removed for privacy reasons, so that renderers never // The header must be removed for privacy reasons, so that renderers never
// have access to the authorization code. // have access to the authorization code.
response_headers->RemoveHeader(kDiceResponseHeader); response->RemoveHeader(kDiceResponseHeader);
} else if (response_headers->GetNormalizedHeader(kGoogleSignoutResponseHeader, } else if (response_headers->GetNormalizedHeader(kGoogleSignoutResponseHeader,
&header_value)) { &header_value)) {
params = BuildDiceSignoutResponseParams(header_value); params = BuildDiceSignoutResponseParams(header_value);
...@@ -413,22 +382,81 @@ void ProcessDiceResponseHeaderIfExists(net::URLRequest* request, ...@@ -413,22 +382,81 @@ void ProcessDiceResponseHeaderIfExists(net::URLRequest* request,
if (params.user_intention == DiceAction::NONE) if (params.user_intention == DiceAction::NONE)
return; return;
const content::ResourceRequestInfo* info =
content::ResourceRequestInfo::ForRequest(request);
content::BrowserThread::PostTask( content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE, content::BrowserThread::UI, FROM_HERE,
base::Bind(ProcessDiceHeaderUIThread, base::Passed(std::move(params)), base::Bind(ProcessDiceHeaderUIThread, base::Passed(std::move(params)),
info->GetWebContentsGetterForRequest())); response->GetWebContentsGetter()));
} }
#endif // BUILDFLAG(ENABLE_DICE_SUPPORT) #endif // BUILDFLAG(ENABLE_DICE_SUPPORT)
} // namespace } // namespace
ChromeRequestAdapter::ChromeRequestAdapter(net::URLRequest* request)
: RequestAdapter(request) {}
ChromeRequestAdapter::~ChromeRequestAdapter() = default;
bool ChromeRequestAdapter::IsMainRequestContext(ProfileIOData* io_data) {
return request_->context() == io_data->GetMainRequestContext();
}
content::ResourceRequestInfo::WebContentsGetter
ChromeRequestAdapter::GetWebContentsGetter() const {
const auto* info = content::ResourceRequestInfo::ForRequest(request_);
return info->GetWebContentsGetterForRequest();
}
content::ResourceType ChromeRequestAdapter::GetResourceType() const {
const auto* info = content::ResourceRequestInfo::ForRequest(request_);
return info->GetResourceType();
}
GURL ChromeRequestAdapter::GetReferrerOrigin() const {
return GURL(request_->referrer()).GetOrigin();
}
void ChromeRequestAdapter::SetDestructionCallback(base::OnceClosure closure) {
if (request_->GetUserData(kRequestDestructionObserverUserDataKey))
return;
request_->SetUserData(
kRequestDestructionObserverUserDataKey,
std::make_unique<RequestDestructionObserverUserData>(std::move(closure)));
}
ResponseAdapter::ResponseAdapter(const net::URLRequest* request)
: request_(request) {}
ResponseAdapter::~ResponseAdapter() = default;
content::ResourceRequestInfo::WebContentsGetter
ResponseAdapter::GetWebContentsGetter() const {
const auto* info = content::ResourceRequestInfo::ForRequest(request_);
return info->GetWebContentsGetterForRequest();
}
bool ResponseAdapter::IsMainFrame() const {
const auto* info = content::ResourceRequestInfo::ForRequest(request_);
return info && (info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME);
}
GURL ResponseAdapter::GetOrigin() const {
return request_->url().GetOrigin();
}
const net::HttpResponseHeaders* ResponseAdapter::GetHeaders() const {
return request_->response_headers();
}
void ResponseAdapter::RemoveHeader(const std::string& name) {
request_->response_headers()->RemoveHeader(name);
}
void SetDiceAccountReconcilorBlockDelayForTesting(int delay_ms) { void SetDiceAccountReconcilorBlockDelayForTesting(int delay_ms) {
g_dice_account_reconcilor_blocked_delay_ms = delay_ms; g_dice_account_reconcilor_blocked_delay_ms = delay_ms;
} }
void FixAccountConsistencyRequestHeader(net::URLRequest* request, void FixAccountConsistencyRequestHeader(ChromeRequestAdapter* request,
const GURL& redirect_url, const GURL& redirect_url,
ProfileIOData* io_data) { ProfileIOData* io_data) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
...@@ -436,7 +464,7 @@ void FixAccountConsistencyRequestHeader(net::URLRequest* request, ...@@ -436,7 +464,7 @@ void FixAccountConsistencyRequestHeader(net::URLRequest* request,
if (io_data->IsOffTheRecord()) if (io_data->IsOffTheRecord())
return; // Account consistency is disabled in incognito. return; // Account consistency is disabled in incognito.
if (io_data->GetMainRequestContext() != request->context()) { if (!request->IsMainRequestContext(io_data)) {
// Account consistency requires the AccountReconcilor, which is only // Account consistency requires the AccountReconcilor, which is only
// attached to the main request context. // attached to the main request context.
// Note: InlineLoginUI uses an isolated request context and thus bypasses // Note: InlineLoginUI uses an isolated request context and thus bypasses
...@@ -475,8 +503,17 @@ void FixAccountConsistencyRequestHeader(net::URLRequest* request, ...@@ -475,8 +503,17 @@ void FixAccountConsistencyRequestHeader(net::URLRequest* request,
// Block the AccountReconcilor while the Dice requests are in flight. This // Block the AccountReconcilor while the Dice requests are in flight. This
// allows the DiceReponseHandler to process the response before the reconcilor // allows the DiceReponseHandler to process the response before the reconcilor
// starts. // starts.
if (dice_header_added) if (dice_header_added && ShouldBlockReconcilorForRequest(request)) {
DiceURLRequestUserData::AttachToRequest(request); auto lock_wrapper = base::MakeRefCounted<AccountReconcilorLockWrapper>();
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::BindOnce(&AccountReconcilorLockWrapper::CreateLockOnUI,
lock_wrapper, request->GetWebContentsGetter()));
// On destruction of the request |lock_wrapper| will be released.
request->SetDestructionCallback(
base::BindOnce(&DestroyLockWrapperAfterDelay, std::move(lock_wrapper)));
}
// Mirror header: // Mirror header:
AppendOrRemoveMirrorRequestHeader( AppendOrRemoveMirrorRequestHeader(
...@@ -484,7 +521,7 @@ void FixAccountConsistencyRequestHeader(net::URLRequest* request, ...@@ -484,7 +521,7 @@ void FixAccountConsistencyRequestHeader(net::URLRequest* request,
io_data->GetCookieSettings(), profile_mode_mask); io_data->GetCookieSettings(), profile_mode_mask);
} }
void ProcessAccountConsistencyResponseHeaders(net::URLRequest* request, void ProcessAccountConsistencyResponseHeaders(ResponseAdapter* response,
const GURL& redirect_url, const GURL& redirect_url,
bool is_off_the_record) { bool is_off_the_record) {
if (redirect_url.is_empty()) { if (redirect_url.is_empty()) {
...@@ -493,13 +530,13 @@ void ProcessAccountConsistencyResponseHeaders(net::URLRequest* request, ...@@ -493,13 +530,13 @@ void ProcessAccountConsistencyResponseHeaders(net::URLRequest* request,
// See if the response contains the X-Chrome-Manage-Accounts header. If so // See if the response contains the X-Chrome-Manage-Accounts header. If so
// show the profile avatar bubble so that user can complete signin/out // show the profile avatar bubble so that user can complete signin/out
// action the native UI. // action the native UI.
ProcessMirrorResponseHeaderIfExists(request, is_off_the_record); ProcessMirrorResponseHeaderIfExists(response, is_off_the_record);
} }
#if BUILDFLAG(ENABLE_DICE_SUPPORT) #if BUILDFLAG(ENABLE_DICE_SUPPORT)
// Process the Dice header: on sign-in, exchange the authorization code for a // Process the Dice header: on sign-in, exchange the authorization code for a
// refresh token, on sign-out just follow the sign-out URL. // refresh token, on sign-out just follow the sign-out URL.
ProcessDiceResponseHeaderIfExists(request, is_off_the_record); ProcessDiceResponseHeaderIfExists(response, is_off_the_record);
#endif // BUILDFLAG(ENABLE_DICE_SUPPORT) #endif // BUILDFLAG(ENABLE_DICE_SUPPORT)
} }
......
...@@ -7,11 +7,15 @@ ...@@ -7,11 +7,15 @@
#include <string> #include <string>
#include "base/macros.h"
#include "components/signin/core/browser/signin_header_helper.h"
#include "content/public/browser/resource_request_info.h" #include "content/public/browser/resource_request_info.h"
namespace net { namespace net {
class HttpResponseHeaders;
class URLRequest; class URLRequest;
} }
class GURL; class GURL;
class ProfileIOData; class ProfileIOData;
...@@ -22,6 +26,44 @@ class ProfileIOData; ...@@ -22,6 +26,44 @@ class ProfileIOData;
// handle signin accordingly. // handle signin accordingly.
namespace signin { namespace signin {
class ChromeRequestAdapter : public RequestAdapter {
public:
explicit ChromeRequestAdapter(net::URLRequest* request);
~ChromeRequestAdapter() override;
virtual bool IsMainRequestContext(ProfileIOData* io_data);
virtual content::ResourceRequestInfo::WebContentsGetter GetWebContentsGetter()
const;
virtual content::ResourceType GetResourceType() const;
virtual GURL GetReferrerOrigin() const;
// Associate a callback with this request which will be executed when the
// request is complete (including any redirects). If a callback was already
// registered this function does nothing.
virtual void SetDestructionCallback(base::OnceClosure closure);
private:
DISALLOW_COPY_AND_ASSIGN(ChromeRequestAdapter);
};
class ResponseAdapter {
public:
explicit ResponseAdapter(const net::URLRequest* request);
virtual ~ResponseAdapter();
virtual content::ResourceRequestInfo::WebContentsGetter GetWebContentsGetter()
const;
virtual bool IsMainFrame() const;
virtual GURL GetOrigin() const;
virtual const net::HttpResponseHeaders* GetHeaders() const;
virtual void RemoveHeader(const std::string& name);
private:
const net::URLRequest* const request_;
DISALLOW_COPY_AND_ASSIGN(ResponseAdapter);
};
// When Dice is enabled, the AccountReconcilor is blocked for a short delay // When Dice is enabled, the AccountReconcilor is blocked for a short delay
// after sending requests to Gaia. Exposed for testing. // after sending requests to Gaia. Exposed for testing.
void SetDiceAccountReconcilorBlockDelayForTesting(int delay_ms); void SetDiceAccountReconcilorBlockDelayForTesting(int delay_ms);
...@@ -31,13 +73,13 @@ void SetDiceAccountReconcilorBlockDelayForTesting(int delay_ms); ...@@ -31,13 +73,13 @@ void SetDiceAccountReconcilorBlockDelayForTesting(int delay_ms);
// thread. // thread.
// Returns true if the account consistency header was added to the request. // Returns true if the account consistency header was added to the request.
// Removes the header if it is already in the headers but should not be there. // Removes the header if it is already in the headers but should not be there.
void FixAccountConsistencyRequestHeader(net::URLRequest* request, void FixAccountConsistencyRequestHeader(ChromeRequestAdapter* request,
const GURL& redirect_url, const GURL& redirect_url,
ProfileIOData* io_data); ProfileIOData* io_data);
// Processes account consistency response headers (X-Chrome-Manage-Accounts and // Processes account consistency response headers (X-Chrome-Manage-Accounts and
// Dice). |redirect_url| is empty if the request is not a redirect. // Dice). |redirect_url| is empty if the request is not a redirect.
void ProcessAccountConsistencyResponseHeaders(net::URLRequest* request, void ProcessAccountConsistencyResponseHeaders(ResponseAdapter* response,
const GURL& redirect_url, const GURL& redirect_url,
bool is_off_the_record); bool is_off_the_record);
......
...@@ -90,7 +90,8 @@ TEST_F(ChromeSigninHelperTest, RemoveDiceSigninHeader) { ...@@ -90,7 +90,8 @@ TEST_F(ChromeSigninHelperTest, RemoveDiceSigninHeader) {
ASSERT_TRUE(request_->response_headers()->HasHeader(kDiceResponseHeader)); ASSERT_TRUE(request_->response_headers()->HasHeader(kDiceResponseHeader));
// Process the header. // Process the header.
signin::ProcessAccountConsistencyResponseHeaders(request_.get(), GURL(), signin::ResponseAdapter response_adapter(request_.get());
signin::ProcessAccountConsistencyResponseHeaders(&response_adapter, GURL(),
false /* is_incognito */); false /* is_incognito */);
// Check that the header has been removed. // Check that the header has been removed.
......
...@@ -63,7 +63,9 @@ void TestMirrorRequestForProfileOnIOThread( ...@@ -63,7 +63,9 @@ void TestMirrorRequestForProfileOnIOThread(
profile_io->GetMainRequestContext()->CreateRequest( profile_io->GetMainRequestContext()->CreateRequest(
GURL(kGaiaUrl), net::DEFAULT_PRIORITY, nullptr, GURL(kGaiaUrl), net::DEFAULT_PRIORITY, nullptr,
TRAFFIC_ANNOTATION_FOR_TESTS); TRAFFIC_ANNOTATION_FOR_TESTS);
signin::FixAccountConsistencyRequestHeader(request.get(), GURL(), profile_io); signin::ChromeRequestAdapter signin_request_adapter(request.get());
signin::FixAccountConsistencyRequestHeader(&signin_request_adapter, GURL(),
profile_io);
CheckRequestHeader(request.get(), kChromeConnectedHeader, CheckRequestHeader(request.get(), kChromeConnectedHeader,
expected_header_value); expected_header_value);
......
...@@ -65,6 +65,27 @@ DiceResponseParams::EnableSyncInfo::~EnableSyncInfo() {} ...@@ -65,6 +65,27 @@ DiceResponseParams::EnableSyncInfo::~EnableSyncInfo() {}
DiceResponseParams::EnableSyncInfo::EnableSyncInfo(const EnableSyncInfo&) = DiceResponseParams::EnableSyncInfo::EnableSyncInfo(const EnableSyncInfo&) =
default; default;
RequestAdapter::RequestAdapter(net::URLRequest* request) : request_(request) {}
RequestAdapter::~RequestAdapter() = default;
const GURL& RequestAdapter::GetUrl() {
return request_->url();
}
bool RequestAdapter::HasHeader(const std::string& name) {
return request_->extra_request_headers().HasHeader(name);
}
void RequestAdapter::RemoveRequestHeaderByName(const std::string& name) {
return request_->RemoveRequestHeaderByName(name);
}
void RequestAdapter::SetExtraHeaderByName(const std::string& name,
const std::string& value) {
return request_->SetExtraRequestHeaderByName(name, value, false);
}
std::string BuildMirrorRequestCookieIfPossible( std::string BuildMirrorRequestCookieIfPossible(
const GURL& url, const GURL& url,
const std::string& account_id, const std::string& account_id,
...@@ -76,7 +97,7 @@ std::string BuildMirrorRequestCookieIfPossible( ...@@ -76,7 +97,7 @@ std::string BuildMirrorRequestCookieIfPossible(
} }
bool SigninHeaderHelper::AppendOrRemoveRequestHeader( bool SigninHeaderHelper::AppendOrRemoveRequestHeader(
net::URLRequest* request, RequestAdapter* request,
const GURL& redirect_url, const GURL& redirect_url,
const char* header_name, const char* header_name,
const std::string& header_value) { const std::string& header_value) {
...@@ -84,15 +105,14 @@ bool SigninHeaderHelper::AppendOrRemoveRequestHeader( ...@@ -84,15 +105,14 @@ bool SigninHeaderHelper::AppendOrRemoveRequestHeader(
// If the request is being redirected, and it has the account consistency // If the request is being redirected, and it has the account consistency
// header, and current url is a Google URL, and the redirected one is not, // header, and current url is a Google URL, and the redirected one is not,
// remove the header. // remove the header.
if (!redirect_url.is_empty() && if (!redirect_url.is_empty() && request->HasHeader(header_name) &&
request->extra_request_headers().HasHeader(header_name) && IsUrlEligibleForRequestHeader(request->GetUrl()) &&
IsUrlEligibleForRequestHeader(request->url()) &&
!IsUrlEligibleForRequestHeader(redirect_url)) { !IsUrlEligibleForRequestHeader(redirect_url)) {
request->RemoveRequestHeaderByName(header_name); request->RemoveRequestHeaderByName(header_name);
} }
return false; return false;
} }
request->SetExtraRequestHeaderByName(header_name, header_value, false); request->SetExtraHeaderByName(header_name, header_value);
return true; return true;
} }
...@@ -134,13 +154,13 @@ bool SigninHeaderHelper::ShouldBuildRequestHeader( ...@@ -134,13 +154,13 @@ bool SigninHeaderHelper::ShouldBuildRequestHeader(
} }
void AppendOrRemoveMirrorRequestHeader( void AppendOrRemoveMirrorRequestHeader(
net::URLRequest* request, RequestAdapter* request,
const GURL& redirect_url, const GURL& redirect_url,
const std::string& account_id, const std::string& account_id,
AccountConsistencyMethod account_consistency, AccountConsistencyMethod account_consistency,
const content_settings::CookieSettings* cookie_settings, const content_settings::CookieSettings* cookie_settings,
int profile_mode_mask) { int profile_mode_mask) {
const GURL& url = redirect_url.is_empty() ? request->url() : redirect_url; const GURL& url = redirect_url.is_empty() ? request->GetUrl() : redirect_url;
ChromeConnectedHeaderHelper chrome_connected_helper(account_consistency); ChromeConnectedHeaderHelper chrome_connected_helper(account_consistency);
std::string chrome_connected_header_value; std::string chrome_connected_header_value;
if (chrome_connected_helper.ShouldBuildRequestHeader(url, cookie_settings)) { if (chrome_connected_helper.ShouldBuildRequestHeader(url, cookie_settings)) {
...@@ -153,7 +173,7 @@ void AppendOrRemoveMirrorRequestHeader( ...@@ -153,7 +173,7 @@ void AppendOrRemoveMirrorRequestHeader(
} }
bool AppendOrRemoveDiceRequestHeader( bool AppendOrRemoveDiceRequestHeader(
net::URLRequest* request, RequestAdapter* request,
const GURL& redirect_url, const GURL& redirect_url,
const std::string& account_id, const std::string& account_id,
bool sync_enabled, bool sync_enabled,
...@@ -161,7 +181,7 @@ bool AppendOrRemoveDiceRequestHeader( ...@@ -161,7 +181,7 @@ bool AppendOrRemoveDiceRequestHeader(
AccountConsistencyMethod account_consistency, AccountConsistencyMethod account_consistency,
const content_settings::CookieSettings* cookie_settings) { const content_settings::CookieSettings* cookie_settings) {
#if BUILDFLAG(ENABLE_DICE_SUPPORT) #if BUILDFLAG(ENABLE_DICE_SUPPORT)
const GURL& url = redirect_url.is_empty() ? request->url() : redirect_url; const GURL& url = redirect_url.is_empty() ? request->GetUrl() : redirect_url;
DiceHeaderHelper dice_helper( DiceHeaderHelper dice_helper(
!account_id.empty() && sync_has_auth_error && sync_enabled, !account_id.empty() && sync_has_auth_error && sync_enabled,
account_consistency); account_consistency);
......
...@@ -145,12 +145,30 @@ struct DiceResponseParams { ...@@ -145,12 +145,30 @@ struct DiceResponseParams {
DISALLOW_COPY_AND_ASSIGN(DiceResponseParams); DISALLOW_COPY_AND_ASSIGN(DiceResponseParams);
}; };
class RequestAdapter {
public:
explicit RequestAdapter(net::URLRequest* request);
virtual ~RequestAdapter();
virtual const GURL& GetUrl();
virtual bool HasHeader(const std::string& name);
virtual void RemoveRequestHeaderByName(const std::string& name);
virtual void SetExtraHeaderByName(const std::string& name,
const std::string& value);
protected:
net::URLRequest* const request_;
private:
DISALLOW_COPY_AND_ASSIGN(RequestAdapter);
};
// Base class for managing the signin headers (Dice and Chrome-Connected). // Base class for managing the signin headers (Dice and Chrome-Connected).
class SigninHeaderHelper { class SigninHeaderHelper {
public: public:
// Appends or remove the header to a network request if necessary. // Appends or remove the header to a network request if necessary.
// Returns whether the request has the request header. // Returns whether the request has the request header.
bool AppendOrRemoveRequestHeader(net::URLRequest* request, bool AppendOrRemoveRequestHeader(RequestAdapter* request,
const GURL& redirect_url, const GURL& redirect_url,
const char* header_name, const char* header_name,
const std::string& header_value); const std::string& header_value);
...@@ -192,7 +210,7 @@ std::string BuildMirrorRequestCookieIfPossible( ...@@ -192,7 +210,7 @@ std::string BuildMirrorRequestCookieIfPossible(
// the exception of requests from gaia webview. // the exception of requests from gaia webview.
// Removes the header in case it should not be transfered to a redirected url. // Removes the header in case it should not be transfered to a redirected url.
void AppendOrRemoveMirrorRequestHeader( void AppendOrRemoveMirrorRequestHeader(
net::URLRequest* request, RequestAdapter* request,
const GURL& redirect_url, const GURL& redirect_url,
const std::string& account_id, const std::string& account_id,
AccountConsistencyMethod account_consistency, AccountConsistencyMethod account_consistency,
...@@ -204,7 +222,7 @@ void AppendOrRemoveMirrorRequestHeader( ...@@ -204,7 +222,7 @@ void AppendOrRemoveMirrorRequestHeader(
// Removes the header in case it should not be transfered to a redirected url. // Removes the header in case it should not be transfered to a redirected url.
// Returns whether the request has the Dice request header. // Returns whether the request has the Dice request header.
bool AppendOrRemoveDiceRequestHeader( bool AppendOrRemoveDiceRequestHeader(
net::URLRequest* request, RequestAdapter* request,
const GURL& redirect_url, const GURL& redirect_url,
const std::string& account_id, const std::string& account_id,
bool sync_enabled, bool sync_enabled,
......
...@@ -58,11 +58,12 @@ class SigninHeaderHelperTest : public testing::Test { ...@@ -58,11 +58,12 @@ class SigninHeaderHelperTest : public testing::Test {
std::unique_ptr<net::URLRequest> url_request = std::unique_ptr<net::URLRequest> url_request =
url_request_context_.CreateRequest(url, net::DEFAULT_PRIORITY, nullptr, url_request_context_.CreateRequest(url, net::DEFAULT_PRIORITY, nullptr,
TRAFFIC_ANNOTATION_FOR_TESTS); TRAFFIC_ANNOTATION_FOR_TESTS);
RequestAdapter request_adapter(url_request.get());
AppendOrRemoveMirrorRequestHeader( AppendOrRemoveMirrorRequestHeader(
url_request.get(), GURL(), account_id, account_consistency_, &request_adapter, GURL(), account_id, account_consistency_,
cookie_settings_.get(), PROFILE_MODE_DEFAULT); cookie_settings_.get(), PROFILE_MODE_DEFAULT);
AppendOrRemoveDiceRequestHeader( AppendOrRemoveDiceRequestHeader(
url_request.get(), GURL(), account_id, sync_enabled_, &request_adapter, GURL(), account_id, sync_enabled_,
sync_has_auth_error_, account_consistency_, cookie_settings_.get()); sync_has_auth_error_, account_consistency_, cookie_settings_.get());
return url_request; return url_request;
} }
...@@ -182,8 +183,9 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleComNoProfileConsistency) { ...@@ -182,8 +183,9 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleComNoProfileConsistency) {
url_request_context_.CreateRequest(GURL("https://www.google.com"), url_request_context_.CreateRequest(GURL("https://www.google.com"),
net::DEFAULT_PRIORITY, nullptr, net::DEFAULT_PRIORITY, nullptr,
TRAFFIC_ANNOTATION_FOR_TESTS); TRAFFIC_ANNOTATION_FOR_TESTS);
RequestAdapter request_adapter(url_request.get());
AppendOrRemoveMirrorRequestHeader( AppendOrRemoveMirrorRequestHeader(
url_request.get(), GURL(), "0123456789", account_consistency_, &request_adapter, GURL(), "0123456789", account_consistency_,
cookie_settings_.get(), PROFILE_MODE_DEFAULT); cookie_settings_.get(), PROFILE_MODE_DEFAULT);
CheckAccountConsistencyHeaderRequest(url_request.get(), CheckAccountConsistencyHeaderRequest(url_request.get(),
kChromeConnectedHeader, ""); kChromeConnectedHeader, "");
...@@ -196,8 +198,9 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleComProfileConsistency) { ...@@ -196,8 +198,9 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleComProfileConsistency) {
url_request_context_.CreateRequest(GURL("https://www.google.com"), url_request_context_.CreateRequest(GURL("https://www.google.com"),
net::DEFAULT_PRIORITY, nullptr, net::DEFAULT_PRIORITY, nullptr,
TRAFFIC_ANNOTATION_FOR_TESTS); TRAFFIC_ANNOTATION_FOR_TESTS);
RequestAdapter request_adapter(url_request.get());
AppendOrRemoveMirrorRequestHeader( AppendOrRemoveMirrorRequestHeader(
url_request.get(), GURL(), "0123456789", account_consistency_, &request_adapter, GURL(), "0123456789", account_consistency_,
cookie_settings_.get(), PROFILE_MODE_DEFAULT); cookie_settings_.get(), PROFILE_MODE_DEFAULT);
CheckAccountConsistencyHeaderRequest( CheckAccountConsistencyHeaderRequest(
url_request.get(), kChromeConnectedHeader, url_request.get(), kChromeConnectedHeader,
...@@ -453,8 +456,9 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderEligibleRedirectURL) { ...@@ -453,8 +456,9 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderEligibleRedirectURL) {
std::unique_ptr<net::URLRequest> url_request = std::unique_ptr<net::URLRequest> url_request =
url_request_context_.CreateRequest(url, net::DEFAULT_PRIORITY, nullptr, url_request_context_.CreateRequest(url, net::DEFAULT_PRIORITY, nullptr,
TRAFFIC_ANNOTATION_FOR_TESTS); TRAFFIC_ANNOTATION_FOR_TESTS);
RequestAdapter request_adapter(url_request.get());
AppendOrRemoveMirrorRequestHeader( AppendOrRemoveMirrorRequestHeader(
url_request.get(), redirect_url, account_id, account_consistency_, &request_adapter, redirect_url, account_id, account_consistency_,
cookie_settings_.get(), PROFILE_MODE_DEFAULT); cookie_settings_.get(), PROFILE_MODE_DEFAULT);
EXPECT_TRUE( EXPECT_TRUE(
url_request->extra_request_headers().HasHeader(kChromeConnectedHeader)); url_request->extra_request_headers().HasHeader(kChromeConnectedHeader));
...@@ -470,8 +474,9 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderNonEligibleRedirectURL) { ...@@ -470,8 +474,9 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderNonEligibleRedirectURL) {
std::unique_ptr<net::URLRequest> url_request = std::unique_ptr<net::URLRequest> url_request =
url_request_context_.CreateRequest(url, net::DEFAULT_PRIORITY, nullptr, url_request_context_.CreateRequest(url, net::DEFAULT_PRIORITY, nullptr,
TRAFFIC_ANNOTATION_FOR_TESTS); TRAFFIC_ANNOTATION_FOR_TESTS);
RequestAdapter request_adapter(url_request.get());
AppendOrRemoveMirrorRequestHeader( AppendOrRemoveMirrorRequestHeader(
url_request.get(), redirect_url, account_id, account_consistency_, &request_adapter, redirect_url, account_id, account_consistency_,
cookie_settings_.get(), PROFILE_MODE_DEFAULT); cookie_settings_.get(), PROFILE_MODE_DEFAULT);
EXPECT_FALSE( EXPECT_FALSE(
url_request->extra_request_headers().HasHeader(kChromeConnectedHeader)); url_request->extra_request_headers().HasHeader(kChromeConnectedHeader));
...@@ -490,8 +495,9 @@ TEST_F(SigninHeaderHelperTest, TestIgnoreMirrorHeaderNonEligibleURLs) { ...@@ -490,8 +495,9 @@ TEST_F(SigninHeaderHelperTest, TestIgnoreMirrorHeaderNonEligibleURLs) {
TRAFFIC_ANNOTATION_FOR_TESTS); TRAFFIC_ANNOTATION_FOR_TESTS);
url_request->SetExtraRequestHeaderByName(kChromeConnectedHeader, fake_header, url_request->SetExtraRequestHeaderByName(kChromeConnectedHeader, fake_header,
false); false);
RequestAdapter request_adapter(url_request.get());
AppendOrRemoveMirrorRequestHeader( AppendOrRemoveMirrorRequestHeader(
url_request.get(), redirect_url, account_id, account_consistency_, &request_adapter, redirect_url, account_id, account_consistency_,
cookie_settings_.get(), PROFILE_MODE_DEFAULT); cookie_settings_.get(), PROFILE_MODE_DEFAULT);
std::string header; std::string header;
EXPECT_TRUE(url_request->extra_request_headers().GetHeader( EXPECT_TRUE(url_request->extra_request_headers().GetHeader(
......
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