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, 70 insertions, 43 deletions
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 8b06a3b..d7a65e2 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -695,13 +695,6 @@ 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()) { @@ -736,20 +729,7 @@ void HttpNetworkTransaction::BuildRequestHeaders(bool using_proxy) { auth_controllers_[HttpAuth::AUTH_SERVER]->AddAuthorizationHeader( &request_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); + request_headers_.MergeFrom(request_->extra_headers); } int HttpNetworkTransaction::DoBuildRequest() { diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 45b3d79..65d699e 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -4910,7 +4910,8 @@ TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) { request.method = "GET"; request.url = GURL("http://www.google.com/"); request.load_flags = 0; - request.referrer = GURL("http://the.previous.site.com/"); + request.extra_headers.SetHeader(HttpRequestHeaders::kReferer, + "http://the.previous.site.com/"); SessionDependencies session_deps; scoped_ptr<HttpTransaction> trans( @@ -5187,6 +5188,7 @@ 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"), }; @@ -5757,8 +5759,9 @@ 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 96c47c0..c368685 100644 --- a/net/http/http_request_info.h +++ b/net/http/http_request_info.h @@ -33,9 +33,6 @@ 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 a155609..52dfa9f 100644 --- a/net/http/http_stream_factory_impl_job.cc +++ b/net/http/http_stream_factory_impl_job.cc @@ -606,7 +606,6 @@ 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, @@ -621,7 +620,6 @@ 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 f5c7514..09aab9d 100644 --- a/net/http/http_vary_data.cc +++ b/net/http/http_vary_data.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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,10 +97,6 @@ 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 be3233a..f26f876 100644 --- a/net/socket/client_socket_pool_manager.cc +++ b/net/socket/client_socket_pool_manager.cc @@ -59,7 +59,6 @@ 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, @@ -79,6 +78,13 @@ 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 = @@ -613,7 +619,6 @@ 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, @@ -628,7 +633,6 @@ int ClientSocketPoolManager::InitSocketHandleForHttpRequest( CompletionCallback* callback) { DCHECK(socket_handle); return InitSocketPoolHelper(request_url, - request_referrer, request_extra_headers, request_load_flags, request_priority, @@ -658,13 +662,11 @@ 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, @@ -684,7 +686,6 @@ 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, @@ -697,7 +698,6 @@ 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 9d42672..5ef70f0 100644 --- a/net/socket/client_socket_pool_manager.h +++ b/net/socket/client_socket_pool_manager.h @@ -111,7 +111,6 @@ 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, @@ -143,7 +142,6 @@ 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 4872792..fc52cb7 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc @@ -794,12 +794,23 @@ 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 97ceb08..0aa0347 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc @@ -2479,6 +2479,50 @@ 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()) { |