ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / net / chrome_network_delegate.cc
blob68a4a74f3444ddd64aa7eb770c8e8df690852334
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.
5 #include "chrome/browser/net/chrome_network_delegate.h"
7 #include <stdlib.h>
9 #include <vector>
11 #include "base/base_paths.h"
12 #include "base/command_line.h"
13 #include "base/debug/alias.h"
14 #include "base/debug/dump_without_crashing.h"
15 #include "base/debug/stack_trace.h"
16 #include "base/logging.h"
17 #include "base/metrics/histogram.h"
18 #include "base/metrics/sparse_histogram.h"
19 #include "base/metrics/user_metrics.h"
20 #include "base/path_service.h"
21 #include "base/prefs/pref_member.h"
22 #include "base/prefs/pref_service.h"
23 #include "base/profiler/scoped_tracker.h"
24 #include "base/strings/string_number_conversions.h"
25 #include "base/strings/string_util.h"
26 #include "base/time/time.h"
27 #include "chrome/browser/browser_process.h"
28 #include "chrome/browser/content_settings/cookie_settings.h"
29 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
30 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
31 #include "chrome/browser/net/chrome_extensions_network_delegate.h"
32 #include "chrome/browser/net/connect_interceptor.h"
33 #include "chrome/browser/net/safe_search_util.h"
34 #include "chrome/browser/prerender/prerender_tracker.h"
35 #include "chrome/browser/profiles/profile_manager.h"
36 #include "chrome/browser/task_manager/task_manager.h"
37 #include "chrome/common/pref_names.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 "content/public/common/content_switches.h"
44 #include "content/public/common/process_type.h"
45 #include "net/base/host_port_pair.h"
46 #include "net/base/load_flags.h"
47 #include "net/base/net_errors.h"
48 #include "net/base/net_log.h"
49 #include "net/cookies/canonical_cookie.h"
50 #include "net/cookies/cookie_options.h"
51 #include "net/http/http_request_headers.h"
52 #include "net/http/http_response_headers.h"
53 #include "net/http/http_status_code.h"
54 #include "net/url_request/url_request.h"
55 #include "net/url_request/url_request_context.h"
57 #if defined(OS_ANDROID)
58 #include "chrome/browser/io_thread.h"
59 #include "components/precache/content/precache_manager.h"
60 #include "components/precache/content/precache_manager_factory.h"
61 #endif
63 #if defined(OS_CHROMEOS)
64 #include "base/sys_info.h"
65 #include "chrome/common/chrome_switches.h"
66 #endif
68 #if defined(ENABLE_CONFIGURATION_POLICY)
69 #include "components/policy/core/browser/url_blacklist_manager.h"
70 #endif
72 #if defined(ENABLE_EXTENSIONS)
73 #include "extensions/common/constants.h"
74 #endif
76 using content::BrowserThread;
77 using content::RenderViewHost;
78 using content::ResourceRequestInfo;
79 using content::ResourceType;
81 // By default we don't allow access to all file:// urls on ChromeOS and
82 // Android.
83 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
84 bool ChromeNetworkDelegate::g_allow_file_access_ = false;
85 #else
86 bool ChromeNetworkDelegate::g_allow_file_access_ = true;
87 #endif
89 #if defined(ENABLE_EXTENSIONS)
90 // This remains false unless the --disable-extensions-http-throttling
91 // flag is passed to the browser.
92 bool ChromeNetworkDelegate::g_never_throttle_requests_ = false;
93 #endif
95 namespace {
97 const char kDNTHeader[] = "DNT";
99 // Gets called when the extensions finish work on the URL. If the extensions
100 // did not do a redirect (so |new_url| is empty) then we enforce the
101 // SafeSearch parameters. Otherwise we will get called again after the
102 // redirect and we enforce SafeSearch then.
103 void ForceGoogleSafeSearchCallbackWrapper(
104 const net::CompletionCallback& callback,
105 net::URLRequest* request,
106 GURL* new_url,
107 int rv) {
108 if (rv == net::OK && new_url->is_empty())
109 safe_search_util::ForceGoogleSafeSearch(request, new_url);
110 callback.Run(rv);
113 #if defined(OS_ANDROID)
114 void RecordPrecacheStatsOnUIThread(const GURL& url,
115 const base::Time& fetch_time, int64 size,
116 bool was_cached, void* profile_id) {
117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
119 Profile* profile = reinterpret_cast<Profile*>(profile_id);
120 if (!g_browser_process->profile_manager()->IsValidProfile(profile)) {
121 return;
124 precache::PrecacheManager* precache_manager =
125 precache::PrecacheManagerFactory::GetForBrowserContext(profile);
126 if (!precache_manager || !precache_manager->IsPrecachingAllowed()) {
127 // |precache_manager| could be NULL if the profile is off the record.
128 return;
131 precache_manager->RecordStatsForFetch(url, fetch_time, size, was_cached);
133 #endif // defined(OS_ANDROID)
135 void ReportInvalidReferrerSendOnUI() {
136 base::RecordAction(
137 base::UserMetricsAction("Net.URLRequest_StartJob_InvalidReferrer"));
140 void ReportInvalidReferrerSend(const GURL& target_url,
141 const GURL& referrer_url) {
142 // Record information to help debug http://crbug.com/422871
143 if (!target_url.SchemeIsHTTPOrHTTPS())
144 return;
145 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
146 base::Bind(&ReportInvalidReferrerSendOnUI));
147 base::debug::DumpWithoutCrashing();
148 NOTREACHED() << "Sending request to " << target_url
149 << " with invalid referrer " << referrer_url;
152 // Record network errors that HTTP requests complete with, including OK and
153 // ABORTED.
154 void RecordNetworkErrorHistograms(const net::URLRequest* request) {
155 if (request->url().SchemeIs("http")) {
156 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.HttpRequestCompletionErrorCodes",
157 std::abs(request->status().error()));
159 if (request->load_flags() & net::LOAD_MAIN_FRAME) {
160 UMA_HISTOGRAM_SPARSE_SLOWLY(
161 "Net.HttpRequestCompletionErrorCodes.MainFrame",
162 std::abs(request->status().error()));
167 // Returns whether |request| is likely to be eligible for delta-encoding.
168 // This is only a rough approximation right now, based on MIME type.
169 bool CanRequestBeDeltaEncoded(const net::URLRequest* request) {
170 struct {
171 const char *prefix;
172 const char *suffix;
173 } kEligibleMasks[] = {
174 // All text/ types are eligible, even if not displayable.
175 { "text/", NULL },
176 // JSON (application/json and application/*+json) is eligible.
177 { "application/", "json" },
178 // Javascript is eligible.
179 { "application/", "javascript" },
180 // XML (application/xml and application/*+xml) is eligible.
181 { "application/", "xml" },
183 const bool kCaseSensitive = true;
185 std::string mime_type;
186 request->GetMimeType(&mime_type);
188 for (size_t i = 0; i < arraysize(kEligibleMasks); i++) {
189 const char *prefix = kEligibleMasks[i].prefix;
190 const char *suffix = kEligibleMasks[i].suffix;
191 if (prefix && !StartsWithASCII(mime_type, prefix, kCaseSensitive))
192 continue;
193 if (suffix && !EndsWith(mime_type, suffix, kCaseSensitive))
194 continue;
195 return true;
197 return false;
200 // Returns whether |request| was issued by a renderer process, as opposed to
201 // the browser process or a plugin process.
202 bool IsRendererInitiatedRequest(const net::URLRequest* request) {
203 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
204 return info && info->GetProcessType() == content::PROCESS_TYPE_RENDERER;
207 // Uploads UMA histograms for delta encoding eligibility. This method can only
208 // be safely called after the network stack has called both OnStarted and
209 // OnCompleted, since it needs the received response content length and the
210 // response headers.
211 void RecordCacheStateStats(const net::URLRequest* request) {
212 net::HttpRequestHeaders request_headers;
213 if (!request->GetFullRequestHeaders(&request_headers)) {
214 // GetFullRequestHeaders is guaranteed to succeed if OnResponseStarted() has
215 // been called on |request|, so if GetFullRequestHeaders() fails,
216 // RecordCacheStateStats must have been called before
217 // OnResponseStarted().
218 return;
221 if (!IsRendererInitiatedRequest(request)) {
222 // Ignore browser-initiated requests. These are internal requests like safe
223 // browsing and sync, and so on. Some of these could be eligible for
224 // delta-encoding, but to be conservative this function ignores all of them.
225 return;
228 const int kCacheAffectingFlags = net::LOAD_BYPASS_CACHE |
229 net::LOAD_DISABLE_CACHE |
230 net::LOAD_PREFERRING_CACHE;
232 if (request->load_flags() & kCacheAffectingFlags) {
233 // Ignore requests with cache-affecting flags, which would otherwise mess up
234 // these stats.
235 return;
238 enum {
239 CACHE_STATE_FROM_CACHE,
240 CACHE_STATE_STILL_VALID,
241 CACHE_STATE_NO_LONGER_VALID,
242 CACHE_STATE_NO_ENTRY,
243 CACHE_STATE_MAX,
244 } state = CACHE_STATE_NO_ENTRY;
245 bool had_cache_headers =
246 request_headers.HasHeader(net::HttpRequestHeaders::kIfModifiedSince) ||
247 request_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch) ||
248 request_headers.HasHeader(net::HttpRequestHeaders::kIfRange);
249 if (request->was_cached() && !had_cache_headers) {
250 // Entry was served directly from cache.
251 state = CACHE_STATE_FROM_CACHE;
252 } else if (request->was_cached() && had_cache_headers) {
253 // Expired entry was present in cache, and server responded with NOT
254 // MODIFIED, indicating the expired entry is still valid.
255 state = CACHE_STATE_STILL_VALID;
256 } else if (!request->was_cached() && had_cache_headers) {
257 // Expired entry was present in cache, and server responded with something
258 // other than NOT MODIFIED, indicating the entry is no longer valid.
259 state = CACHE_STATE_NO_LONGER_VALID;
260 } else if (!request->was_cached() && !had_cache_headers) {
261 // Neither |was_cached| nor |had_cache_headers|, so there's no local cache
262 // entry for this content at all.
263 state = CACHE_STATE_NO_ENTRY;
266 UMA_HISTOGRAM_ENUMERATION("Net.CacheState.AllRequests", state,
267 CACHE_STATE_MAX);
268 if (CanRequestBeDeltaEncoded(request)) {
269 UMA_HISTOGRAM_ENUMERATION("Net.CacheState.EncodeableRequests", state,
270 CACHE_STATE_MAX);
273 int64 size = request->received_response_content_length();
274 if (size >= 0 && state == CACHE_STATE_NO_LONGER_VALID) {
275 UMA_HISTOGRAM_COUNTS("Net.CacheState.AllBytes", size);
276 if (CanRequestBeDeltaEncoded(request)) {
277 UMA_HISTOGRAM_COUNTS("Net.CacheState.EncodeableBytes", size);
282 } // namespace
284 ChromeNetworkDelegate::ChromeNetworkDelegate(
285 extensions::EventRouterForwarder* event_router,
286 BooleanPrefMember* enable_referrers)
287 : profile_(NULL),
288 enable_referrers_(enable_referrers),
289 enable_do_not_track_(NULL),
290 force_safe_search_(NULL),
291 force_google_safe_search_(NULL),
292 force_youtube_safety_mode_(NULL),
293 #if defined(ENABLE_CONFIGURATION_POLICY)
294 url_blacklist_manager_(NULL),
295 #endif
296 domain_reliability_monitor_(NULL),
297 experimental_web_platform_features_enabled_(
298 base::CommandLine::ForCurrentProcess()->HasSwitch(
299 switches::kEnableExperimentalWebPlatformFeatures)),
300 first_request_(true),
301 prerender_tracker_(NULL) {
302 DCHECK(enable_referrers);
303 extensions_delegate_.reset(
304 ChromeExtensionsNetworkDelegate::Create(event_router));
307 ChromeNetworkDelegate::~ChromeNetworkDelegate() {}
309 void ChromeNetworkDelegate::set_extension_info_map(
310 extensions::InfoMap* extension_info_map) {
311 extensions_delegate_->set_extension_info_map(extension_info_map);
314 void ChromeNetworkDelegate::set_profile(void* profile) {
315 profile_ = profile;
316 extensions_delegate_->set_profile(profile);
319 void ChromeNetworkDelegate::set_cookie_settings(
320 CookieSettings* cookie_settings) {
321 cookie_settings_ = cookie_settings;
324 void ChromeNetworkDelegate::set_predictor(
325 chrome_browser_net::Predictor* predictor) {
326 connect_interceptor_.reset(
327 new chrome_browser_net::ConnectInterceptor(predictor));
330 // static
331 #if defined(ENABLE_EXTENSIONS)
332 void ChromeNetworkDelegate::NeverThrottleRequests() {
333 g_never_throttle_requests_ = true;
335 #endif
337 // static
338 void ChromeNetworkDelegate::InitializePrefsOnUIThread(
339 BooleanPrefMember* enable_referrers,
340 BooleanPrefMember* enable_do_not_track,
341 BooleanPrefMember* force_safe_search,
342 BooleanPrefMember* force_google_safe_search,
343 BooleanPrefMember* force_youtube_safety_mode,
344 PrefService* pref_service) {
345 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
346 enable_referrers->Init(prefs::kEnableReferrers, pref_service);
347 enable_referrers->MoveToThread(
348 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
349 if (enable_do_not_track) {
350 enable_do_not_track->Init(prefs::kEnableDoNotTrack, pref_service);
351 enable_do_not_track->MoveToThread(
352 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
354 if (force_safe_search) {
355 force_safe_search->Init(prefs::kForceSafeSearch, pref_service);
356 force_safe_search->MoveToThread(
357 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
359 if (force_google_safe_search) {
360 force_google_safe_search->Init(prefs::kForceGoogleSafeSearch, pref_service);
361 force_google_safe_search->MoveToThread(
362 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
364 if (force_youtube_safety_mode) {
365 force_youtube_safety_mode->Init(prefs::kForceYouTubeSafetyMode,
366 pref_service);
367 force_youtube_safety_mode->MoveToThread(
368 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
372 // static
373 void ChromeNetworkDelegate::AllowAccessToAllFiles() {
374 g_allow_file_access_ = true;
377 int ChromeNetworkDelegate::OnBeforeURLRequest(
378 net::URLRequest* request,
379 const net::CompletionCallback& callback,
380 GURL* new_url) {
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;
395 #endif
397 extensions_delegate_->ForwardStartRequestStatus(request);
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 */);
404 bool force_safe_search =
405 (force_safe_search_ && force_safe_search_->GetValue()) ||
406 (force_google_safe_search_ && force_google_safe_search_->GetValue());
408 net::CompletionCallback wrapped_callback = callback;
409 if (force_safe_search) {
410 wrapped_callback = base::Bind(&ForceGoogleSafeSearchCallbackWrapper,
411 callback,
412 base::Unretained(request),
413 base::Unretained(new_url));
416 int rv = extensions_delegate_->OnBeforeURLRequest(
417 request, wrapped_callback, new_url);
419 if (force_safe_search && rv == net::OK && new_url->is_empty())
420 safe_search_util::ForceGoogleSafeSearch(request, new_url);
422 if (connect_interceptor_)
423 connect_interceptor_->WitnessURLRequest(request);
425 return rv;
428 int ChromeNetworkDelegate::OnBeforeSendHeaders(
429 net::URLRequest* request,
430 const net::CompletionCallback& callback,
431 net::HttpRequestHeaders* headers) {
432 bool force_safety_mode =
433 (force_safe_search_ && force_safe_search_->GetValue()) ||
434 (force_youtube_safety_mode_ && force_youtube_safety_mode_->GetValue());
435 if (force_safety_mode)
436 safe_search_util::ForceYouTubeSafetyMode(request, headers);
438 return extensions_delegate_->OnBeforeSendHeaders(request, callback, headers);
441 void ChromeNetworkDelegate::OnSendHeaders(
442 net::URLRequest* request,
443 const net::HttpRequestHeaders& headers) {
444 extensions_delegate_->OnSendHeaders(request, headers);
447 int ChromeNetworkDelegate::OnHeadersReceived(
448 net::URLRequest* request,
449 const net::CompletionCallback& callback,
450 const net::HttpResponseHeaders* original_response_headers,
451 scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
452 GURL* allowed_unsafe_redirect_url) {
453 return extensions_delegate_->OnHeadersReceived(
454 request,
455 callback,
456 original_response_headers,
457 override_response_headers,
458 allowed_unsafe_redirect_url);
461 void ChromeNetworkDelegate::OnBeforeRedirect(net::URLRequest* request,
462 const GURL& new_location) {
463 if (domain_reliability_monitor_)
464 domain_reliability_monitor_->OnBeforeRedirect(request);
465 extensions_delegate_->OnBeforeRedirect(request, new_location);
469 void ChromeNetworkDelegate::OnResponseStarted(net::URLRequest* request) {
470 extensions_delegate_->OnResponseStarted(request);
473 void ChromeNetworkDelegate::OnRawBytesRead(const net::URLRequest& request,
474 int bytes_read) {
475 // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
476 tracked_objects::ScopedTracker tracking_profile(
477 FROM_HERE_WITH_EXPLICIT_FUNCTION(
478 "423948 ChromeNetworkDelegate::OnRawBytesRead"));
480 #if defined(ENABLE_TASK_MANAGER)
481 // This is not completely accurate, but as a first approximation ignore
482 // requests that are served from the cache. See bug 330931 for more info.
483 if (!request.was_cached()) {
484 // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
485 // I suspect that the jank is in creating a TaskManager instance. After the
486 // bug is fixed, rewrite the operators below as one line.
487 tracked_objects::ScopedTracker tracking_profile1(
488 FROM_HERE_WITH_EXPLICIT_FUNCTION(
489 "423948 ChromeNetworkDelegate::OnRawBytesRead1"));
491 TaskManager* task_manager = TaskManager::GetInstance();
493 // TODO(vadimt): Remove ScopedTracker below once crbug.com/423948 is fixed.
494 tracked_objects::ScopedTracker tracking_profile2(
495 FROM_HERE_WITH_EXPLICIT_FUNCTION(
496 "423948 ChromeNetworkDelegate::OnRawBytesRead2"));
498 task_manager->model()->NotifyBytesRead(request, bytes_read);
500 #endif // defined(ENABLE_TASK_MANAGER)
503 void ChromeNetworkDelegate::OnCompleted(net::URLRequest* request,
504 bool started) {
505 RecordNetworkErrorHistograms(request);
506 if (started) {
507 // Only call in for requests that were started, to obey the precondition
508 // that RecordCacheStateStats can only be called on requests for which
509 // OnResponseStarted was called.
510 RecordCacheStateStats(request);
513 if (request->status().status() == net::URLRequestStatus::SUCCESS) {
514 #if defined(OS_ANDROID)
515 // For better accuracy, we use the actual bytes read instead of the length
516 // specified with the Content-Length header, which may be inaccurate,
517 // or missing, as is the case with chunked encoding.
518 int64 received_content_length = request->received_response_content_length();
520 if (precache::PrecacheManager::IsPrecachingEnabled()) {
521 // Record precache metrics when a fetch is completed successfully, if
522 // precaching is enabled.
523 BrowserThread::PostTask(
524 BrowserThread::UI, FROM_HERE,
525 base::Bind(&RecordPrecacheStatsOnUIThread, request->url(),
526 base::Time::Now(), received_content_length,
527 request->was_cached(), profile_));
529 #endif // defined(OS_ANDROID)
530 extensions_delegate_->OnCompleted(request, started);
531 } else if (request->status().status() == net::URLRequestStatus::FAILED ||
532 request->status().status() == net::URLRequestStatus::CANCELED) {
533 extensions_delegate_->OnCompleted(request, started);
534 } else {
535 NOTREACHED();
537 if (domain_reliability_monitor_)
538 domain_reliability_monitor_->OnCompleted(request, started);
539 extensions_delegate_->ForwardProxyErrors(request);
540 extensions_delegate_->ForwardDoneRequestStatus(request);
543 void ChromeNetworkDelegate::OnURLRequestDestroyed(net::URLRequest* request) {
544 extensions_delegate_->OnURLRequestDestroyed(request);
547 void ChromeNetworkDelegate::OnPACScriptError(int line_number,
548 const base::string16& error) {
549 extensions_delegate_->OnPACScriptError(line_number, error);
552 net::NetworkDelegate::AuthRequiredResponse
553 ChromeNetworkDelegate::OnAuthRequired(
554 net::URLRequest* request,
555 const net::AuthChallengeInfo& auth_info,
556 const AuthCallback& callback,
557 net::AuthCredentials* credentials) {
558 return extensions_delegate_->OnAuthRequired(
559 request, auth_info, callback, credentials);
562 bool ChromeNetworkDelegate::OnCanGetCookies(
563 const net::URLRequest& request,
564 const net::CookieList& cookie_list) {
565 // NULL during tests, or when we're running in the system context.
566 if (!cookie_settings_.get())
567 return true;
569 bool allow = cookie_settings_->IsReadingCookieAllowed(
570 request.url(), request.first_party_for_cookies());
572 int render_process_id = -1;
573 int render_frame_id = -1;
575 // |is_for_blocking_resource| indicates whether the cookies read were for a
576 // blocking resource (eg script, css). It is only temporarily added for
577 // diagnostic purposes, per bug 353678. Will be removed again once data
578 // collection is finished.
579 bool is_for_blocking_resource = false;
580 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(&request);
581 if (info && ((!info->IsAsync()) ||
582 info->GetResourceType() == content::RESOURCE_TYPE_STYLESHEET ||
583 info->GetResourceType() == content::RESOURCE_TYPE_SCRIPT)) {
584 is_for_blocking_resource = true;
587 if (content::ResourceRequestInfo::GetRenderFrameForRequest(
588 &request, &render_process_id, &render_frame_id)) {
589 BrowserThread::PostTask(
590 BrowserThread::UI, FROM_HERE,
591 base::Bind(&TabSpecificContentSettings::CookiesRead,
592 render_process_id, render_frame_id,
593 request.url(), request.first_party_for_cookies(),
594 cookie_list, !allow, is_for_blocking_resource));
597 return allow;
600 bool ChromeNetworkDelegate::OnCanSetCookie(const net::URLRequest& request,
601 const std::string& cookie_line,
602 net::CookieOptions* options) {
603 // NULL during tests, or when we're running in the system context.
604 if (!cookie_settings_.get())
605 return true;
607 bool allow = cookie_settings_->IsSettingCookieAllowed(
608 request.url(), request.first_party_for_cookies());
610 int render_process_id = -1;
611 int render_frame_id = -1;
612 if (content::ResourceRequestInfo::GetRenderFrameForRequest(
613 &request, &render_process_id, &render_frame_id)) {
614 BrowserThread::PostTask(
615 BrowserThread::UI, FROM_HERE,
616 base::Bind(&TabSpecificContentSettings::CookieChanged,
617 render_process_id, render_frame_id,
618 request.url(), request.first_party_for_cookies(),
619 cookie_line, *options, !allow));
622 if (prerender_tracker_) {
623 prerender_tracker_->OnCookieChangedForURL(
624 render_process_id,
625 request.context()->cookie_store()->GetCookieMonster(),
626 request.url());
629 return allow;
632 bool ChromeNetworkDelegate::OnCanAccessFile(const net::URLRequest& request,
633 const base::FilePath& path) const {
634 if (g_allow_file_access_)
635 return true;
637 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
638 return true;
639 #else
640 #if defined(OS_CHROMEOS)
641 // If we're running Chrome for ChromeOS on Linux, we want to allow file
642 // access.
643 if (!base::SysInfo::IsRunningOnChromeOS() ||
644 base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kTestType)) {
645 return true;
648 // Use a whitelist to only allow access to files residing in the list of
649 // directories below.
650 static const char* const kLocalAccessWhiteList[] = {
651 "/home/chronos/user/Downloads",
652 "/home/chronos/user/log",
653 "/home/chronos/user/WebRTC Logs",
654 "/media",
655 "/opt/oem",
656 "/usr/share/chromeos-assets",
657 "/tmp",
658 "/var/log",
661 // The actual location of "/home/chronos/user/Xyz" is the Xyz directory under
662 // the profile path ("/home/chronos/user' is a hard link to current primary
663 // logged in profile.) For the support of multi-profile sessions, we are
664 // switching to use explicit "$PROFILE_PATH/Xyz" path and here whitelist such
665 // access.
666 if (!profile_path_.empty()) {
667 const base::FilePath downloads = profile_path_.AppendASCII("Downloads");
668 if (downloads == path.StripTrailingSeparators() || downloads.IsParent(path))
669 return true;
670 const base::FilePath webrtc_logs = profile_path_.AppendASCII("WebRTC Logs");
671 if (webrtc_logs == path.StripTrailingSeparators() ||
672 webrtc_logs.IsParent(path)) {
673 return true;
676 #elif defined(OS_ANDROID)
677 // Access to files in external storage is allowed.
678 base::FilePath external_storage_path;
679 PathService::Get(base::DIR_ANDROID_EXTERNAL_STORAGE, &external_storage_path);
680 if (external_storage_path.IsParent(path))
681 return true;
683 // Whitelist of other allowed directories.
684 static const char* const kLocalAccessWhiteList[] = {
685 "/sdcard",
686 "/mnt/sdcard",
688 #endif
690 for (size_t i = 0; i < arraysize(kLocalAccessWhiteList); ++i) {
691 const base::FilePath white_listed_path(kLocalAccessWhiteList[i]);
692 // base::FilePath::operator== should probably handle trailing separators.
693 if (white_listed_path == path.StripTrailingSeparators() ||
694 white_listed_path.IsParent(path)) {
695 return true;
699 DVLOG(1) << "File access denied - " << path.value().c_str();
700 return false;
701 #endif // !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
704 bool ChromeNetworkDelegate::OnCanThrottleRequest(
705 const net::URLRequest& request) const {
706 #if defined(ENABLE_EXTENSIONS)
707 if (g_never_throttle_requests_)
708 return false;
709 return request.first_party_for_cookies().scheme() ==
710 extensions::kExtensionScheme;
711 #else
712 return false;
713 #endif
716 bool ChromeNetworkDelegate::OnCanEnablePrivacyMode(
717 const GURL& url,
718 const GURL& first_party_for_cookies) const {
719 // NULL during tests, or when we're running in the system context.
720 if (!cookie_settings_.get())
721 return false;
723 bool reading_cookie_allowed = cookie_settings_->IsReadingCookieAllowed(
724 url, first_party_for_cookies);
725 bool setting_cookie_allowed = cookie_settings_->IsSettingCookieAllowed(
726 url, first_party_for_cookies);
727 bool privacy_mode = !(reading_cookie_allowed && setting_cookie_allowed);
728 return privacy_mode;
731 bool ChromeNetworkDelegate::OnFirstPartyOnlyCookieExperimentEnabled() const {
732 return experimental_web_platform_features_enabled_;
735 bool ChromeNetworkDelegate::OnCancelURLRequestWithPolicyViolatingReferrerHeader(
736 const net::URLRequest& request,
737 const GURL& target_url,
738 const GURL& referrer_url) const {
739 ReportInvalidReferrerSend(target_url, referrer_url);
740 return true;