diff options
-rw-r--r-- | net/http/http_network_transaction.cc | 22 | ||||
-rw-r--r-- | net/http/http_network_transaction_unittest.cc | 7 | ||||
-rw-r--r-- | net/http/http_request_info.h | 3 | ||||
-rw-r--r-- | net/http/http_stream_factory_impl_job.cc | 2 | ||||
-rw-r--r-- | net/http/http_vary_data.cc | 6 | ||||
-rw-r--r-- | net/socket/client_socket_pool_manager.cc | 14 | ||||
-rw-r--r-- | net/socket/client_socket_pool_manager.h | 2 | ||||
-rw-r--r-- | net/url_request/url_request_http_job.cc | 13 | ||||
-rw-r--r-- | net/url_request/url_request_unittest.cc | 44 |
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()) { |