summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/http/http_network_transaction.cc22
-rw-r--r--net/http/http_network_transaction_unittest.cc7
-rw-r--r--net/http/http_request_info.h3
-rw-r--r--net/http/http_stream_factory_impl_job.cc2
-rw-r--r--net/http/http_vary_data.cc6
-rw-r--r--net/socket/client_socket_pool_manager.cc14
-rw-r--r--net/socket/client_socket_pool_manager.h2
-rw-r--r--net/url_request/url_request_http_job.cc13
-rw-r--r--net/url_request/url_request_unittest.cc44
9 files changed, 43 insertions, 70 deletions
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index d7a65e2..8b06a3b 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -695,6 +695,13 @@ void HttpNetworkTransaction::BuildRequestHeaders(bool using_proxy) {
request_headers_.SetHeader(HttpRequestHeaders::kConnection, "keep-alive");
}
+ // Our consumer should have made sure that this is a safe referrer. See for
+ // instance WebCore::FrameLoader::HideReferrer.
+ if (request_->referrer.is_valid()) {
+ request_headers_.SetHeader(HttpRequestHeaders::kReferer,
+ request_->referrer.spec());
+ }
+
// Add a content length header?
if (request_body_.get()) {
if (request_body_->is_chunked()) {
@@ -729,7 +736,20 @@ void HttpNetworkTransaction::BuildRequestHeaders(bool using_proxy) {
auth_controllers_[HttpAuth::AUTH_SERVER]->AddAuthorizationHeader(
&request_headers_);
- request_headers_.MergeFrom(request_->extra_headers);
+ // Headers that will be stripped from request_->extra_headers to prevent,
+ // e.g., plugins from overriding headers that are controlled using other
+ // means. Otherwise a plugin could set a referrer although sending the
+ // referrer is inhibited.
+ // TODO(jochen): check whether also other headers should be stripped.
+ static const char* const kExtraHeadersToBeStripped[] = {
+ "Referer"
+ };
+
+ HttpRequestHeaders stripped_extra_headers;
+ stripped_extra_headers.CopyFrom(request_->extra_headers);
+ for (size_t i = 0; i < arraysize(kExtraHeadersToBeStripped); ++i)
+ stripped_extra_headers.RemoveHeader(kExtraHeadersToBeStripped[i]);
+ request_headers_.MergeFrom(stripped_extra_headers);
}
int HttpNetworkTransaction::DoBuildRequest() {
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 65d699e..45b3d79 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -4910,8 +4910,7 @@ TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
request.method = "GET";
request.url = GURL("http://www.google.com/");
request.load_flags = 0;
- request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
- "http://the.previous.site.com/");
+ request.referrer = GURL("http://the.previous.site.com/");
SessionDependencies session_deps;
scoped_ptr<HttpTransaction> trans(
@@ -5188,7 +5187,6 @@ TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
MockWrite("GET / HTTP/1.1\r\n"
"Host: www.google.com\r\n"
"Connection: keep-alive\r\n"
- "referer: www.foo.com\r\n"
"hEllo: Kitty\r\n"
"FoO: bar\r\n\r\n"),
};
@@ -5759,9 +5757,8 @@ TEST_F(HttpNetworkTransactionTest, ResolveMadeWithReferrer) {
// Issue a request, containing an HTTP referrer.
HttpRequestInfo request;
request.method = "GET";
+ request.referrer = referrer;
request.url = GURL("http://www.google.com/");
- request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
- referrer.spec());
SessionDependencies session_deps;
scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
diff --git a/net/http/http_request_info.h b/net/http/http_request_info.h
index c368685..96c47c0 100644
--- a/net/http/http_request_info.h
+++ b/net/http/http_request_info.h
@@ -33,6 +33,9 @@ struct NET_API HttpRequestInfo {
// The requested URL.
GURL url;
+ // The referring URL (if any).
+ GURL referrer;
+
// The method to use (GET, POST, etc.).
std::string method;
diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc
index 52dfa9f..a155609 100644
--- a/net/http/http_stream_factory_impl_job.cc
+++ b/net/http/http_stream_factory_impl_job.cc
@@ -606,6 +606,7 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() {
if (IsPreconnecting()) {
return ClientSocketPoolManager::PreconnectSocketsForHttpRequest(
origin_url_,
+ request_info_.referrer,
request_info_.extra_headers,
request_info_.load_flags,
request_info_.priority,
@@ -620,6 +621,7 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() {
} else {
return ClientSocketPoolManager::InitSocketHandleForHttpRequest(
origin_url_,
+ request_info_.referrer,
request_info_.extra_headers,
request_info_.load_flags,
request_info_.priority,
diff --git a/net/http/http_vary_data.cc b/net/http/http_vary_data.cc
index 09aab9d..f5c7514 100644
--- a/net/http/http_vary_data.cc
+++ b/net/http/http_vary_data.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2008 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.
@@ -97,6 +97,10 @@ bool HttpVaryData::MatchesRequest(
std::string HttpVaryData::GetRequestValue(
const HttpRequestInfo& request_info,
const std::string& request_header) {
+ // Some special cases:
+ if (!base::strcasecmp(request_header.c_str(), HttpRequestHeaders::kReferer))
+ return request_info.referrer.spec();
+
// Unfortunately, we do not have access to all of the request headers at this
// point. Most notably, we do not have access to an Authorization header if
// one will be added to the request.
diff --git a/net/socket/client_socket_pool_manager.cc b/net/socket/client_socket_pool_manager.cc
index f26f876..be3233a 100644
--- a/net/socket/client_socket_pool_manager.cc
+++ b/net/socket/client_socket_pool_manager.cc
@@ -59,6 +59,7 @@ static void AddSocketPoolsToList(ListValue* list,
// The meat of the implementation for the InitSocketHandleForHttpRequest,
// InitSocketHandleForRawConnect and PreconnectSocketsForHttpRequest methods.
int InitSocketPoolHelper(const GURL& request_url,
+ const GURL& request_referrer,
const HttpRequestHeaders& request_extra_headers,
int request_load_flags,
RequestPriority request_priority,
@@ -78,13 +79,6 @@ int InitSocketPoolHelper(const GURL& request_url,
scoped_refptr<SOCKSSocketParams> socks_params;
scoped_ptr<HostPortPair> proxy_host_port;
- GURL request_referrer;
- std::string request_referrer_str;
- if (request_extra_headers.GetHeader(HttpRequestHeaders::kReferer,
- &request_referrer_str)) {
- request_referrer = GURL(request_referrer_str);
- }
-
bool using_ssl = request_url.SchemeIs("https") || force_spdy_over_ssl;
HostPortPair origin_host_port =
@@ -619,6 +613,7 @@ void ClientSocketPoolManager::OnCertTrustChanged(const X509Certificate* cert) {
// static
int ClientSocketPoolManager::InitSocketHandleForHttpRequest(
const GURL& request_url,
+ const GURL& request_referrer,
const HttpRequestHeaders& request_extra_headers,
int request_load_flags,
RequestPriority request_priority,
@@ -633,6 +628,7 @@ int ClientSocketPoolManager::InitSocketHandleForHttpRequest(
CompletionCallback* callback) {
DCHECK(socket_handle);
return InitSocketPoolHelper(request_url,
+ request_referrer,
request_extra_headers,
request_load_flags,
request_priority,
@@ -662,11 +658,13 @@ int ClientSocketPoolManager::InitSocketHandleForRawConnect(
DCHECK(socket_handle);
// Synthesize an HttpRequestInfo.
GURL request_url = GURL("http://" + host_port_pair.ToString());
+ GURL request_referrer;
HttpRequestHeaders request_extra_headers;
int request_load_flags = 0;
RequestPriority request_priority = MEDIUM;
return InitSocketPoolHelper(request_url,
+ request_referrer,
request_extra_headers,
request_load_flags,
request_priority,
@@ -686,6 +684,7 @@ int ClientSocketPoolManager::InitSocketHandleForRawConnect(
// static
int ClientSocketPoolManager::PreconnectSocketsForHttpRequest(
const GURL& request_url,
+ const GURL& request_referrer,
const HttpRequestHeaders& request_extra_headers,
int request_load_flags,
RequestPriority request_priority,
@@ -698,6 +697,7 @@ int ClientSocketPoolManager::PreconnectSocketsForHttpRequest(
const BoundNetLog& net_log,
int num_preconnect_streams) {
return InitSocketPoolHelper(request_url,
+ request_referrer,
request_extra_headers,
request_load_flags,
request_priority,
diff --git a/net/socket/client_socket_pool_manager.h b/net/socket/client_socket_pool_manager.h
index 5ef70f0..9d42672 100644
--- a/net/socket/client_socket_pool_manager.h
+++ b/net/socket/client_socket_pool_manager.h
@@ -111,6 +111,7 @@ class ClientSocketPoolManager : public base::NonThreadSafe,
// uses SSL and |ssl_config_for_proxy| is used if the proxy server is HTTPS.
static int InitSocketHandleForHttpRequest(
const GURL& request_url,
+ const GURL& request_referrer,
const HttpRequestHeaders& request_extra_headers,
int request_load_flags,
RequestPriority request_priority,
@@ -142,6 +143,7 @@ class ClientSocketPoolManager : public base::NonThreadSafe,
// desired number of preconnect streams from the relevant socket pool.
static int PreconnectSocketsForHttpRequest(
const GURL& request_url,
+ const GURL& request_referrer,
const HttpRequestHeaders& request_extra_headers,
int request_load_flags,
RequestPriority request_priority,
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index fc52cb7..4872792 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -794,23 +794,12 @@ void URLRequestHttpJob::Start() {
GURL referrer(request_->GetSanitizedReferrer());
request_info_.url = request_->url();
+ request_info_.referrer = referrer;
request_info_.method = request_->method();
request_info_.load_flags = request_->load_flags();
request_info_.priority = request_->priority();
request_info_.request_id = request_->identifier();
- // Strip Referer from request_info_.extra_headers to prevent, e.g., plugins
- // from overriding headers that are controlled using other means. Otherwise a
- // plugin could set a referrer although sending the referrer is inhibited.
- request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kReferer);
-
- // Our consumer should have made sure that this is a safe referrer. See for
- // instance WebCore::FrameLoader::HideReferrer.
- if (referrer.is_valid()) {
- request_info_.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
- referrer.spec());
- }
-
if (request_->context()) {
request_info_.extra_headers.SetHeaderIfMissing(
HttpRequestHeaders::kUserAgent,
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 0aa0347..97ceb08 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -2479,50 +2479,6 @@ TEST_F(URLRequestTest, NetworkDelegateProxyError) {
EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, network_delegate.last_os_error());
}
-// Check that it is impossible to change the referrer in the extra headers of
-// an URLRequest.
-TEST_F(URLRequestTest, DoNotOverrideReferrer) {
- TestServer test_server(TestServer::TYPE_HTTP, FilePath());
- ASSERT_TRUE(test_server.Start());
-
- scoped_refptr<URLRequestContext> context(new TestURLRequestContext());
-
- // If extra headers contain referer and the request contains a referer,
- // only the latter shall be respected.
- {
- TestDelegate d;
- TestURLRequest req(test_server.GetURL("echoheader?Referer"), &d);
- req.set_referrer("http://foo.com/");
- req.set_context(context);
-
- HttpRequestHeaders headers;
- headers.SetHeader(HttpRequestHeaders::kReferer, "http://bar.com/");
- req.SetExtraRequestHeaders(headers);
-
- req.Start();
- MessageLoop::current()->Run();
-
- EXPECT_EQ("http://foo.com/", d.data_received());
- }
-
- // If extra headers contain a referer but the request does not, no referer
- // shall be sent in the header.
- {
- TestDelegate d;
- TestURLRequest req(test_server.GetURL("echoheader?Referer"), &d);
- req.set_context(context);
-
- HttpRequestHeaders headers;
- headers.SetHeader(HttpRequestHeaders::kReferer, "http://bar.com/");
- req.SetExtraRequestHeaders(headers);
-
- req.Start();
- MessageLoop::current()->Run();
-
- EXPECT_EQ("None", d.data_received());
- }
-}
-
class URLRequestTestFTP : public URLRequestTest {
public:
URLRequestTestFTP() : test_server_(TestServer::TYPE_FTP, FilePath()) {