blob: 615a80d56ae35c1c439d6a6017795183e4b8b4b4 [file] [log] [blame]
[email protected]9045b8822012-01-13 20:35:351// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]ac039522010-06-15 16:39:442// 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
[email protected]d8e4f132012-09-06 04:28:057#include "base/base_paths.h"
[email protected]7a299a92012-10-24 23:54:508#include "base/logging.h"
9#include "base/metrics/histogram.h"
[email protected]d8e4f132012-09-06 04:28:0510#include "base/path_service.h"
[email protected]c5aa8262012-08-21 11:19:5411#include "chrome/browser/api/prefs/pref_member.h"
[email protected]6baff0b52012-03-06 01:30:1812#include "chrome/browser/browser_process.h"
[email protected]9c8ae8c2012-03-09 13:13:3513#include "chrome/browser/content_settings/cookie_settings.h"
14#include "chrome/browser/content_settings/tab_specific_content_settings.h"
[email protected]8523ba52011-05-22 19:00:5815#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
[email protected]aa84a7e2012-03-15 21:29:0616#include "chrome/browser/extensions/api/proxy/proxy_api.h"
[email protected]2b33dcd02012-03-18 01:34:1617#include "chrome/browser/extensions/api/web_request/web_request_api.h"
[email protected]5a38dfd2012-07-23 23:22:1018#include "chrome/browser/extensions/event_router_forwarder.h"
[email protected]c357acb42011-06-09 20:52:4219#include "chrome/browser/extensions/extension_info_map.h"
[email protected]6baff0b52012-03-06 01:30:1820#include "chrome/browser/extensions/extension_process_manager.h"
[email protected]be93bba02012-10-24 16:44:0321#include "chrome/browser/extensions/extension_system.h"
[email protected]a9e0d1412012-08-20 22:13:0122#include "chrome/browser/net/load_time_stats.h"
[email protected]6f4b4b42012-08-27 21:59:0723#include "chrome/browser/performance_monitor/performance_monitor.h"
[email protected]fb8fdf12012-08-21 16:28:2024#include "chrome/browser/prefs/pref_service.h"
[email protected]6baff0b52012-03-06 01:30:1825#include "chrome/browser/profiles/profile_manager.h"
[email protected]8523ba52011-05-22 19:00:5826#include "chrome/browser/task_manager/task_manager.h"
[email protected]0a8db0d2011-04-13 15:15:4027#include "chrome/common/pref_names.h"
[email protected]a1d4ab072012-06-07 13:21:1528#include "chrome/common/url_constants.h"
[email protected]c38831a12011-10-28 12:44:4929#include "content/public/browser/browser_thread.h"
[email protected]9c1662b2012-03-06 15:44:3330#include "content/public/browser/render_view_host.h"
[email protected]9c8ae8c2012-03-09 13:13:3531#include "content/public/browser/resource_request_info.h"
[email protected]82b42302011-04-20 16:28:1632#include "net/base/host_port_pair.h"
[email protected]8202d0c2011-02-23 08:31:1433#include "net/base/net_errors.h"
[email protected]6a5f77c32011-09-04 19:19:5934#include "net/base/net_log.h"
[email protected]5b9bc352012-07-18 13:13:3435#include "net/cookies/canonical_cookie.h"
36#include "net/cookies/cookie_options.h"
[email protected]ac039522010-06-15 16:39:4437#include "net/http/http_request_headers.h"
[email protected]48944382011-04-23 13:28:1638#include "net/http/http_response_headers.h"
[email protected]aa28181e2012-06-13 00:53:5839#include "net/socket_stream/socket_stream.h"
[email protected]d05ef99c2011-02-01 21:38:1640#include "net/url_request/url_request.h"
41
[email protected]e9c41d22012-08-17 00:08:1542#if !defined(OS_ANDROID)
[email protected]46690b72012-10-26 19:33:3243#include "chrome/browser/managed_mode/managed_mode_url_filter.h"
[email protected]e9c41d22012-08-17 00:08:1544#endif
45
[email protected]4c219e22012-05-05 19:41:0446#if defined(OS_CHROMEOS)
47#include "base/chromeos/chromeos_version.h"
[email protected]288538482012-09-06 21:09:3548#include "base/command_line.h"
49#include "chrome/common/chrome_switches.h"
[email protected]4c219e22012-05-05 19:41:0450#endif
51
[email protected]3e598ff12011-09-06 11:22:3452#if defined(ENABLE_CONFIGURATION_POLICY)
53#include "chrome/browser/policy/url_blacklist_manager.h"
54#endif
55
[email protected]631bb742011-11-02 11:29:3956using content::BrowserThread;
[email protected]eaabba22012-03-07 15:02:1157using content::RenderViewHost;
[email protected]ea114722012-03-12 01:11:2558using content::ResourceRequestInfo;
[email protected]631bb742011-11-02 11:29:3959
[email protected]d8e4f132012-09-06 04:28:0560// By default we don't allow access to all file:// urls on ChromeOS and
61// Android.
62#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
[email protected]4c219e22012-05-05 19:41:0463bool ChromeNetworkDelegate::g_allow_file_access_ = false;
64#else
65bool ChromeNetworkDelegate::g_allow_file_access_ = true;
66#endif
67
[email protected]c4a7df82012-08-09 22:48:4668// This remains false unless the --disable-extensions-http-throttling
69// flag is passed to the browser.
70bool ChromeNetworkDelegate::g_never_throttle_requests_ = false;
71
[email protected]d05ef99c2011-02-01 21:38:1672namespace {
73
[email protected]9d8cfb682012-09-13 16:48:0474const char kDNTHeader[] = "DNT";
75
[email protected]8202d0c2011-02-23 08:31:1476// If the |request| failed due to problems with a proxy, forward the error to
77// the proxy extension API.
[email protected]0651b812011-02-24 00:22:5078void ForwardProxyErrors(net::URLRequest* request,
[email protected]5a38dfd2012-07-23 23:22:1079 extensions::EventRouterForwarder* event_router,
[email protected]673514522011-07-13 18:17:1880 void* profile) {
[email protected]8202d0c2011-02-23 08:31:1481 if (request->status().status() == net::URLRequestStatus::FAILED) {
[email protected]d0cc35b2011-09-08 12:02:0582 switch (request->status().error()) {
[email protected]8202d0c2011-02-23 08:31:1483 case net::ERR_PROXY_AUTH_UNSUPPORTED:
84 case net::ERR_PROXY_CONNECTION_FAILED:
85 case net::ERR_TUNNEL_CONNECTION_FAILED:
[email protected]c454fe672012-03-12 21:18:0186 extensions::ProxyEventRouter::GetInstance()->OnProxyError(
[email protected]d0cc35b2011-09-08 12:02:0587 event_router, profile, request->status().error());
[email protected]8202d0c2011-02-23 08:31:1488 }
89 }
90}
91
[email protected]6baff0b52012-03-06 01:30:1892enum RequestStatus { REQUEST_STARTED, REQUEST_DONE };
93
94// Notifies the ExtensionProcessManager that a request has started or stopped
95// for a particular RenderView.
96void NotifyEPMRequestStatus(RequestStatus status,
97 void* profile_id,
98 int process_id,
99 int render_view_id) {
100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
101 Profile* profile = reinterpret_cast<Profile*>(profile_id);
102 if (!g_browser_process->profile_manager()->IsValidProfile(profile))
103 return;
104
[email protected]e5775a52012-03-17 04:59:57105 ExtensionProcessManager* extension_process_manager =
[email protected]be93bba02012-10-24 16:44:03106 extensions::ExtensionSystem::Get(profile)->process_manager();
[email protected]e5775a52012-03-17 04:59:57107 // This may be NULL in unit tests.
108 if (!extension_process_manager)
109 return;
110
[email protected]6baff0b52012-03-06 01:30:18111 // Will be NULL if the request was not issued on behalf of a renderer (e.g. a
112 // system-level request).
[email protected]d3e898e2012-03-14 03:45:08113 RenderViewHost* render_view_host =
114 RenderViewHost::FromID(process_id, render_view_id);
[email protected]e5775a52012-03-17 04:59:57115 if (render_view_host) {
[email protected]6baff0b52012-03-06 01:30:18116 if (status == REQUEST_STARTED) {
[email protected]d3e898e2012-03-14 03:45:08117 extension_process_manager->OnNetworkRequestStarted(render_view_host);
[email protected]6baff0b52012-03-06 01:30:18118 } else if (status == REQUEST_DONE) {
[email protected]d3e898e2012-03-14 03:45:08119 extension_process_manager->OnNetworkRequestDone(render_view_host);
[email protected]6baff0b52012-03-06 01:30:18120 } else {
121 NOTREACHED();
122 }
123 }
124}
125
126void ForwardRequestStatus(
127 RequestStatus status, net::URLRequest* request, void* profile_id) {
[email protected]ea114722012-03-12 01:11:25128 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
129 if (!info)
130 return;
131
[email protected]6baff0b52012-03-06 01:30:18132 int process_id, render_view_id;
[email protected]ea114722012-03-12 01:11:25133 if (info->GetAssociatedRenderView(&process_id, &render_view_id)) {
[email protected]6baff0b52012-03-06 01:30:18134 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
135 base::Bind(&NotifyEPMRequestStatus,
136 status, profile_id, process_id, render_view_id));
137 }
138}
139
[email protected]7a299a92012-10-24 23:54:50140void UpdateContentLengthPrefs(int received_content_length,
141 int original_content_length) {
142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
143 DCHECK_GE(received_content_length, 0);
144 DCHECK_GE(original_content_length, 0);
145
146 PrefService* prefs = g_browser_process->local_state();
147
148 int64 total_received = prefs->GetInt64(prefs::kHttpReceivedContentLength);
149 int64 total_original = prefs->GetInt64(prefs::kHttpOriginalContentLength);
150 total_received += received_content_length;
151 total_original += original_content_length;
152 prefs->SetInt64(prefs::kHttpReceivedContentLength, total_received);
153 prefs->SetInt64(prefs::kHttpOriginalContentLength, total_original);
154}
155
156void StoreAccumulatedContentLength(int received_content_length,
157 int original_content_length) {
158 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
159 base::Bind(&UpdateContentLengthPrefs,
160 received_content_length, original_content_length));
161}
162
163void RecordContentLengthHistograms(
164 int64 received_content_length, int64 original_content_length) {
165#if defined(OS_ANDROID)
166 // Add the current resource to these histograms only when a valid
167 // X-Original-Content-Length header is present.
168 if (original_content_length >= 0) {
169 UMA_HISTOGRAM_COUNTS("Net.HttpContentLengthWithValidOCL",
170 received_content_length);
171 UMA_HISTOGRAM_COUNTS("Net.HttpOriginalContentLengthWithValidOCL",
172 original_content_length);
173 UMA_HISTOGRAM_COUNTS("Net.HttpContentLengthDifferenceWithValidOCL",
174 original_content_length - received_content_length);
175 } else {
176 // Presume the original content length is the same as the received content
177 // length if the X-Original-Content-Header is not present.
178 original_content_length = received_content_length;
179 }
180 UMA_HISTOGRAM_COUNTS("Net.HttpContentLength", received_content_length);
181 UMA_HISTOGRAM_COUNTS("Net.HttpOriginalContentLength",
182 original_content_length);
183 UMA_HISTOGRAM_COUNTS("Net.HttpContentLengthDifference",
184 original_content_length - received_content_length);
185#endif
186}
187
[email protected]d05ef99c2011-02-01 21:38:16188} // namespace
[email protected]ac039522010-06-15 16:39:44189
[email protected]0651b812011-02-24 00:22:50190ChromeNetworkDelegate::ChromeNetworkDelegate(
[email protected]5a38dfd2012-07-23 23:22:10191 extensions::EventRouterForwarder* event_router,
[email protected]c357acb42011-06-09 20:52:42192 ExtensionInfoMap* extension_info_map,
[email protected]6a5f77c32011-09-04 19:19:59193 const policy::URLBlacklistManager* url_blacklist_manager,
[email protected]e9c41d22012-08-17 00:08:15194 const ManagedModeURLFilter* managed_mode_url_filter,
[email protected]673514522011-07-13 18:17:18195 void* profile,
[email protected]9c8ae8c2012-03-09 13:13:35196 CookieSettings* cookie_settings,
[email protected]5a07c192012-07-30 20:18:22197 BooleanPrefMember* enable_referrers,
[email protected]9d8cfb682012-09-13 16:48:04198 BooleanPrefMember* enable_do_not_track,
[email protected]a9e0d1412012-08-20 22:13:01199 chrome_browser_net::LoadTimeStats* load_time_stats)
[email protected]3ce02412011-03-01 12:01:15200 : event_router_(event_router),
[email protected]673514522011-07-13 18:17:18201 profile_(profile),
[email protected]9c8ae8c2012-03-09 13:13:35202 cookie_settings_(cookie_settings),
[email protected]c357acb42011-06-09 20:52:42203 extension_info_map_(extension_info_map),
[email protected]6a5f77c32011-09-04 19:19:59204 enable_referrers_(enable_referrers),
[email protected]9d8cfb682012-09-13 16:48:04205 enable_do_not_track_(enable_do_not_track),
[email protected]5a07c192012-07-30 20:18:22206 url_blacklist_manager_(url_blacklist_manager),
[email protected]e9c41d22012-08-17 00:08:15207 managed_mode_url_filter_(managed_mode_url_filter),
[email protected]7a299a92012-10-24 23:54:50208 load_time_stats_(load_time_stats),
209 received_content_length_(0),
210 original_content_length_(0) {
[email protected]4b50cb52011-03-10 00:29:37211 DCHECK(event_router);
[email protected]0a8db0d2011-04-13 15:15:40212 DCHECK(enable_referrers);
[email protected]9c8ae8c2012-03-09 13:13:35213 DCHECK(!profile || cookie_settings);
[email protected]0651b812011-02-24 00:22:50214}
215
[email protected]ac039522010-06-15 16:39:44216ChromeNetworkDelegate::~ChromeNetworkDelegate() {}
217
[email protected]c4a7df82012-08-09 22:48:46218// static
[email protected]a1d4ab072012-06-07 13:21:15219void ChromeNetworkDelegate::NeverThrottleRequests() {
[email protected]c4a7df82012-08-09 22:48:46220 g_never_throttle_requests_ = true;
[email protected]a1d4ab072012-06-07 13:21:15221}
222
[email protected]0a8db0d2011-04-13 15:15:40223// static
[email protected]9d8cfb682012-09-13 16:48:04224void ChromeNetworkDelegate::InitializePrefsOnUIThread(
[email protected]0a8db0d2011-04-13 15:15:40225 BooleanPrefMember* enable_referrers,
[email protected]9d8cfb682012-09-13 16:48:04226 BooleanPrefMember* enable_do_not_track,
[email protected]0a8db0d2011-04-13 15:15:40227 PrefService* pref_service) {
228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
229 enable_referrers->Init(prefs::kEnableReferrers, pref_service, NULL);
[email protected]6a1c98e02012-10-24 21:49:43230 enable_referrers->MoveToThread(
231 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
[email protected]9d8cfb682012-09-13 16:48:04232 if (enable_do_not_track) {
233 enable_do_not_track->Init(prefs::kEnableDoNotTrack, pref_service, NULL);
[email protected]6a1c98e02012-10-24 21:49:43234 enable_do_not_track->MoveToThread(
235 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
[email protected]9d8cfb682012-09-13 16:48:04236 }
[email protected]0a8db0d2011-04-13 15:15:40237}
238
[email protected]4c219e22012-05-05 19:41:04239// static
240void ChromeNetworkDelegate::AllowAccessToAllFiles() {
241 g_allow_file_access_ = true;
242}
243
[email protected]7a299a92012-10-24 23:54:50244// static
245Value* ChromeNetworkDelegate::HistoricNetworkStatsInfoToValue() {
246 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
247 PrefService* prefs = g_browser_process->local_state();
248 int64 total_received = prefs->GetInt64(prefs::kHttpReceivedContentLength);
249 int64 total_original = prefs->GetInt64(prefs::kHttpOriginalContentLength);
250
251 DictionaryValue* dict = new DictionaryValue();
252 dict->SetInteger("historic_received_content_length", total_received);
253 dict->SetInteger("historic_original_content_length", total_original);
254 return dict;
255}
256
257Value* ChromeNetworkDelegate::SessionNetworkStatsInfoToValue() const {
258 DictionaryValue* dict = new DictionaryValue();
259 dict->SetInteger("session_received_content_length", received_content_length_);
260 dict->SetInteger("session_original_content_length", original_content_length_);
261 return dict;
262}
263
[email protected]4875ba12011-03-30 22:31:51264int ChromeNetworkDelegate::OnBeforeURLRequest(
[email protected]4c76d7c2011-04-15 19:14:12265 net::URLRequest* request,
[email protected]084262c2011-12-01 21:12:47266 const net::CompletionCallback& callback,
[email protected]4c76d7c2011-04-15 19:14:12267 GURL* new_url) {
[email protected]3e598ff12011-09-06 11:22:34268#if defined(ENABLE_CONFIGURATION_POLICY)
[email protected]6a5f77c32011-09-04 19:19:59269 // TODO(joaodasilva): This prevents extensions from seeing URLs that are
270 // blocked. However, an extension might redirect the request to another URL,
271 // which is not blocked.
272 if (url_blacklist_manager_ &&
273 url_blacklist_manager_->IsURLBlocked(request->url())) {
274 // URL access blocked by policy.
[email protected]6a5f77c32011-09-04 19:19:59275 request->net_log().AddEvent(
[email protected]2fa08912012-06-14 20:56:26276 net::NetLog::TYPE_CHROME_POLICY_ABORTED_REQUEST,
277 net::NetLog::StringCallback("url",
278 &request->url().possibly_invalid_spec()));
[email protected]6a5f77c32011-09-04 19:19:59279 return net::ERR_NETWORK_ACCESS_DENIED;
280 }
[email protected]3e598ff12011-09-06 11:22:34281#endif
[email protected]6a5f77c32011-09-04 19:19:59282
[email protected]e9c41d22012-08-17 00:08:15283#if !defined(OS_ANDROID)
284 if (managed_mode_url_filter_ &&
285 !managed_mode_url_filter_->IsURLWhitelisted(request->url())) {
286 // Block for now.
287 return net::ERR_NETWORK_ACCESS_DENIED;
288 }
289#endif
290
[email protected]6baff0b52012-03-06 01:30:18291 ForwardRequestStatus(REQUEST_STARTED, request, profile_);
292
[email protected]0a8db0d2011-04-13 15:15:40293 if (!enable_referrers_->GetValue())
294 request->set_referrer(std::string());
[email protected]9d8cfb682012-09-13 16:48:04295 if (enable_do_not_track_ && enable_do_not_track_->GetValue())
296 request->SetExtraRequestHeaderByName(kDNTHeader, "1", true /* override */);
[email protected]05cc4e72011-03-08 21:29:48297 return ExtensionWebRequestEventRouter::GetInstance()->OnBeforeRequest(
[email protected]673514522011-07-13 18:17:18298 profile_, extension_info_map_.get(), request, callback, new_url);
[email protected]d05ef99c2011-02-01 21:38:16299}
300
[email protected]4875ba12011-03-30 22:31:51301int ChromeNetworkDelegate::OnBeforeSendHeaders(
[email protected]636eccd2011-06-28 12:28:01302 net::URLRequest* request,
[email protected]084262c2011-12-01 21:12:47303 const net::CompletionCallback& callback,
[email protected]4c76d7c2011-04-15 19:14:12304 net::HttpRequestHeaders* headers) {
[email protected]4875ba12011-03-30 22:31:51305 return ExtensionWebRequestEventRouter::GetInstance()->OnBeforeSendHeaders(
[email protected]673514522011-07-13 18:17:18306 profile_, extension_info_map_.get(), request, callback, headers);
[email protected]ac039522010-06-15 16:39:44307}
[email protected]8202d0c2011-02-23 08:31:14308
[email protected]5796dc942011-07-14 19:26:10309void ChromeNetworkDelegate::OnSendHeaders(
310 net::URLRequest* request,
[email protected]783573b2011-05-13 11:05:15311 const net::HttpRequestHeaders& headers) {
[email protected]5796dc942011-07-14 19:26:10312 ExtensionWebRequestEventRouter::GetInstance()->OnSendHeaders(
313 profile_, extension_info_map_.get(), request, headers);
[email protected]82b42302011-04-20 16:28:16314}
315
[email protected]ea8141e2011-10-05 13:12:51316int ChromeNetworkDelegate::OnHeadersReceived(
317 net::URLRequest* request,
[email protected]084262c2011-12-01 21:12:47318 const net::CompletionCallback& callback,
[email protected]507af8f2012-10-20 00:42:32319 const net::HttpResponseHeaders* original_response_headers,
[email protected]ea8141e2011-10-05 13:12:51320 scoped_refptr<net::HttpResponseHeaders>* override_response_headers) {
321 return ExtensionWebRequestEventRouter::GetInstance()->OnHeadersReceived(
322 profile_, extension_info_map_.get(), request, callback,
323 original_response_headers, override_response_headers);
324}
325
[email protected]31b2e5f2011-04-20 16:58:32326void ChromeNetworkDelegate::OnBeforeRedirect(net::URLRequest* request,
327 const GURL& new_location) {
328 ExtensionWebRequestEventRouter::GetInstance()->OnBeforeRedirect(
[email protected]673514522011-07-13 18:17:18329 profile_, extension_info_map_.get(), request, new_location);
[email protected]31b2e5f2011-04-20 16:58:32330}
331
332
[email protected]8202d0c2011-02-23 08:31:14333void ChromeNetworkDelegate::OnResponseStarted(net::URLRequest* request) {
[email protected]62fecae2011-04-21 11:08:24334 ExtensionWebRequestEventRouter::GetInstance()->OnResponseStarted(
[email protected]673514522011-07-13 18:17:18335 profile_, extension_info_map_.get(), request);
336 ForwardProxyErrors(request, event_router_.get(), profile_);
[email protected]8202d0c2011-02-23 08:31:14337}
338
[email protected]8523ba52011-05-22 19:00:58339void ChromeNetworkDelegate::OnRawBytesRead(const net::URLRequest& request,
340 int bytes_read) {
[email protected]6f4b4b42012-08-27 21:59:07341 performance_monitor::PerformanceMonitor::GetInstance()->BytesReadOnIOThread(
342 request, bytes_read);
343
[email protected]44879ed2012-04-06 01:11:02344#if defined(ENABLE_TASK_MANAGER)
[email protected]8523ba52011-05-22 19:00:58345 TaskManager::GetInstance()->model()->NotifyBytesRead(request, bytes_read);
[email protected]44879ed2012-04-06 01:11:02346#endif // defined(ENABLE_TASK_MANAGER)
[email protected]8523ba52011-05-22 19:00:58347}
348
[email protected]9045b8822012-01-13 20:35:35349void ChromeNetworkDelegate::OnCompleted(net::URLRequest* request,
350 bool started) {
[email protected]2756a8e2012-09-07 18:24:29351 if (request->status().status() == net::URLRequestStatus::SUCCESS) {
[email protected]7a299a92012-10-24 23:54:50352 // For better accuracy, we use the actual bytes read instead of the length
353 // specified with the Content-Length header, which may be inaccurate,
354 // or missing, as is the case with chunked encoding.
355 int64 received_content_length = request->received_response_content_length();
356
357 // Only record for http or https urls.
358 bool is_http = request->url().SchemeIs("http");
359 bool is_https = request->url().SchemeIs("https");
360
361 if (!request->was_cached() && // Don't record cached content
362 received_content_length && // Zero-byte responses aren't useful.
363 (is_http || is_https)) { // Only record for HTTP or HTTPS urls.
364 int64 original_content_length =
365 request->response_info().headers->GetInt64HeaderValue(
366 "x-original-content-length");
367 // Since there was no indication of the original content length, presume
368 // it is no different from the number of bytes read.
369 int64 adjusted_original_content_length = original_content_length;
370 if (adjusted_original_content_length == -1)
371 adjusted_original_content_length = received_content_length;
372 AccumulateContentLength(received_content_length,
373 adjusted_original_content_length);
374 RecordContentLengthHistograms(received_content_length,
375 original_content_length);
376 DVLOG(2) << __FUNCTION__
377 << " received content length: " << received_content_length
378 << " original content length: " << original_content_length
379 << " url: " << request->url();
380 }
381
[email protected]48944382011-04-23 13:28:16382 bool is_redirect = request->response_headers() &&
383 net::HttpResponseHeaders::IsRedirectResponseCode(
384 request->response_headers()->response_code());
385 if (!is_redirect) {
386 ExtensionWebRequestEventRouter::GetInstance()->OnCompleted(
[email protected]673514522011-07-13 18:17:18387 profile_, extension_info_map_.get(), request);
[email protected]48944382011-04-23 13:28:16388 }
[email protected]a83dd332011-07-13 10:41:01389 } else if (request->status().status() == net::URLRequestStatus::FAILED ||
390 request->status().status() == net::URLRequestStatus::CANCELED) {
[email protected]05b6ab42011-04-23 13:46:04391 ExtensionWebRequestEventRouter::GetInstance()->OnErrorOccurred(
[email protected]9045b8822012-01-13 20:35:35392 profile_, extension_info_map_.get(), request, started);
[email protected]a83dd332011-07-13 10:41:01393 } else {
394 NOTREACHED();
[email protected]48944382011-04-23 13:28:16395 }
[email protected]673514522011-07-13 18:17:18396 ForwardProxyErrors(request, event_router_.get(), profile_);
[email protected]6baff0b52012-03-06 01:30:18397
398 ForwardRequestStatus(REQUEST_DONE, request, profile_);
[email protected]8202d0c2011-02-23 08:31:14399}
[email protected]4b50cb52011-03-10 00:29:37400
[email protected]4875ba12011-03-30 22:31:51401void ChromeNetworkDelegate::OnURLRequestDestroyed(net::URLRequest* request) {
402 ExtensionWebRequestEventRouter::GetInstance()->OnURLRequestDestroyed(
[email protected]673514522011-07-13 18:17:18403 profile_, request);
[email protected]16d5c72b2012-09-14 20:42:37404 if (load_time_stats_)
405 load_time_stats_->OnURLRequestDestroyed(*request);
[email protected]4875ba12011-03-30 22:31:51406}
407
[email protected]82a37672011-05-03 12:02:41408void ChromeNetworkDelegate::OnPACScriptError(int line_number,
409 const string16& error) {
[email protected]c454fe672012-03-12 21:18:01410 extensions::ProxyEventRouter::GetInstance()->OnPACScriptError(
[email protected]673514522011-07-13 18:17:18411 event_router_.get(), profile_, line_number, error);
[email protected]82a37672011-05-03 12:02:41412}
[email protected]7efc582d2011-08-03 20:46:35413
[email protected]c2911d72011-10-03 22:16:36414net::NetworkDelegate::AuthRequiredResponse
415ChromeNetworkDelegate::OnAuthRequired(
[email protected]7efc582d2011-08-03 20:46:35416 net::URLRequest* request,
[email protected]c2911d72011-10-03 22:16:36417 const net::AuthChallengeInfo& auth_info,
418 const AuthCallback& callback,
419 net::AuthCredentials* credentials) {
[email protected]90449ab2011-10-11 15:36:45420 return ExtensionWebRequestEventRouter::GetInstance()->OnAuthRequired(
421 profile_, extension_info_map_.get(), request, auth_info,
422 callback, credentials);
[email protected]7efc582d2011-08-03 20:46:35423}
[email protected]9c8ae8c2012-03-09 13:13:35424
[email protected]4c219e22012-05-05 19:41:04425bool ChromeNetworkDelegate::OnCanGetCookies(
426 const net::URLRequest& request,
[email protected]9c8ae8c2012-03-09 13:13:35427 const net::CookieList& cookie_list) {
428 // NULL during tests, or when we're running in the system context.
429 if (!cookie_settings_)
430 return true;
431
432 bool allow = cookie_settings_->IsReadingCookieAllowed(
[email protected]4c219e22012-05-05 19:41:04433 request.url(), request.first_party_for_cookies());
[email protected]9c8ae8c2012-03-09 13:13:35434
435 int render_process_id = -1;
436 int render_view_id = -1;
437 if (content::ResourceRequestInfo::GetRenderViewForRequest(
[email protected]4c219e22012-05-05 19:41:04438 &request, &render_process_id, &render_view_id)) {
[email protected]9c8ae8c2012-03-09 13:13:35439 BrowserThread::PostTask(
440 BrowserThread::UI, FROM_HERE,
441 base::Bind(&TabSpecificContentSettings::CookiesRead,
442 render_process_id, render_view_id,
[email protected]4c219e22012-05-05 19:41:04443 request.url(), request.first_party_for_cookies(),
[email protected]fd473d12012-04-05 11:38:43444 cookie_list, !allow));
[email protected]9c8ae8c2012-03-09 13:13:35445 }
446
447 return allow;
448}
449
[email protected]4c219e22012-05-05 19:41:04450bool ChromeNetworkDelegate::OnCanSetCookie(const net::URLRequest& request,
451 const std::string& cookie_line,
452 net::CookieOptions* options) {
[email protected]9c8ae8c2012-03-09 13:13:35453 // NULL during tests, or when we're running in the system context.
454 if (!cookie_settings_)
455 return true;
456
457 bool allow = cookie_settings_->IsSettingCookieAllowed(
[email protected]4c219e22012-05-05 19:41:04458 request.url(), request.first_party_for_cookies());
[email protected]9c8ae8c2012-03-09 13:13:35459
[email protected]9c8ae8c2012-03-09 13:13:35460 int render_process_id = -1;
461 int render_view_id = -1;
462 if (content::ResourceRequestInfo::GetRenderViewForRequest(
[email protected]4c219e22012-05-05 19:41:04463 &request, &render_process_id, &render_view_id)) {
[email protected]9c8ae8c2012-03-09 13:13:35464 BrowserThread::PostTask(
465 BrowserThread::UI, FROM_HERE,
466 base::Bind(&TabSpecificContentSettings::CookieChanged,
467 render_process_id, render_view_id,
[email protected]4c219e22012-05-05 19:41:04468 request.url(), request.first_party_for_cookies(),
[email protected]fd473d12012-04-05 11:38:43469 cookie_line, *options, !allow));
[email protected]9c8ae8c2012-03-09 13:13:35470 }
471
472 return allow;
473}
[email protected]4c219e22012-05-05 19:41:04474
475bool ChromeNetworkDelegate::OnCanAccessFile(const net::URLRequest& request,
476 const FilePath& path) const {
477 if (g_allow_file_access_)
478 return true;
479
[email protected]d8e4f132012-09-06 04:28:05480#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
481 return true;
482#else
[email protected]4c219e22012-05-05 19:41:04483#if defined(OS_CHROMEOS)
[email protected]d8e4f132012-09-06 04:28:05484 // If we're running Chrome for ChromeOS on Linux, we want to allow file
485 // access.
[email protected]288538482012-09-06 21:09:35486 if (!base::chromeos::IsRunningOnChromeOS() ||
487 CommandLine::ForCurrentProcess()->HasSwitch(switches::kTestType)) {
[email protected]d8e4f132012-09-06 04:28:05488 return true;
[email protected]288538482012-09-06 21:09:35489 }
[email protected]d8e4f132012-09-06 04:28:05490
491 // Use a whitelist to only allow access to files residing in the list of
492 // directories below.
[email protected]4c219e22012-05-05 19:41:04493 static const char* const kLocalAccessWhiteList[] = {
494 "/home/chronos/user/Downloads",
495 "/home/chronos/user/log",
496 "/media",
497 "/opt/oem",
498 "/usr/share/chromeos-assets",
499 "/tmp",
500 "/var/log",
501 };
[email protected]d8e4f132012-09-06 04:28:05502#elif defined(OS_ANDROID)
503 // Access to files in external storage is allowed.
504 FilePath external_storage_path;
505 PathService::Get(base::DIR_ANDROID_EXTERNAL_STORAGE, &external_storage_path);
506 if (external_storage_path.IsParent(path))
[email protected]4c219e22012-05-05 19:41:04507 return true;
508
[email protected]d8e4f132012-09-06 04:28:05509 // Whitelist of other allowed directories.
510 static const char* const kLocalAccessWhiteList[] = {
511 "/sdcard",
512 "/mnt/sdcard",
513 };
514#endif
515
[email protected]4c219e22012-05-05 19:41:04516 for (size_t i = 0; i < arraysize(kLocalAccessWhiteList); ++i) {
517 const FilePath white_listed_path(kLocalAccessWhiteList[i]);
518 // FilePath::operator== should probably handle trailing separators.
519 if (white_listed_path == path.StripTrailingSeparators() ||
520 white_listed_path.IsParent(path)) {
521 return true;
522 }
523 }
[email protected]d8e4f132012-09-06 04:28:05524
[email protected]288538482012-09-06 21:09:35525 DVLOG(1) << "File access denied - " << path.value().c_str();
[email protected]4c219e22012-05-05 19:41:04526 return false;
[email protected]d8e4f132012-09-06 04:28:05527#endif // !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
[email protected]4c219e22012-05-05 19:41:04528}
[email protected]a1d4ab072012-06-07 13:21:15529
530bool ChromeNetworkDelegate::OnCanThrottleRequest(
531 const net::URLRequest& request) const {
[email protected]c4a7df82012-08-09 22:48:46532 if (g_never_throttle_requests_) {
[email protected]a1d4ab072012-06-07 13:21:15533 return false;
534 }
535
[email protected]c4a7df82012-08-09 22:48:46536 return request.first_party_for_cookies().scheme() ==
[email protected]a1d4ab072012-06-07 13:21:15537 chrome::kExtensionScheme;
538}
[email protected]aa28181e2012-06-13 00:53:58539
540int ChromeNetworkDelegate::OnBeforeSocketStreamConnect(
541 net::SocketStream* socket,
542 const net::CompletionCallback& callback) {
543#if defined(ENABLE_CONFIGURATION_POLICY)
544 if (url_blacklist_manager_ &&
545 url_blacklist_manager_->IsURLBlocked(socket->url())) {
546 // URL access blocked by policy.
[email protected]aa28181e2012-06-13 00:53:58547 socket->net_log()->AddEvent(
[email protected]2fa08912012-06-14 20:56:26548 net::NetLog::TYPE_CHROME_POLICY_ABORTED_REQUEST,
549 net::NetLog::StringCallback("url",
550 &socket->url().possibly_invalid_spec()));
[email protected]aa28181e2012-06-13 00:53:58551 return net::ERR_NETWORK_ACCESS_DENIED;
552 }
553#endif
554 return net::OK;
555}
[email protected]5a07c192012-07-30 20:18:22556
[email protected]a9e0d1412012-08-20 22:13:01557void ChromeNetworkDelegate::OnRequestWaitStateChange(
[email protected]5a07c192012-07-30 20:18:22558 const net::URLRequest& request,
[email protected]a9e0d1412012-08-20 22:13:01559 RequestWaitState state) {
560 if (load_time_stats_)
561 load_time_stats_->OnRequestWaitStateChange(request, state);
[email protected]5a07c192012-07-30 20:18:22562}
[email protected]7a299a92012-10-24 23:54:50563
564void ChromeNetworkDelegate::AccumulateContentLength(
565 int64 received_content_length, int64 original_content_length) {
566 DCHECK_GE(received_content_length, 0);
567 DCHECK_GE(original_content_length, 0);
568 StoreAccumulatedContentLength(received_content_length,
569 original_content_length);
570 received_content_length_ += received_content_length;
571 original_content_length_ += original_content_length;
572}