Commit 53e6841e authored by Scott Violet's avatar Scott Violet Committed by Commit Bot

weblayer/content: adds ability to set referer on NavigationHandle

This adds NavigationHandle::SetReferer() and calls it from
WebLayer's Navigation::SetRequestHeader().

BUG=1114870
TEST=covered by test

Change-Id: I5154e477422cccebad2a2a9af734e5401ce66533
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2350384
Commit-Queue: Scott Violet <sky@chromium.org>
Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#797792}
parent 10b6d624
...@@ -4578,6 +4578,12 @@ const blink::mojom::Referrer& NavigationRequest::GetReferrer() { ...@@ -4578,6 +4578,12 @@ const blink::mojom::Referrer& NavigationRequest::GetReferrer() {
return *sanitized_referrer_; return *sanitized_referrer_;
} }
void NavigationRequest::SetReferrer(blink::mojom::ReferrerPtr referrer) {
DCHECK(state_ == WILL_START_REQUEST || state_ == WILL_REDIRECT_REQUEST);
sanitized_referrer_ = std::move(referrer);
common_params_->referrer = sanitized_referrer_.Clone();
}
bool NavigationRequest::HasUserGesture() { bool NavigationRequest::HasUserGesture() {
return common_params().has_user_gesture; return common_params().has_user_gesture;
} }
......
...@@ -296,6 +296,7 @@ class CONTENT_EXPORT NavigationRequest ...@@ -296,6 +296,7 @@ class CONTENT_EXPORT NavigationRequest
const NavigationHandleTiming& GetNavigationHandleTiming() override; const NavigationHandleTiming& GetNavigationHandleTiming() override;
bool IsPost() override; bool IsPost() override;
const blink::mojom::Referrer& GetReferrer() override; const blink::mojom::Referrer& GetReferrer() override;
void SetReferrer(blink::mojom::ReferrerPtr referrer) override;
bool HasUserGesture() override; bool HasUserGesture() override;
ui::PageTransition GetPageTransition() override; ui::PageTransition GetPageTransition() override;
NavigationUIData* GetNavigationUIData() override; NavigationUIData* GetNavigationUIData() override;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "net/dns/public/resolve_error_info.h" #include "net/dns/public/resolve_error_info.h"
#include "net/http/http_response_info.h" #include "net/http/http_response_info.h"
#include "services/network/public/cpp/resource_request_body.h" #include "services/network/public/cpp/resource_request_body.h"
#include "third_party/blink/public/mojom/loader/referrer.mojom.h"
#include "third_party/blink/public/mojom/loader/transferrable_url_loader.mojom.h" #include "third_party/blink/public/mojom/loader/transferrable_url_loader.mojom.h"
#include "ui/base/page_transition_types.h" #include "ui/base/page_transition_types.h"
...@@ -158,6 +159,12 @@ class CONTENT_EXPORT NavigationHandle { ...@@ -158,6 +159,12 @@ class CONTENT_EXPORT NavigationHandle {
// Returns a sanitized version of the referrer for this request. // Returns a sanitized version of the referrer for this request.
virtual const blink::mojom::Referrer& GetReferrer() = 0; virtual const blink::mojom::Referrer& GetReferrer() = 0;
// Sets the referrer. The referrer may only be set during start and redirect
// phases. If the referer is set in navigation start, it is reset during the
// redirect. In other words, if you need to set a referer that applies to
// redirects, then this must be called during DidRedirectNavigation().
virtual void SetReferrer(blink::mojom::ReferrerPtr referrer) = 0;
// Whether the navigation was initiated by a user gesture. Note that this // Whether the navigation was initiated by a user gesture. Note that this
// will return false for browser-initiated navigations. // will return false for browser-initiated navigations.
// TODO(clamy): This should return true for browser-initiated navigations. // TODO(clamy): This should return true for browser-initiated navigations.
......
...@@ -58,6 +58,7 @@ class MockNavigationHandle : public NavigationHandle { ...@@ -58,6 +58,7 @@ class MockNavigationHandle : public NavigationHandle {
const GURL& GetBaseURLForDataURL() override { return base_url_for_data_url_; } const GURL& GetBaseURLForDataURL() override { return base_url_for_data_url_; }
MOCK_METHOD0(IsPost, bool()); MOCK_METHOD0(IsPost, bool());
const blink::mojom::Referrer& GetReferrer() override { return referrer_; } const blink::mojom::Referrer& GetReferrer() override { return referrer_; }
void SetReferrer(blink::mojom::ReferrerPtr referrer) override {}
MOCK_METHOD0(HasUserGesture, bool()); MOCK_METHOD0(HasUserGesture, bool());
ui::PageTransition GetPageTransition() override { return page_transition_; } ui::PageTransition GetPageTransition() override { return page_transition_; }
MOCK_METHOD0(GetNavigationUIData, NavigationUIData*()); MOCK_METHOD0(GetNavigationUIData, NavigationUIData*());
......
...@@ -365,6 +365,28 @@ IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, SetRequestHeader) { ...@@ -365,6 +365,28 @@ IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, SetRequestHeader) {
EXPECT_EQ(header_value, response_2.http_request()->headers.at(header_name)); EXPECT_EQ(header_value, response_2.http_request()->headers.at(header_name));
} }
// Verifies setting the 'referer' via SetRequestHeader() works as expected.
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, SetRequestHeaderWithReferer) {
net::test_server::ControllableHttpResponse response(embedded_test_server(),
"", true);
ASSERT_TRUE(embedded_test_server()->Start());
const std::string header_name = "Referer";
const std::string header_value = "http://request.com";
NavigationObserverImpl observer(GetNavigationController());
observer.SetStartedCallback(
base::BindLambdaForTesting([&](Navigation* navigation) {
navigation->SetRequestHeader(header_name, header_value);
}));
shell()->LoadURL(embedded_test_server()->GetURL("/simple_page.html"));
response.WaitForRequest();
// Verify 'referer' matches expected value.
EXPECT_EQ(GURL(header_value),
GURL(response.http_request()->headers.at(header_name)));
}
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, SetRequestHeaderInRedirect) { IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, SetRequestHeaderInRedirect) {
net::test_server::ControllableHttpResponse response_1(embedded_test_server(), net::test_server::ControllableHttpResponse response_1(embedded_test_server(),
"", true); "", true);
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
#include "net/http/http_util.h" #include "net/http/http_util.h"
#include "third_party/blink/public/common/user_agent/user_agent_metadata.h" #include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
#include "third_party/blink/public/mojom/loader/referrer.mojom.h"
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
#include "base/android/jni_array.h" #include "base/android/jni_array.h"
...@@ -158,8 +159,17 @@ Navigation::LoadError NavigationImpl::GetLoadError() { ...@@ -158,8 +159,17 @@ Navigation::LoadError NavigationImpl::GetLoadError() {
void NavigationImpl::SetRequestHeader(const std::string& name, void NavigationImpl::SetRequestHeader(const std::string& name,
const std::string& value) { const std::string& value) {
if (base::ToLowerASCII(name) == "referer") {
// The referrer needs to be special cased as content maintains it
// separately.
auto referrer = blink::mojom::Referrer::New();
referrer->url = GURL(value);
referrer->policy = network::mojom::ReferrerPolicy::kDefault;
navigation_handle_->SetReferrer(std::move(referrer));
} else {
// Any headers coming from the client should be exempt from CORS checks. // Any headers coming from the client should be exempt from CORS checks.
navigation_handle_->SetCorsExemptRequestHeader(name, value); navigation_handle_->SetCorsExemptRequestHeader(name, value);
}
} }
void NavigationImpl::SetUserAgentString(const std::string& value) { void NavigationImpl::SetUserAgentString(const std::string& value) {
......
...@@ -172,6 +172,10 @@ public class Navigation extends IClientNavigation.Stub { ...@@ -172,6 +172,10 @@ public class Navigation extends IClientNavigation.Stub {
* NavigationCallback.onNavigationRedirected}. When called during start, the header applies to * NavigationCallback.onNavigationRedirected}. When called during start, the header applies to
* both the initial network request as well as redirects. * both the initial network request as well as redirects.
* *
* This method may be used to set the referer. If the referer is set in navigation start, it is
* reset during the redirect. In other words, if you need to set a referer that applies to
* redirects, then this must be called from {@link onNavigationRedirected}.
*
* @param name The name of the header. The name must be rfc 2616 compliant. * @param name The name of the header. The name must be rfc 2616 compliant.
* @param value The value of the header. The value must not contain '\0', '\n' or '\r'. * @param value The value of the header. The value must not contain '\0', '\n' or '\r'.
* *
......
...@@ -94,6 +94,11 @@ class Navigation { ...@@ -94,6 +94,11 @@ class Navigation {
// and redirect. When called during start, the header applies to both the // and redirect. When called during start, the header applies to both the
// start and redirect. |name| must be rfc 2616 compliant and |value| must // start and redirect. |name| must be rfc 2616 compliant and |value| must
// not contain '\0', '\n' or '\r'. // not contain '\0', '\n' or '\r'.
//
// This function may be used to set the referer. If the referer is set in
// navigation start, it is reset during the redirect. In other words, if you
// need to set a referer that applies to redirects, then this must be called
// from NavigationRedirected().
virtual void SetRequestHeader(const std::string& name, virtual void SetRequestHeader(const std::string& name,
const std::string& value) = 0; const std::string& value) = 0;
......
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