chrome_network_delegate.cc revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/net/chrome_network_delegate.h" 6 7#include <stdlib.h> 8 9#include <vector> 10 11#include "base/base_paths.h" 12#include "base/debug/trace_event.h" 13#include "base/logging.h" 14#include "base/metrics/histogram.h" 15#include "base/path_service.h" 16#include "base/prefs/pref_member.h" 17#include "base/prefs/pref_service.h" 18#include "base/strings/string_number_conversions.h" 19#include "base/time/time.h" 20#include "chrome/browser/browser_process.h" 21#include "chrome/browser/content_settings/cookie_settings.h" 22#include "chrome/browser/content_settings/tab_specific_content_settings.h" 23#include "chrome/browser/custom_handlers/protocol_handler_registry.h" 24#include "chrome/browser/net/chrome_extensions_network_delegate.h" 25#include "chrome/browser/net/client_hints.h" 26#include "chrome/browser/net/connect_interceptor.h" 27#include "chrome/browser/net/safe_search_util.h" 28#include "chrome/browser/performance_monitor/performance_monitor.h" 29#include "chrome/browser/prerender/prerender_tracker.h" 30#include "chrome/browser/profiles/profile_manager.h" 31#include "chrome/browser/task_manager/task_manager.h" 32#include "chrome/common/pref_names.h" 33#include "components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.h" 34#include "components/data_reduction_proxy/browser/data_reduction_proxy_metrics.h" 35#include "components/data_reduction_proxy/browser/data_reduction_proxy_params.h" 36#include "components/data_reduction_proxy/browser/data_reduction_proxy_protocol.h" 37#include "components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.h" 38#include "components/domain_reliability/monitor.h" 39#include "content/public/browser/browser_thread.h" 40#include "content/public/browser/render_frame_host.h" 41#include "content/public/browser/render_view_host.h" 42#include "content/public/browser/resource_request_info.h" 43#include "net/base/host_port_pair.h" 44#include "net/base/net_errors.h" 45#include "net/base/net_log.h" 46#include "net/cookies/canonical_cookie.h" 47#include "net/cookies/cookie_options.h" 48#include "net/http/http_request_headers.h" 49#include "net/http/http_response_headers.h" 50#include "net/proxy/proxy_config.h" 51#include "net/proxy/proxy_info.h" 52#include "net/proxy/proxy_retry_info.h" 53#include "net/proxy/proxy_server.h" 54#include "net/socket_stream/socket_stream.h" 55#include "net/url_request/url_request.h" 56#include "net/url_request/url_request_context.h" 57 58#if defined(OS_ANDROID) 59#include "chrome/browser/io_thread.h" 60#include "components/precache/content/precache_manager.h" 61#include "components/precache/content/precache_manager_factory.h" 62#endif 63 64#if defined(OS_CHROMEOS) 65#include "base/command_line.h" 66#include "base/sys_info.h" 67#include "chrome/common/chrome_switches.h" 68#endif 69 70#if defined(ENABLE_CONFIGURATION_POLICY) 71#include "components/policy/core/browser/url_blacklist_manager.h" 72#endif 73 74#if defined(ENABLE_EXTENSIONS) 75#include "extensions/common/constants.h" 76#endif 77 78using content::BrowserThread; 79using content::RenderViewHost; 80using content::ResourceRequestInfo; 81using content::ResourceType; 82 83// By default we don't allow access to all file:// urls on ChromeOS and 84// Android. 85#if defined(OS_CHROMEOS) || defined(OS_ANDROID) 86bool ChromeNetworkDelegate::g_allow_file_access_ = false; 87#else 88bool ChromeNetworkDelegate::g_allow_file_access_ = true; 89#endif 90 91#if defined(ENABLE_EXTENSIONS) 92// This remains false unless the --disable-extensions-http-throttling 93// flag is passed to the browser. 94bool ChromeNetworkDelegate::g_never_throttle_requests_ = false; 95#endif 96 97namespace { 98 99const char kDNTHeader[] = "DNT"; 100 101// Gets called when the extensions finish work on the URL. If the extensions 102// did not do a redirect (so |new_url| is empty) then we enforce the 103// SafeSearch parameters. Otherwise we will get called again after the 104// redirect and we enforce SafeSearch then. 105void ForceGoogleSafeSearchCallbackWrapper( 106 const net::CompletionCallback& callback, 107 net::URLRequest* request, 108 GURL* new_url, 109 int rv) { 110 if (rv == net::OK && new_url->is_empty()) 111 safe_search_util::ForceGoogleSafeSearch(request, new_url); 112 callback.Run(rv); 113} 114 115void UpdateContentLengthPrefs( 116 int received_content_length, 117 int original_content_length, 118 data_reduction_proxy::DataReductionProxyRequestType request_type, 119 Profile* profile) { 120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 121 DCHECK_GE(received_content_length, 0); 122 DCHECK_GE(original_content_length, 0); 123 124 // Can be NULL in a unit test. 125 if (!g_browser_process) 126 return; 127 128 PrefService* prefs = g_browser_process->local_state(); 129 if (!prefs) 130 return; 131 132 // Ignore off-the-record data. 133 if (!g_browser_process->profile_manager()->IsValidProfile(profile) || 134 profile->IsOffTheRecord()) { 135 return; 136 } 137#if defined(OS_ANDROID) && defined(SPDY_PROXY_AUTH_ORIGIN) 138 // If Android ever goes multi profile, the profile should be passed so that 139 // the browser preference will be taken. 140 bool with_data_reduction_proxy_enabled = 141 ProfileManager::GetActiveUserProfile()->GetPrefs()->GetBoolean( 142 data_reduction_proxy::prefs::kDataReductionProxyEnabled); 143#else 144 bool with_data_reduction_proxy_enabled = false; 145#endif 146 147 data_reduction_proxy::UpdateContentLengthPrefs(received_content_length, 148 original_content_length, 149 with_data_reduction_proxy_enabled, 150 request_type, prefs); 151} 152 153void StoreAccumulatedContentLength( 154 int received_content_length, 155 int original_content_length, 156 data_reduction_proxy::DataReductionProxyRequestType request_type, 157 Profile* profile) { 158 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 159 base::Bind(&UpdateContentLengthPrefs, 160 received_content_length, original_content_length, 161 request_type, profile)); 162} 163 164void RecordContentLengthHistograms( 165 int64 received_content_length, 166 int64 original_content_length, 167 const base::TimeDelta& freshness_lifetime) { 168 // Add the current resource to these histograms only when a valid 169 // X-Original-Content-Length header is present. 170 if (original_content_length >= 0) { 171 UMA_HISTOGRAM_COUNTS("Net.HttpContentLengthWithValidOCL", 172 received_content_length); 173 UMA_HISTOGRAM_COUNTS("Net.HttpOriginalContentLengthWithValidOCL", 174 original_content_length); 175 UMA_HISTOGRAM_COUNTS("Net.HttpContentLengthDifferenceWithValidOCL", 176 original_content_length - received_content_length); 177 } else { 178 // Presume the original content length is the same as the received content 179 // length if the X-Original-Content-Header is not present. 180 original_content_length = received_content_length; 181 } 182 UMA_HISTOGRAM_COUNTS("Net.HttpContentLength", received_content_length); 183 UMA_HISTOGRAM_COUNTS("Net.HttpOriginalContentLength", 184 original_content_length); 185 UMA_HISTOGRAM_COUNTS("Net.HttpContentLengthDifference", 186 original_content_length - received_content_length); 187 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.HttpContentFreshnessLifetime", 188 freshness_lifetime.InSeconds(), 189 base::TimeDelta::FromHours(1).InSeconds(), 190 base::TimeDelta::FromDays(30).InSeconds(), 191 100); 192 if (freshness_lifetime.InSeconds() <= 0) 193 return; 194 UMA_HISTOGRAM_COUNTS("Net.HttpContentLengthCacheable", 195 received_content_length); 196 if (freshness_lifetime.InHours() < 4) 197 return; 198 UMA_HISTOGRAM_COUNTS("Net.HttpContentLengthCacheable4Hours", 199 received_content_length); 200 201 if (freshness_lifetime.InHours() < 24) 202 return; 203 UMA_HISTOGRAM_COUNTS("Net.HttpContentLengthCacheable24Hours", 204 received_content_length); 205} 206 207#if defined(OS_ANDROID) 208void RecordPrecacheStatsOnUIThread(const GURL& url, 209 const base::Time& fetch_time, int64 size, 210 bool was_cached, void* profile_id) { 211 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 212 213 Profile* profile = reinterpret_cast<Profile*>(profile_id); 214 if (!g_browser_process->profile_manager()->IsValidProfile(profile)) { 215 return; 216 } 217 218 precache::PrecacheManager* precache_manager = 219 precache::PrecacheManagerFactory::GetForBrowserContext(profile); 220 if (!precache_manager) { 221 // This could be NULL if the profile is off the record. 222 return; 223 } 224 225 precache_manager->RecordStatsForFetch(url, fetch_time, size, was_cached); 226} 227 228void RecordIOThreadToRequestStartOnUIThread( 229 const base::TimeTicks& request_start) { 230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 231 base::TimeDelta request_lag = request_start - 232 g_browser_process->io_thread()->creation_time(); 233 UMA_HISTOGRAM_TIMES("Net.IOThreadCreationToHTTPRequestStart", request_lag); 234} 235#endif // defined(OS_ANDROID) 236 237} // namespace 238 239ChromeNetworkDelegate::ChromeNetworkDelegate( 240 extensions::EventRouterForwarder* event_router, 241 BooleanPrefMember* enable_referrers) 242 : profile_(NULL), 243 enable_referrers_(enable_referrers), 244 enable_do_not_track_(NULL), 245 force_google_safe_search_(NULL), 246 data_reduction_proxy_enabled_(NULL), 247#if defined(ENABLE_CONFIGURATION_POLICY) 248 url_blacklist_manager_(NULL), 249#endif 250 domain_reliability_monitor_(NULL), 251 received_content_length_(0), 252 original_content_length_(0), 253 first_request_(true), 254 prerender_tracker_(NULL), 255 data_reduction_proxy_params_(NULL), 256 data_reduction_proxy_usage_stats_(NULL), 257 data_reduction_proxy_auth_request_handler_(NULL) { 258 DCHECK(enable_referrers); 259 extensions_delegate_.reset( 260 ChromeExtensionsNetworkDelegate::Create(event_router)); 261} 262 263ChromeNetworkDelegate::~ChromeNetworkDelegate() {} 264 265void ChromeNetworkDelegate::set_extension_info_map( 266 extensions::InfoMap* extension_info_map) { 267 extensions_delegate_->set_extension_info_map(extension_info_map); 268} 269 270void ChromeNetworkDelegate::set_profile(void* profile) { 271 profile_ = profile; 272 extensions_delegate_->set_profile(profile); 273} 274 275void ChromeNetworkDelegate::set_cookie_settings( 276 CookieSettings* cookie_settings) { 277 cookie_settings_ = cookie_settings; 278} 279 280void ChromeNetworkDelegate::set_predictor( 281 chrome_browser_net::Predictor* predictor) { 282 connect_interceptor_.reset( 283 new chrome_browser_net::ConnectInterceptor(predictor)); 284} 285 286void ChromeNetworkDelegate::SetEnableClientHints() { 287 client_hints_.reset(new ClientHints()); 288 client_hints_->Init(); 289} 290 291// static 292#if defined(ENABLE_EXTENSIONS) 293void ChromeNetworkDelegate::NeverThrottleRequests() { 294 g_never_throttle_requests_ = true; 295} 296#endif 297 298// static 299void ChromeNetworkDelegate::InitializePrefsOnUIThread( 300 BooleanPrefMember* enable_referrers, 301 BooleanPrefMember* enable_do_not_track, 302 BooleanPrefMember* force_google_safe_search, 303 PrefService* pref_service) { 304 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 305 enable_referrers->Init(prefs::kEnableReferrers, pref_service); 306 enable_referrers->MoveToThread( 307 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)); 308 if (enable_do_not_track) { 309 enable_do_not_track->Init(prefs::kEnableDoNotTrack, pref_service); 310 enable_do_not_track->MoveToThread( 311 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)); 312 } 313 if (force_google_safe_search) { 314 force_google_safe_search->Init(prefs::kForceSafeSearch, pref_service); 315 force_google_safe_search->MoveToThread( 316 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)); 317 } 318} 319 320// static 321void ChromeNetworkDelegate::AllowAccessToAllFiles() { 322 g_allow_file_access_ = true; 323} 324 325// static 326base::Value* ChromeNetworkDelegate::HistoricNetworkStatsInfoToValue() { 327 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 328 PrefService* prefs = g_browser_process->local_state(); 329 int64 total_received = prefs->GetInt64( 330 data_reduction_proxy::prefs::kHttpReceivedContentLength); 331 int64 total_original = prefs->GetInt64( 332 data_reduction_proxy::prefs::kHttpOriginalContentLength); 333 334 base::DictionaryValue* dict = new base::DictionaryValue(); 335 // Use strings to avoid overflow. base::Value only supports 32-bit integers. 336 dict->SetString("historic_received_content_length", 337 base::Int64ToString(total_received)); 338 dict->SetString("historic_original_content_length", 339 base::Int64ToString(total_original)); 340 return dict; 341} 342 343base::Value* ChromeNetworkDelegate::SessionNetworkStatsInfoToValue() const { 344 base::DictionaryValue* dict = new base::DictionaryValue(); 345 // Use strings to avoid overflow. base::Value only supports 32-bit integers. 346 dict->SetString("session_received_content_length", 347 base::Int64ToString(received_content_length_)); 348 dict->SetString("session_original_content_length", 349 base::Int64ToString(original_content_length_)); 350 return dict; 351} 352 353int ChromeNetworkDelegate::OnBeforeURLRequest( 354 net::URLRequest* request, 355 const net::CompletionCallback& callback, 356 GURL* new_url) { 357#if defined(OS_ANDROID) 358 // This UMA tracks the time to the first user-initiated request start, so 359 // only non-null profiles are considered. 360 if (first_request_ && profile_) { 361 bool record_timing = true; 362 if (data_reduction_proxy_params_) { 363 record_timing = 364 (request->url() != data_reduction_proxy_params_->probe_url()) && 365 (request->url() != data_reduction_proxy_params_->warmup_url()); 366 } 367 if (record_timing) { 368 first_request_ = false; 369 net::LoadTimingInfo timing_info; 370 request->GetLoadTimingInfo(&timing_info); 371 BrowserThread::PostTask( 372 BrowserThread::UI, FROM_HERE, 373 base::Bind(&RecordIOThreadToRequestStartOnUIThread, 374 timing_info.request_start)); 375 } 376 } 377#endif // defined(OS_ANDROID) 378 379#if defined(ENABLE_CONFIGURATION_POLICY) 380 // TODO(joaodasilva): This prevents extensions from seeing URLs that are 381 // blocked. However, an extension might redirect the request to another URL, 382 // which is not blocked. 383 int error = net::ERR_BLOCKED_BY_ADMINISTRATOR; 384 if (url_blacklist_manager_ && 385 url_blacklist_manager_->IsRequestBlocked(*request, &error)) { 386 // URL access blocked by policy. 387 request->net_log().AddEvent( 388 net::NetLog::TYPE_CHROME_POLICY_ABORTED_REQUEST, 389 net::NetLog::StringCallback("url", 390 &request->url().possibly_invalid_spec())); 391 return error; 392 } 393#endif 394 395 extensions_delegate_->ForwardStartRequestStatus(request); 396 397 if (!enable_referrers_->GetValue()) 398 request->SetReferrer(std::string()); 399 if (enable_do_not_track_ && enable_do_not_track_->GetValue()) 400 request->SetExtraRequestHeaderByName(kDNTHeader, "1", true /* override */); 401 402 if (client_hints_) { 403 request->SetExtraRequestHeaderByName( 404 ClientHints::kDevicePixelRatioHeader, 405 client_hints_->GetDevicePixelRatioHeader(), true); 406 } 407 408 bool force_safe_search = force_google_safe_search_ && 409 force_google_safe_search_->GetValue(); 410 411 net::CompletionCallback wrapped_callback = callback; 412 if (force_safe_search) { 413 wrapped_callback = base::Bind(&ForceGoogleSafeSearchCallbackWrapper, 414 callback, 415 base::Unretained(request), 416 base::Unretained(new_url)); 417 } 418 419 int rv = extensions_delegate_->OnBeforeURLRequest( 420 request, wrapped_callback, new_url); 421 422 if (force_safe_search && rv == net::OK && new_url->is_empty()) 423 safe_search_util::ForceGoogleSafeSearch(request, new_url); 424 425 if (connect_interceptor_) 426 connect_interceptor_->WitnessURLRequest(request); 427 428 return rv; 429} 430 431void ChromeNetworkDelegate::OnResolveProxy( 432 const GURL& url, 433 int load_flags, 434 const net::ProxyService& proxy_service, 435 net::ProxyInfo* result) { 436 if (!on_resolve_proxy_handler_.is_null() && 437 !proxy_config_getter_.is_null()) { 438 on_resolve_proxy_handler_.Run(url, load_flags, 439 proxy_config_getter_.Run(), 440 proxy_service.proxy_retry_info(), 441 data_reduction_proxy_params_, result); 442 } 443} 444 445void ChromeNetworkDelegate::OnProxyFallback(const net::ProxyServer& bad_proxy, 446 int net_error) { 447 if (data_reduction_proxy_usage_stats_) { 448 data_reduction_proxy_usage_stats_->RecordBypassEventHistograms( 449 bad_proxy, net_error); 450 } 451} 452 453int ChromeNetworkDelegate::OnBeforeSendHeaders( 454 net::URLRequest* request, 455 const net::CompletionCallback& callback, 456 net::HttpRequestHeaders* headers) { 457 bool force_safe_search = force_google_safe_search_ && 458 force_google_safe_search_->GetValue(); 459 if (force_safe_search) 460 safe_search_util::ForceYouTubeSafetyMode(request, headers); 461 462 TRACE_EVENT_ASYNC_STEP_PAST0("net", "URLRequest", request, "SendRequest"); 463 return extensions_delegate_->OnBeforeSendHeaders(request, callback, headers); 464} 465 466void ChromeNetworkDelegate::OnBeforeSendProxyHeaders( 467 net::URLRequest* request, 468 const net::ProxyInfo& proxy_info, 469 net::HttpRequestHeaders* headers) { 470 if (data_reduction_proxy_auth_request_handler_) { 471 data_reduction_proxy_auth_request_handler_->MaybeAddRequestHeader( 472 request, proxy_info.proxy_server(), headers); 473 } 474} 475 476void ChromeNetworkDelegate::OnSendHeaders( 477 net::URLRequest* request, 478 const net::HttpRequestHeaders& headers) { 479 extensions_delegate_->OnSendHeaders(request, headers); 480} 481 482int ChromeNetworkDelegate::OnHeadersReceived( 483 net::URLRequest* request, 484 const net::CompletionCallback& callback, 485 const net::HttpResponseHeaders* original_response_headers, 486 scoped_refptr<net::HttpResponseHeaders>* override_response_headers, 487 GURL* allowed_unsafe_redirect_url) { 488 data_reduction_proxy::DataReductionProxyBypassType bypass_type; 489 if (data_reduction_proxy::MaybeBypassProxyAndPrepareToRetry( 490 data_reduction_proxy_params_, 491 request, 492 original_response_headers, 493 override_response_headers, 494 &bypass_type)) { 495 if (data_reduction_proxy_usage_stats_) 496 data_reduction_proxy_usage_stats_->SetBypassType(bypass_type); 497 return net::OK; 498 } 499 500 return extensions_delegate_->OnHeadersReceived( 501 request, 502 callback, 503 original_response_headers, 504 override_response_headers, 505 allowed_unsafe_redirect_url); 506} 507 508void ChromeNetworkDelegate::OnBeforeRedirect(net::URLRequest* request, 509 const GURL& new_location) { 510 if (domain_reliability_monitor_) 511 domain_reliability_monitor_->OnBeforeRedirect(request); 512 extensions_delegate_->OnBeforeRedirect(request, new_location); 513} 514 515 516void ChromeNetworkDelegate::OnResponseStarted(net::URLRequest* request) { 517 TRACE_EVENT_ASYNC_STEP_PAST0("net", "URLRequest", request, "ResponseStarted"); 518 extensions_delegate_->OnResponseStarted(request); 519} 520 521void ChromeNetworkDelegate::OnRawBytesRead(const net::URLRequest& request, 522 int bytes_read) { 523 TRACE_EVENT_ASYNC_STEP_PAST1("net", "URLRequest", &request, "DidRead", 524 "bytes_read", bytes_read); 525 performance_monitor::PerformanceMonitor::GetInstance()->BytesReadOnIOThread( 526 request, bytes_read); 527 528#if defined(ENABLE_TASK_MANAGER) 529 // This is not completely accurate, but as a first approximation ignore 530 // requests that are served from the cache. See bug 330931 for more info. 531 if (!request.was_cached()) 532 TaskManager::GetInstance()->model()->NotifyBytesRead(request, bytes_read); 533#endif // defined(ENABLE_TASK_MANAGER) 534} 535 536void ChromeNetworkDelegate::OnCompleted(net::URLRequest* request, 537 bool started) { 538 if (data_reduction_proxy_usage_stats_) 539 data_reduction_proxy_usage_stats_->OnUrlRequestCompleted(request, started); 540 541 TRACE_EVENT_ASYNC_END0("net", "URLRequest", request); 542 if (request->status().status() == net::URLRequestStatus::SUCCESS) { 543 // For better accuracy, we use the actual bytes read instead of the length 544 // specified with the Content-Length header, which may be inaccurate, 545 // or missing, as is the case with chunked encoding. 546 int64 received_content_length = request->received_response_content_length(); 547 548#if defined(OS_ANDROID) 549 if (precache::PrecacheManager::IsPrecachingEnabled()) { 550 // Record precache metrics when a fetch is completed successfully, if 551 // precaching is enabled. 552 BrowserThread::PostTask( 553 BrowserThread::UI, FROM_HERE, 554 base::Bind(&RecordPrecacheStatsOnUIThread, request->url(), 555 base::Time::Now(), received_content_length, 556 request->was_cached(), profile_)); 557 } 558#endif // defined(OS_ANDROID) 559 560 // Only record for http or https urls. 561 bool is_http = request->url().SchemeIs("http"); 562 bool is_https = request->url().SchemeIs("https"); 563 564 if (!request->was_cached() && // Don't record cached content 565 received_content_length && // Zero-byte responses aren't useful. 566 (is_http || is_https)) { // Only record for HTTP or HTTPS urls. 567 int64 original_content_length = 568 request->response_info().headers->GetInt64HeaderValue( 569 "x-original-content-length"); 570 data_reduction_proxy::DataReductionProxyRequestType request_type = 571 data_reduction_proxy::GetDataReductionProxyRequestType(request); 572 573 base::TimeDelta freshness_lifetime = 574 request->response_info().headers->GetFreshnessLifetime( 575 request->response_info().response_time); 576 int64 adjusted_original_content_length = 577 data_reduction_proxy::GetAdjustedOriginalContentLength( 578 request_type, original_content_length, 579 received_content_length); 580 AccumulateContentLength(received_content_length, 581 adjusted_original_content_length, 582 request_type); 583 RecordContentLengthHistograms(received_content_length, 584 original_content_length, 585 freshness_lifetime); 586 if (data_reduction_proxy_enabled_ && data_reduction_proxy_usage_stats_) { 587 data_reduction_proxy_usage_stats_->RecordBypassedBytesHistograms( 588 *request, *data_reduction_proxy_enabled_); 589 } 590 DVLOG(2) << __FUNCTION__ 591 << " received content length: " << received_content_length 592 << " original content length: " << original_content_length 593 << " url: " << request->url(); 594 } 595 596 extensions_delegate_->OnCompleted(request, started); 597 } else if (request->status().status() == net::URLRequestStatus::FAILED || 598 request->status().status() == net::URLRequestStatus::CANCELED) { 599 extensions_delegate_->OnCompleted(request, started); 600 } else { 601 NOTREACHED(); 602 } 603 if (domain_reliability_monitor_) 604 domain_reliability_monitor_->OnCompleted(request, started); 605 extensions_delegate_->ForwardProxyErrors(request); 606 extensions_delegate_->ForwardDoneRequestStatus(request); 607} 608 609void ChromeNetworkDelegate::OnURLRequestDestroyed(net::URLRequest* request) { 610 extensions_delegate_->OnURLRequestDestroyed(request); 611} 612 613void ChromeNetworkDelegate::OnPACScriptError(int line_number, 614 const base::string16& error) { 615 extensions_delegate_->OnPACScriptError(line_number, error); 616} 617 618net::NetworkDelegate::AuthRequiredResponse 619ChromeNetworkDelegate::OnAuthRequired( 620 net::URLRequest* request, 621 const net::AuthChallengeInfo& auth_info, 622 const AuthCallback& callback, 623 net::AuthCredentials* credentials) { 624 return extensions_delegate_->OnAuthRequired( 625 request, auth_info, callback, credentials); 626} 627 628bool ChromeNetworkDelegate::OnCanGetCookies( 629 const net::URLRequest& request, 630 const net::CookieList& cookie_list) { 631 // NULL during tests, or when we're running in the system context. 632 if (!cookie_settings_.get()) 633 return true; 634 635 bool allow = cookie_settings_->IsReadingCookieAllowed( 636 request.url(), request.first_party_for_cookies()); 637 638 int render_process_id = -1; 639 int render_frame_id = -1; 640 641 // |is_for_blocking_resource| indicates whether the cookies read were for a 642 // blocking resource (eg script, css). It is only temporarily added for 643 // diagnostic purposes, per bug 353678. Will be removed again once data 644 // collection is finished. 645 bool is_for_blocking_resource = false; 646 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(&request); 647 if (info && ((!info->IsAsync()) || 648 info->GetResourceType() == content::RESOURCE_TYPE_STYLESHEET || 649 info->GetResourceType() == content::RESOURCE_TYPE_SCRIPT)) { 650 is_for_blocking_resource = true; 651 } 652 653 if (content::ResourceRequestInfo::GetRenderFrameForRequest( 654 &request, &render_process_id, &render_frame_id)) { 655 BrowserThread::PostTask( 656 BrowserThread::UI, FROM_HERE, 657 base::Bind(&TabSpecificContentSettings::CookiesRead, 658 render_process_id, render_frame_id, 659 request.url(), request.first_party_for_cookies(), 660 cookie_list, !allow, is_for_blocking_resource)); 661 } 662 663 return allow; 664} 665 666bool ChromeNetworkDelegate::OnCanSetCookie(const net::URLRequest& request, 667 const std::string& cookie_line, 668 net::CookieOptions* options) { 669 // NULL during tests, or when we're running in the system context. 670 if (!cookie_settings_.get()) 671 return true; 672 673 bool allow = cookie_settings_->IsSettingCookieAllowed( 674 request.url(), request.first_party_for_cookies()); 675 676 int render_process_id = -1; 677 int render_frame_id = -1; 678 if (content::ResourceRequestInfo::GetRenderFrameForRequest( 679 &request, &render_process_id, &render_frame_id)) { 680 BrowserThread::PostTask( 681 BrowserThread::UI, FROM_HERE, 682 base::Bind(&TabSpecificContentSettings::CookieChanged, 683 render_process_id, render_frame_id, 684 request.url(), request.first_party_for_cookies(), 685 cookie_line, *options, !allow)); 686 } 687 688 if (prerender_tracker_) { 689 prerender_tracker_->OnCookieChangedForURL( 690 render_process_id, 691 request.context()->cookie_store()->GetCookieMonster(), 692 request.url()); 693 } 694 695 return allow; 696} 697 698bool ChromeNetworkDelegate::OnCanAccessFile(const net::URLRequest& request, 699 const base::FilePath& path) const { 700 if (g_allow_file_access_) 701 return true; 702 703#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) 704 return true; 705#else 706#if defined(OS_CHROMEOS) 707 // If we're running Chrome for ChromeOS on Linux, we want to allow file 708 // access. 709 if (!base::SysInfo::IsRunningOnChromeOS() || 710 CommandLine::ForCurrentProcess()->HasSwitch(switches::kTestType)) { 711 return true; 712 } 713 714 // Use a whitelist to only allow access to files residing in the list of 715 // directories below. 716 static const char* const kLocalAccessWhiteList[] = { 717 "/home/chronos/user/Downloads", 718 "/home/chronos/user/log", 719 "/home/chronos/user/WebRTC Logs", 720 "/media", 721 "/opt/oem", 722 "/usr/share/chromeos-assets", 723 "/tmp", 724 "/var/log", 725 }; 726 727 // The actual location of "/home/chronos/user/Xyz" is the Xyz directory under 728 // the profile path ("/home/chronos/user' is a hard link to current primary 729 // logged in profile.) For the support of multi-profile sessions, we are 730 // switching to use explicit "$PROFILE_PATH/Xyz" path and here whitelist such 731 // access. 732 if (!profile_path_.empty()) { 733 const base::FilePath downloads = profile_path_.AppendASCII("Downloads"); 734 if (downloads == path.StripTrailingSeparators() || downloads.IsParent(path)) 735 return true; 736 const base::FilePath webrtc_logs = profile_path_.AppendASCII("WebRTC Logs"); 737 if (webrtc_logs == path.StripTrailingSeparators() || 738 webrtc_logs.IsParent(path)) { 739 return true; 740 } 741 } 742#elif defined(OS_ANDROID) 743 // Access to files in external storage is allowed. 744 base::FilePath external_storage_path; 745 PathService::Get(base::DIR_ANDROID_EXTERNAL_STORAGE, &external_storage_path); 746 if (external_storage_path.IsParent(path)) 747 return true; 748 749 // Whitelist of other allowed directories. 750 static const char* const kLocalAccessWhiteList[] = { 751 "/sdcard", 752 "/mnt/sdcard", 753 }; 754#endif 755 756 for (size_t i = 0; i < arraysize(kLocalAccessWhiteList); ++i) { 757 const base::FilePath white_listed_path(kLocalAccessWhiteList[i]); 758 // base::FilePath::operator== should probably handle trailing separators. 759 if (white_listed_path == path.StripTrailingSeparators() || 760 white_listed_path.IsParent(path)) { 761 return true; 762 } 763 } 764 765 DVLOG(1) << "File access denied - " << path.value().c_str(); 766 return false; 767#endif // !defined(OS_CHROMEOS) && !defined(OS_ANDROID) 768} 769 770bool ChromeNetworkDelegate::OnCanThrottleRequest( 771 const net::URLRequest& request) const { 772#if defined(ENABLE_EXTENSIONS) 773 if (g_never_throttle_requests_) 774 return false; 775 return request.first_party_for_cookies().scheme() == 776 extensions::kExtensionScheme; 777#else 778 return false; 779#endif 780} 781 782bool ChromeNetworkDelegate::OnCanEnablePrivacyMode( 783 const GURL& url, 784 const GURL& first_party_for_cookies) const { 785 // NULL during tests, or when we're running in the system context. 786 if (!cookie_settings_.get()) 787 return false; 788 789 bool reading_cookie_allowed = cookie_settings_->IsReadingCookieAllowed( 790 url, first_party_for_cookies); 791 bool setting_cookie_allowed = cookie_settings_->IsSettingCookieAllowed( 792 url, first_party_for_cookies); 793 bool privacy_mode = !(reading_cookie_allowed && setting_cookie_allowed); 794 return privacy_mode; 795} 796 797int ChromeNetworkDelegate::OnBeforeSocketStreamConnect( 798 net::SocketStream* socket, 799 const net::CompletionCallback& callback) { 800#if defined(ENABLE_CONFIGURATION_POLICY) 801 if (url_blacklist_manager_ && 802 url_blacklist_manager_->IsURLBlocked(socket->url())) { 803 // URL access blocked by policy. 804 socket->net_log()->AddEvent( 805 net::NetLog::TYPE_CHROME_POLICY_ABORTED_REQUEST, 806 net::NetLog::StringCallback("url", 807 &socket->url().possibly_invalid_spec())); 808 return net::ERR_BLOCKED_BY_ADMINISTRATOR; 809 } 810#endif 811 return net::OK; 812} 813 814void ChromeNetworkDelegate::AccumulateContentLength( 815 int64 received_content_length, 816 int64 original_content_length, 817 data_reduction_proxy::DataReductionProxyRequestType request_type) { 818 DCHECK_GE(received_content_length, 0); 819 DCHECK_GE(original_content_length, 0); 820 StoreAccumulatedContentLength(received_content_length, 821 original_content_length, 822 request_type, 823 reinterpret_cast<Profile*>(profile_)); 824 received_content_length_ += received_content_length; 825 original_content_length_ += original_content_length; 826} 827