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