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"
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/profiles/profile_manager.h"
35 #include "chrome/browser/task_manager/task_manager.h"
36 #include "chrome/common/pref_names.h"
37 #include "components/domain_reliability/monitor.h"
38 #include "content/public/browser/browser_thread.h"
39 #include "content/public/browser/render_frame_host.h"
40 #include "content/public/browser/render_view_host.h"
41 #include "content/public/browser/resource_request_info.h"
42 #include "content/public/common/content_switches.h"
43 #include "content/public/common/process_type.h"
44 #include "net/base/host_port_pair.h"
45 #include "net/base/load_flags.h"
46 #include "net/base/net_errors.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/http/http_status_code.h"
52 #include "net/log/net_log.h"
53 #include "net/url_request/url_request.h"
55 #if defined(OS_ANDROID)
56 #include "chrome/browser/io_thread.h"
57 #include "chrome/browser/precache/precache_manager_factory.h"
58 #include "components/precache/content/precache_manager.h"
61 #if defined(OS_CHROMEOS)
62 #include "base/sys_info.h"
63 #include "chrome/common/chrome_switches.h"
66 #if defined(ENABLE_CONFIGURATION_POLICY)
67 #include "components/policy/core/browser/url_blacklist_manager.h"
70 #if defined(ENABLE_EXTENSIONS)
71 #include "extensions/common/constants.h"
74 using content::BrowserThread
;
75 using content::RenderViewHost
;
76 using content::ResourceRequestInfo
;
77 using content::ResourceType
;
79 // By default we don't allow access to all file:// urls on ChromeOS and
81 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
82 bool ChromeNetworkDelegate::g_allow_file_access_
= false;
84 bool ChromeNetworkDelegate::g_allow_file_access_
= true;
89 const char kDNTHeader
[] = "DNT";
91 // Gets called when the extensions finish work on the URL. If the extensions
92 // did not do a redirect (so |new_url| is empty) then we enforce the
93 // SafeSearch parameters. Otherwise we will get called again after the
94 // redirect and we enforce SafeSearch then.
95 void ForceGoogleSafeSearchCallbackWrapper(
96 const net::CompletionCallback
& callback
,
97 net::URLRequest
* request
,
100 if (rv
== net::OK
&& new_url
->is_empty())
101 safe_search_util::ForceGoogleSafeSearch(request
, new_url
);
105 #if defined(OS_ANDROID)
106 void RecordPrecacheStatsOnUIThread(const GURL
& url
,
107 const base::Time
& fetch_time
, int64 size
,
108 bool was_cached
, void* profile_id
) {
109 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
111 Profile
* profile
= reinterpret_cast<Profile
*>(profile_id
);
112 if (!g_browser_process
->profile_manager()->IsValidProfile(profile
)) {
116 precache::PrecacheManager
* precache_manager
=
117 precache::PrecacheManagerFactory::GetForBrowserContext(profile
);
118 if (!precache_manager
|| !precache_manager
->IsPrecachingAllowed()) {
119 // |precache_manager| could be NULL if the profile is off the record.
123 precache_manager
->RecordStatsForFetch(url
, fetch_time
, size
, was_cached
);
125 #endif // defined(OS_ANDROID)
127 void ReportInvalidReferrerSendOnUI() {
129 base::UserMetricsAction("Net.URLRequest_StartJob_InvalidReferrer"));
132 void ReportInvalidReferrerSend(const GURL
& target_url
,
133 const GURL
& referrer_url
) {
134 LOG(ERROR
) << "Cancelling request to " << target_url
135 << " with invalid referrer " << referrer_url
;
136 // Record information to help debug http://crbug.com/422871
137 if (!target_url
.SchemeIsHTTPOrHTTPS())
139 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
140 base::Bind(&ReportInvalidReferrerSendOnUI
));
141 base::debug::DumpWithoutCrashing();
145 // Record network errors that HTTP requests complete with, including OK and
147 void RecordNetworkErrorHistograms(const net::URLRequest
* request
) {
148 if (request
->url().SchemeIs("http")) {
149 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.HttpRequestCompletionErrorCodes",
150 std::abs(request
->status().error()));
152 if (request
->load_flags() & net::LOAD_MAIN_FRAME
) {
153 UMA_HISTOGRAM_SPARSE_SLOWLY(
154 "Net.HttpRequestCompletionErrorCodes.MainFrame",
155 std::abs(request
->status().error()));
160 // Returns whether |request| is likely to be eligible for delta-encoding.
161 // This is only a rough approximation right now, based on MIME type.
162 bool CanRequestBeDeltaEncoded(const net::URLRequest
* request
) {
166 } kEligibleMasks
[] = {
167 // All text/ types are eligible, even if not displayable.
169 // JSON (application/json and application/*+json) is eligible.
170 { "application/", "json" },
171 // Javascript is eligible.
172 { "application/", "javascript" },
173 // XML (application/xml and application/*+xml) is eligible.
174 { "application/", "xml" },
176 const bool kCaseSensitive
= true;
178 std::string mime_type
;
179 request
->GetMimeType(&mime_type
);
181 for (size_t i
= 0; i
< arraysize(kEligibleMasks
); i
++) {
182 const char *prefix
= kEligibleMasks
[i
].prefix
;
183 const char *suffix
= kEligibleMasks
[i
].suffix
;
184 if (prefix
&& !base::StartsWithASCII(mime_type
, prefix
, kCaseSensitive
))
186 if (suffix
&& !base::EndsWith(mime_type
, suffix
, kCaseSensitive
))
193 // Returns whether |request| was issued by a renderer process, as opposed to
194 // the browser process or a plugin process.
195 bool IsRendererInitiatedRequest(const net::URLRequest
* request
) {
196 const ResourceRequestInfo
* info
= ResourceRequestInfo::ForRequest(request
);
197 return info
&& info
->GetProcessType() == content::PROCESS_TYPE_RENDERER
;
200 // Uploads UMA histograms for delta encoding eligibility. This method can only
201 // be safely called after the network stack has called both OnStarted and
202 // OnCompleted, since it needs the received response content length and the
204 void RecordCacheStateStats(const net::URLRequest
* request
) {
205 net::HttpRequestHeaders request_headers
;
206 if (!request
->GetFullRequestHeaders(&request_headers
)) {
207 // GetFullRequestHeaders is guaranteed to succeed if OnResponseStarted() has
208 // been called on |request|, so if GetFullRequestHeaders() fails,
209 // RecordCacheStateStats must have been called before
210 // OnResponseStarted().
214 if (!IsRendererInitiatedRequest(request
)) {
215 // Ignore browser-initiated requests. These are internal requests like safe
216 // browsing and sync, and so on. Some of these could be eligible for
217 // delta-encoding, but to be conservative this function ignores all of them.
221 const int kCacheAffectingFlags
= net::LOAD_BYPASS_CACHE
|
222 net::LOAD_DISABLE_CACHE
|
223 net::LOAD_PREFERRING_CACHE
;
225 if (request
->load_flags() & kCacheAffectingFlags
) {
226 // Ignore requests with cache-affecting flags, which would otherwise mess up
232 CACHE_STATE_FROM_CACHE
,
233 CACHE_STATE_STILL_VALID
,
234 CACHE_STATE_NO_LONGER_VALID
,
235 CACHE_STATE_NO_ENTRY
,
237 } state
= CACHE_STATE_NO_ENTRY
;
238 bool had_cache_headers
=
239 request_headers
.HasHeader(net::HttpRequestHeaders::kIfModifiedSince
) ||
240 request_headers
.HasHeader(net::HttpRequestHeaders::kIfNoneMatch
) ||
241 request_headers
.HasHeader(net::HttpRequestHeaders::kIfRange
);
242 if (request
->was_cached() && !had_cache_headers
) {
243 // Entry was served directly from cache.
244 state
= CACHE_STATE_FROM_CACHE
;
245 } else if (request
->was_cached() && had_cache_headers
) {
246 // Expired entry was present in cache, and server responded with NOT
247 // MODIFIED, indicating the expired entry is still valid.
248 state
= CACHE_STATE_STILL_VALID
;
249 } else if (!request
->was_cached() && had_cache_headers
) {
250 // Expired entry was present in cache, and server responded with something
251 // other than NOT MODIFIED, indicating the entry is no longer valid.
252 state
= CACHE_STATE_NO_LONGER_VALID
;
253 } else if (!request
->was_cached() && !had_cache_headers
) {
254 // Neither |was_cached| nor |had_cache_headers|, so there's no local cache
255 // entry for this content at all.
256 state
= CACHE_STATE_NO_ENTRY
;
259 UMA_HISTOGRAM_ENUMERATION("Net.CacheState.AllRequests", state
,
261 if (CanRequestBeDeltaEncoded(request
)) {
262 UMA_HISTOGRAM_ENUMERATION("Net.CacheState.EncodeableRequests", state
,
266 int64 size
= request
->received_response_content_length();
267 if (size
>= 0 && state
== CACHE_STATE_NO_LONGER_VALID
) {
268 UMA_HISTOGRAM_COUNTS("Net.CacheState.AllBytes", size
);
269 if (CanRequestBeDeltaEncoded(request
)) {
270 UMA_HISTOGRAM_COUNTS("Net.CacheState.EncodeableBytes", size
);
277 ChromeNetworkDelegate::ChromeNetworkDelegate(
278 extensions::EventRouterForwarder
* event_router
,
279 BooleanPrefMember
* enable_referrers
)
281 enable_referrers_(enable_referrers
),
282 enable_do_not_track_(NULL
),
283 force_google_safe_search_(NULL
),
284 force_youtube_safety_mode_(NULL
),
285 #if defined(ENABLE_CONFIGURATION_POLICY)
286 url_blacklist_manager_(NULL
),
288 domain_reliability_monitor_(NULL
),
289 experimental_web_platform_features_enabled_(
290 base::CommandLine::ForCurrentProcess()->HasSwitch(
291 switches::kEnableExperimentalWebPlatformFeatures
)) {
292 DCHECK(enable_referrers
);
293 extensions_delegate_
.reset(
294 ChromeExtensionsNetworkDelegate::Create(event_router
));
297 ChromeNetworkDelegate::~ChromeNetworkDelegate() {}
299 void ChromeNetworkDelegate::set_extension_info_map(
300 extensions::InfoMap
* extension_info_map
) {
301 extensions_delegate_
->set_extension_info_map(extension_info_map
);
304 void ChromeNetworkDelegate::set_profile(void* profile
) {
306 extensions_delegate_
->set_profile(profile
);
309 void ChromeNetworkDelegate::set_cookie_settings(
310 CookieSettings
* cookie_settings
) {
311 cookie_settings_
= cookie_settings
;
314 void ChromeNetworkDelegate::set_predictor(
315 chrome_browser_net::Predictor
* predictor
) {
316 connect_interceptor_
.reset(
317 new chrome_browser_net::ConnectInterceptor(predictor
));
321 void ChromeNetworkDelegate::InitializePrefsOnUIThread(
322 BooleanPrefMember
* enable_referrers
,
323 BooleanPrefMember
* enable_do_not_track
,
324 BooleanPrefMember
* force_google_safe_search
,
325 BooleanPrefMember
* force_youtube_safety_mode
,
326 PrefService
* pref_service
) {
327 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
328 enable_referrers
->Init(prefs::kEnableReferrers
, pref_service
);
329 enable_referrers
->MoveToThread(
330 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
));
331 if (enable_do_not_track
) {
332 enable_do_not_track
->Init(prefs::kEnableDoNotTrack
, pref_service
);
333 enable_do_not_track
->MoveToThread(
334 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
));
336 if (force_google_safe_search
) {
337 force_google_safe_search
->Init(prefs::kForceGoogleSafeSearch
, pref_service
);
338 force_google_safe_search
->MoveToThread(
339 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
));
341 if (force_youtube_safety_mode
) {
342 force_youtube_safety_mode
->Init(prefs::kForceYouTubeSafetyMode
,
344 force_youtube_safety_mode
->MoveToThread(
345 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
));
350 void ChromeNetworkDelegate::AllowAccessToAllFiles() {
351 g_allow_file_access_
= true;
354 int ChromeNetworkDelegate::OnBeforeURLRequest(
355 net::URLRequest
* request
,
356 const net::CompletionCallback
& callback
,
358 // TODO(mmenke): Remove ScopedTracker below once crbug.com/456327 is fixed.
359 tracked_objects::ScopedTracker
tracking_profile1(
360 FROM_HERE_WITH_EXPLICIT_FUNCTION(
361 "456327 URLRequest::ChromeNetworkDelegate::OnBeforeURLRequest"));
363 #if defined(ENABLE_CONFIGURATION_POLICY)
364 // TODO(joaodasilva): This prevents extensions from seeing URLs that are
365 // blocked. However, an extension might redirect the request to another URL,
366 // which is not blocked.
368 const ResourceRequestInfo
* info
= ResourceRequestInfo::ForRequest(request
);
369 int error
= net::ERR_BLOCKED_BY_ADMINISTRATOR
;
370 if (info
&& content::IsResourceTypeFrame(info
->GetResourceType()) &&
371 url_blacklist_manager_
&&
372 url_blacklist_manager_
->ShouldBlockRequestForFrame(
373 request
->url(), &error
)) {
374 // URL access blocked by policy.
375 request
->net_log().AddEvent(
376 net::NetLog::TYPE_CHROME_POLICY_ABORTED_REQUEST
,
377 net::NetLog::StringCallback("url",
378 &request
->url().possibly_invalid_spec()));
383 // TODO(mmenke): Remove ScopedTracker below once crbug.com/456327 is fixed.
384 tracked_objects::ScopedTracker
tracking_profile2(
385 FROM_HERE_WITH_EXPLICIT_FUNCTION(
386 "456327 URLRequest::ChromeNetworkDelegate::OnBeforeURLRequest 2"));
388 extensions_delegate_
->ForwardStartRequestStatus(request
);
390 if (!enable_referrers_
->GetValue())
391 request
->SetReferrer(std::string());
392 if (enable_do_not_track_
&& enable_do_not_track_
->GetValue())
393 request
->SetExtraRequestHeaderByName(kDNTHeader
, "1", true /* override */);
395 // TODO(mmenke): Remove ScopedTracker below once crbug.com/456327 is fixed.
396 tracked_objects::ScopedTracker
tracking_profile3(
397 FROM_HERE_WITH_EXPLICIT_FUNCTION(
398 "456327 URLRequest::ChromeNetworkDelegate::OnBeforeURLRequest 3"));
400 bool force_safe_search
=
401 (force_google_safe_search_
&& force_google_safe_search_
->GetValue());
403 net::CompletionCallback wrapped_callback
= callback
;
404 if (force_safe_search
) {
405 wrapped_callback
= base::Bind(&ForceGoogleSafeSearchCallbackWrapper
,
407 base::Unretained(request
),
408 base::Unretained(new_url
));
411 int rv
= extensions_delegate_
->OnBeforeURLRequest(
412 request
, wrapped_callback
, new_url
);
414 // TODO(mmenke): Remove ScopedTracker below once crbug.com/456327 is fixed.
415 tracked_objects::ScopedTracker
tracking_profile4(
416 FROM_HERE_WITH_EXPLICIT_FUNCTION(
417 "456327 URLRequest::ChromeNetworkDelegate::OnBeforeURLRequest 4"));
419 if (force_safe_search
&& rv
== net::OK
&& new_url
->is_empty())
420 safe_search_util::ForceGoogleSafeSearch(request
, new_url
);
422 // TODO(mmenke): Remove ScopedTracker below once crbug.com/456327 is fixed.
423 tracked_objects::ScopedTracker
tracking_profile5(
424 FROM_HERE_WITH_EXPLICIT_FUNCTION(
425 "456327 URLRequest::ChromeNetworkDelegate::OnBeforeURLRequest 5"));
427 if (connect_interceptor_
)
428 connect_interceptor_
->WitnessURLRequest(request
);
433 int ChromeNetworkDelegate::OnBeforeSendHeaders(
434 net::URLRequest
* request
,
435 const net::CompletionCallback
& callback
,
436 net::HttpRequestHeaders
* headers
) {
437 if (force_youtube_safety_mode_
&& force_youtube_safety_mode_
->GetValue())
438 safe_search_util::ForceYouTubeSafetyMode(request
, headers
);
440 return extensions_delegate_
->OnBeforeSendHeaders(request
, callback
, headers
);
443 void ChromeNetworkDelegate::OnSendHeaders(
444 net::URLRequest
* request
,
445 const net::HttpRequestHeaders
& headers
) {
446 extensions_delegate_
->OnSendHeaders(request
, headers
);
449 int ChromeNetworkDelegate::OnHeadersReceived(
450 net::URLRequest
* request
,
451 const net::CompletionCallback
& callback
,
452 const net::HttpResponseHeaders
* original_response_headers
,
453 scoped_refptr
<net::HttpResponseHeaders
>* override_response_headers
,
454 GURL
* allowed_unsafe_redirect_url
) {
455 return extensions_delegate_
->OnHeadersReceived(
458 original_response_headers
,
459 override_response_headers
,
460 allowed_unsafe_redirect_url
);
463 void ChromeNetworkDelegate::OnBeforeRedirect(net::URLRequest
* request
,
464 const GURL
& new_location
) {
465 if (domain_reliability_monitor_
)
466 domain_reliability_monitor_
->OnBeforeRedirect(request
);
467 extensions_delegate_
->OnBeforeRedirect(request
, new_location
);
471 void ChromeNetworkDelegate::OnResponseStarted(net::URLRequest
* request
) {
472 extensions_delegate_
->OnResponseStarted(request
);
475 void ChromeNetworkDelegate::OnRawBytesRead(const net::URLRequest
& request
,
477 #if defined(ENABLE_TASK_MANAGER)
478 // This is not completely accurate, but as a first approximation ignore
479 // requests that are served from the cache. See bug 330931 for more info.
480 if (!request
.was_cached())
481 TaskManager::GetInstance()->model()->NotifyBytesRead(request
, bytes_read
);
482 #endif // defined(ENABLE_TASK_MANAGER)
485 void ChromeNetworkDelegate::OnCompleted(net::URLRequest
* request
,
487 RecordNetworkErrorHistograms(request
);
489 // Only call in for requests that were started, to obey the precondition
490 // that RecordCacheStateStats can only be called on requests for which
491 // OnResponseStarted was called.
492 RecordCacheStateStats(request
);
495 if (request
->status().status() == net::URLRequestStatus::SUCCESS
) {
496 #if defined(OS_ANDROID)
497 // For better accuracy, we use the actual bytes read instead of the length
498 // specified with the Content-Length header, which may be inaccurate,
499 // or missing, as is the case with chunked encoding.
500 int64 received_content_length
= request
->received_response_content_length();
502 if (precache::PrecacheManager::IsPrecachingEnabled()) {
503 // Record precache metrics when a fetch is completed successfully, if
504 // precaching is enabled.
505 BrowserThread::PostTask(
506 BrowserThread::UI
, FROM_HERE
,
507 base::Bind(&RecordPrecacheStatsOnUIThread
, request
->url(),
508 base::Time::Now(), received_content_length
,
509 request
->was_cached(), profile_
));
511 #endif // defined(OS_ANDROID)
512 extensions_delegate_
->OnCompleted(request
, started
);
513 } else if (request
->status().status() == net::URLRequestStatus::FAILED
||
514 request
->status().status() == net::URLRequestStatus::CANCELED
) {
515 extensions_delegate_
->OnCompleted(request
, started
);
519 if (domain_reliability_monitor_
)
520 domain_reliability_monitor_
->OnCompleted(request
, started
);
521 extensions_delegate_
->ForwardProxyErrors(request
);
522 extensions_delegate_
->ForwardDoneRequestStatus(request
);
525 void ChromeNetworkDelegate::OnURLRequestDestroyed(net::URLRequest
* request
) {
526 extensions_delegate_
->OnURLRequestDestroyed(request
);
529 void ChromeNetworkDelegate::OnPACScriptError(int line_number
,
530 const base::string16
& error
) {
531 extensions_delegate_
->OnPACScriptError(line_number
, error
);
534 net::NetworkDelegate::AuthRequiredResponse
535 ChromeNetworkDelegate::OnAuthRequired(
536 net::URLRequest
* request
,
537 const net::AuthChallengeInfo
& auth_info
,
538 const AuthCallback
& callback
,
539 net::AuthCredentials
* credentials
) {
540 return extensions_delegate_
->OnAuthRequired(
541 request
, auth_info
, callback
, credentials
);
544 bool ChromeNetworkDelegate::OnCanGetCookies(
545 const net::URLRequest
& request
,
546 const net::CookieList
& cookie_list
) {
547 // NULL during tests, or when we're running in the system context.
548 if (!cookie_settings_
.get())
551 bool allow
= cookie_settings_
->IsReadingCookieAllowed(
552 request
.url(), request
.first_party_for_cookies());
554 int render_process_id
= -1;
555 int render_frame_id
= -1;
556 if (content::ResourceRequestInfo::GetRenderFrameForRequest(
557 &request
, &render_process_id
, &render_frame_id
)) {
558 BrowserThread::PostTask(
559 BrowserThread::UI
, FROM_HERE
,
560 base::Bind(&TabSpecificContentSettings::CookiesRead
,
561 render_process_id
, render_frame_id
,
562 request
.url(), request
.first_party_for_cookies(),
563 cookie_list
, !allow
));
569 bool ChromeNetworkDelegate::OnCanSetCookie(const net::URLRequest
& request
,
570 const std::string
& cookie_line
,
571 net::CookieOptions
* options
) {
572 // NULL during tests, or when we're running in the system context.
573 if (!cookie_settings_
.get())
576 bool allow
= cookie_settings_
->IsSettingCookieAllowed(
577 request
.url(), request
.first_party_for_cookies());
579 int render_process_id
= -1;
580 int render_frame_id
= -1;
581 if (content::ResourceRequestInfo::GetRenderFrameForRequest(
582 &request
, &render_process_id
, &render_frame_id
)) {
583 BrowserThread::PostTask(
584 BrowserThread::UI
, FROM_HERE
,
585 base::Bind(&TabSpecificContentSettings::CookieChanged
,
586 render_process_id
, render_frame_id
,
587 request
.url(), request
.first_party_for_cookies(),
588 cookie_line
, *options
, !allow
));
594 bool ChromeNetworkDelegate::OnCanAccessFile(const net::URLRequest
& request
,
595 const base::FilePath
& path
) const {
596 if (g_allow_file_access_
)
599 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
602 #if defined(OS_CHROMEOS)
603 // If we're running Chrome for ChromeOS on Linux, we want to allow file
605 if (!base::SysInfo::IsRunningOnChromeOS() ||
606 base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kTestType
)) {
610 // Use a whitelist to only allow access to files residing in the list of
611 // directories below.
612 static const char* const kLocalAccessWhiteList
[] = {
613 "/home/chronos/user/Downloads",
614 "/home/chronos/user/log",
615 "/home/chronos/user/WebRTC Logs",
618 "/usr/share/chromeos-assets",
623 // The actual location of "/home/chronos/user/Xyz" is the Xyz directory under
624 // the profile path ("/home/chronos/user' is a hard link to current primary
625 // logged in profile.) For the support of multi-profile sessions, we are
626 // switching to use explicit "$PROFILE_PATH/Xyz" path and here whitelist such
628 if (!profile_path_
.empty()) {
629 const base::FilePath downloads
= profile_path_
.AppendASCII("Downloads");
630 if (downloads
== path
.StripTrailingSeparators() || downloads
.IsParent(path
))
632 const base::FilePath webrtc_logs
= profile_path_
.AppendASCII("WebRTC Logs");
633 if (webrtc_logs
== path
.StripTrailingSeparators() ||
634 webrtc_logs
.IsParent(path
)) {
638 #elif defined(OS_ANDROID)
639 // Access to files in external storage is allowed.
640 base::FilePath external_storage_path
;
641 PathService::Get(base::DIR_ANDROID_EXTERNAL_STORAGE
, &external_storage_path
);
642 if (external_storage_path
.IsParent(path
))
645 // Whitelist of other allowed directories.
646 static const char* const kLocalAccessWhiteList
[] = {
652 for (size_t i
= 0; i
< arraysize(kLocalAccessWhiteList
); ++i
) {
653 const base::FilePath
white_listed_path(kLocalAccessWhiteList
[i
]);
654 // base::FilePath::operator== should probably handle trailing separators.
655 if (white_listed_path
== path
.StripTrailingSeparators() ||
656 white_listed_path
.IsParent(path
)) {
661 DVLOG(1) << "File access denied - " << path
.value().c_str();
663 #endif // !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
666 bool ChromeNetworkDelegate::OnCanEnablePrivacyMode(
668 const GURL
& first_party_for_cookies
) const {
669 // NULL during tests, or when we're running in the system context.
670 if (!cookie_settings_
.get())
673 bool reading_cookie_allowed
= cookie_settings_
->IsReadingCookieAllowed(
674 url
, first_party_for_cookies
);
675 bool setting_cookie_allowed
= cookie_settings_
->IsSettingCookieAllowed(
676 url
, first_party_for_cookies
);
677 bool privacy_mode
= !(reading_cookie_allowed
&& setting_cookie_allowed
);
681 bool ChromeNetworkDelegate::OnFirstPartyOnlyCookieExperimentEnabled() const {
682 return experimental_web_platform_features_enabled_
;
685 bool ChromeNetworkDelegate::OnCancelURLRequestWithPolicyViolatingReferrerHeader(
686 const net::URLRequest
& request
,
687 const GURL
& target_url
,
688 const GURL
& referrer_url
) const {
689 ReportInvalidReferrerSend(target_url
, referrer_url
);