blob: cc87909b0cd04a57aea64fb1ad96f06d167f1a36 [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
7#include "base/logging.h"
[email protected]6baff0b52012-03-06 01:30:188#include "chrome/browser/browser_process.h"
[email protected]9c8ae8c2012-03-09 13:13:359#include "chrome/browser/content_settings/cookie_settings.h"
10#include "chrome/browser/content_settings/tab_specific_content_settings.h"
[email protected]8523ba52011-05-22 19:00:5811#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
[email protected]aa84a7e2012-03-15 21:29:0612#include "chrome/browser/extensions/api/proxy/proxy_api.h"
[email protected]2b33dcd02012-03-18 01:34:1613#include "chrome/browser/extensions/api/web_request/web_request_api.h"
[email protected]3ce02412011-03-01 12:01:1514#include "chrome/browser/extensions/extension_event_router_forwarder.h"
[email protected]c357acb42011-06-09 20:52:4215#include "chrome/browser/extensions/extension_info_map.h"
[email protected]6baff0b52012-03-06 01:30:1816#include "chrome/browser/extensions/extension_process_manager.h"
[email protected]0a8db0d2011-04-13 15:15:4017#include "chrome/browser/prefs/pref_member.h"
[email protected]6baff0b52012-03-06 01:30:1818#include "chrome/browser/profiles/profile_manager.h"
[email protected]8523ba52011-05-22 19:00:5819#include "chrome/browser/task_manager/task_manager.h"
[email protected]0a8db0d2011-04-13 15:15:4020#include "chrome/common/pref_names.h"
[email protected]a1d4ab072012-06-07 13:21:1521#include "chrome/common/url_constants.h"
[email protected]c38831a12011-10-28 12:44:4922#include "content/public/browser/browser_thread.h"
[email protected]9c1662b2012-03-06 15:44:3323#include "content/public/browser/render_view_host.h"
[email protected]9c8ae8c2012-03-09 13:13:3524#include "content/public/browser/resource_request_info.h"
[email protected]82b42302011-04-20 16:28:1625#include "net/base/host_port_pair.h"
[email protected]8202d0c2011-02-23 08:31:1426#include "net/base/net_errors.h"
[email protected]6a5f77c32011-09-04 19:19:5927#include "net/base/net_log.h"
[email protected]aa84a7e2012-03-15 21:29:0628#include "net/cookies/cookie_monster.h"
[email protected]ac039522010-06-15 16:39:4429#include "net/http/http_request_headers.h"
[email protected]48944382011-04-23 13:28:1630#include "net/http/http_response_headers.h"
[email protected]aa28181e2012-06-13 00:53:5831#include "net/socket_stream/socket_stream.h"
[email protected]d05ef99c2011-02-01 21:38:1632#include "net/url_request/url_request.h"
33
[email protected]4c219e22012-05-05 19:41:0434#if defined(OS_CHROMEOS)
35#include "base/chromeos/chromeos_version.h"
36#endif
37
[email protected]3e598ff12011-09-06 11:22:3438#if defined(ENABLE_CONFIGURATION_POLICY)
39#include "chrome/browser/policy/url_blacklist_manager.h"
40#endif
41
[email protected]631bb742011-11-02 11:29:3942using content::BrowserThread;
[email protected]eaabba22012-03-07 15:02:1143using content::RenderViewHost;
[email protected]ea114722012-03-12 01:11:2544using content::ResourceRequestInfo;
[email protected]631bb742011-11-02 11:29:3945
[email protected]4c219e22012-05-05 19:41:0446// By default we don't allow access to all file:// urls on ChromeOS but we do on
47// other platforms.
48#if defined(OS_CHROMEOS)
49bool ChromeNetworkDelegate::g_allow_file_access_ = false;
50#else
51bool ChromeNetworkDelegate::g_allow_file_access_ = true;
52#endif
53
[email protected]d05ef99c2011-02-01 21:38:1654namespace {
55
[email protected]8202d0c2011-02-23 08:31:1456// If the |request| failed due to problems with a proxy, forward the error to
57// the proxy extension API.
[email protected]0651b812011-02-24 00:22:5058void ForwardProxyErrors(net::URLRequest* request,
[email protected]3ce02412011-03-01 12:01:1559 ExtensionEventRouterForwarder* event_router,
[email protected]673514522011-07-13 18:17:1860 void* profile) {
[email protected]8202d0c2011-02-23 08:31:1461 if (request->status().status() == net::URLRequestStatus::FAILED) {
[email protected]d0cc35b2011-09-08 12:02:0562 switch (request->status().error()) {
[email protected]8202d0c2011-02-23 08:31:1463 case net::ERR_PROXY_AUTH_UNSUPPORTED:
64 case net::ERR_PROXY_CONNECTION_FAILED:
65 case net::ERR_TUNNEL_CONNECTION_FAILED:
[email protected]c454fe672012-03-12 21:18:0166 extensions::ProxyEventRouter::GetInstance()->OnProxyError(
[email protected]d0cc35b2011-09-08 12:02:0567 event_router, profile, request->status().error());
[email protected]8202d0c2011-02-23 08:31:1468 }
69 }
70}
71
[email protected]6baff0b52012-03-06 01:30:1872enum RequestStatus { REQUEST_STARTED, REQUEST_DONE };
73
74// Notifies the ExtensionProcessManager that a request has started or stopped
75// for a particular RenderView.
76void NotifyEPMRequestStatus(RequestStatus status,
77 void* profile_id,
78 int process_id,
79 int render_view_id) {
80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
81 Profile* profile = reinterpret_cast<Profile*>(profile_id);
82 if (!g_browser_process->profile_manager()->IsValidProfile(profile))
83 return;
84
[email protected]e5775a52012-03-17 04:59:5785 ExtensionProcessManager* extension_process_manager =
86 profile->GetExtensionProcessManager();
87 // This may be NULL in unit tests.
88 if (!extension_process_manager)
89 return;
90
[email protected]6baff0b52012-03-06 01:30:1891 // Will be NULL if the request was not issued on behalf of a renderer (e.g. a
92 // system-level request).
[email protected]d3e898e2012-03-14 03:45:0893 RenderViewHost* render_view_host =
94 RenderViewHost::FromID(process_id, render_view_id);
[email protected]e5775a52012-03-17 04:59:5795 if (render_view_host) {
[email protected]6baff0b52012-03-06 01:30:1896 if (status == REQUEST_STARTED) {
[email protected]d3e898e2012-03-14 03:45:0897 extension_process_manager->OnNetworkRequestStarted(render_view_host);
[email protected]6baff0b52012-03-06 01:30:1898 } else if (status == REQUEST_DONE) {
[email protected]d3e898e2012-03-14 03:45:0899 extension_process_manager->OnNetworkRequestDone(render_view_host);
[email protected]6baff0b52012-03-06 01:30:18100 } else {
101 NOTREACHED();
102 }
103 }
104}
105
106void ForwardRequestStatus(
107 RequestStatus status, net::URLRequest* request, void* profile_id) {
[email protected]ea114722012-03-12 01:11:25108 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
109 if (!info)
110 return;
111
[email protected]6baff0b52012-03-06 01:30:18112 int process_id, render_view_id;
[email protected]ea114722012-03-12 01:11:25113 if (info->GetAssociatedRenderView(&process_id, &render_view_id)) {
[email protected]6baff0b52012-03-06 01:30:18114 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
115 base::Bind(&NotifyEPMRequestStatus,
116 status, profile_id, process_id, render_view_id));
117 }
118}
119
[email protected]d05ef99c2011-02-01 21:38:16120} // namespace
[email protected]ac039522010-06-15 16:39:44121
[email protected]0651b812011-02-24 00:22:50122ChromeNetworkDelegate::ChromeNetworkDelegate(
[email protected]3ce02412011-03-01 12:01:15123 ExtensionEventRouterForwarder* event_router,
[email protected]c357acb42011-06-09 20:52:42124 ExtensionInfoMap* extension_info_map,
[email protected]6a5f77c32011-09-04 19:19:59125 const policy::URLBlacklistManager* url_blacklist_manager,
[email protected]673514522011-07-13 18:17:18126 void* profile,
[email protected]9c8ae8c2012-03-09 13:13:35127 CookieSettings* cookie_settings,
[email protected]a8c1e7452011-05-14 06:17:07128 BooleanPrefMember* enable_referrers)
[email protected]3ce02412011-03-01 12:01:15129 : event_router_(event_router),
[email protected]673514522011-07-13 18:17:18130 profile_(profile),
[email protected]9c8ae8c2012-03-09 13:13:35131 cookie_settings_(cookie_settings),
[email protected]c357acb42011-06-09 20:52:42132 extension_info_map_(extension_info_map),
[email protected]6a5f77c32011-09-04 19:19:59133 enable_referrers_(enable_referrers),
[email protected]a1d4ab072012-06-07 13:21:15134 never_throttle_requests_(false),
[email protected]6a5f77c32011-09-04 19:19:59135 url_blacklist_manager_(url_blacklist_manager) {
[email protected]4b50cb52011-03-10 00:29:37136 DCHECK(event_router);
[email protected]0a8db0d2011-04-13 15:15:40137 DCHECK(enable_referrers);
[email protected]9c8ae8c2012-03-09 13:13:35138 DCHECK(!profile || cookie_settings);
[email protected]0651b812011-02-24 00:22:50139}
140
[email protected]ac039522010-06-15 16:39:44141ChromeNetworkDelegate::~ChromeNetworkDelegate() {}
142
[email protected]a1d4ab072012-06-07 13:21:15143void ChromeNetworkDelegate::NeverThrottleRequests() {
144 never_throttle_requests_ = true;
145}
146
[email protected]0a8db0d2011-04-13 15:15:40147// static
148void ChromeNetworkDelegate::InitializeReferrersEnabled(
149 BooleanPrefMember* enable_referrers,
150 PrefService* pref_service) {
151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
152 enable_referrers->Init(prefs::kEnableReferrers, pref_service, NULL);
153 enable_referrers->MoveToThread(BrowserThread::IO);
154}
155
[email protected]4c219e22012-05-05 19:41:04156// static
157void ChromeNetworkDelegate::AllowAccessToAllFiles() {
158 g_allow_file_access_ = true;
159}
160
[email protected]4875ba12011-03-30 22:31:51161int ChromeNetworkDelegate::OnBeforeURLRequest(
[email protected]4c76d7c2011-04-15 19:14:12162 net::URLRequest* request,
[email protected]084262c2011-12-01 21:12:47163 const net::CompletionCallback& callback,
[email protected]4c76d7c2011-04-15 19:14:12164 GURL* new_url) {
[email protected]3e598ff12011-09-06 11:22:34165#if defined(ENABLE_CONFIGURATION_POLICY)
[email protected]6a5f77c32011-09-04 19:19:59166 // TODO(joaodasilva): This prevents extensions from seeing URLs that are
167 // blocked. However, an extension might redirect the request to another URL,
168 // which is not blocked.
169 if (url_blacklist_manager_ &&
170 url_blacklist_manager_->IsURLBlocked(request->url())) {
171 // URL access blocked by policy.
[email protected]6a5f77c32011-09-04 19:19:59172 request->net_log().AddEvent(
[email protected]2fa08912012-06-14 20:56:26173 net::NetLog::TYPE_CHROME_POLICY_ABORTED_REQUEST,
174 net::NetLog::StringCallback("url",
175 &request->url().possibly_invalid_spec()));
[email protected]6a5f77c32011-09-04 19:19:59176 return net::ERR_NETWORK_ACCESS_DENIED;
177 }
[email protected]3e598ff12011-09-06 11:22:34178#endif
[email protected]6a5f77c32011-09-04 19:19:59179
[email protected]6baff0b52012-03-06 01:30:18180 ForwardRequestStatus(REQUEST_STARTED, request, profile_);
181
[email protected]0a8db0d2011-04-13 15:15:40182 if (!enable_referrers_->GetValue())
183 request->set_referrer(std::string());
[email protected]05cc4e72011-03-08 21:29:48184 return ExtensionWebRequestEventRouter::GetInstance()->OnBeforeRequest(
[email protected]673514522011-07-13 18:17:18185 profile_, extension_info_map_.get(), request, callback, new_url);
[email protected]d05ef99c2011-02-01 21:38:16186}
187
[email protected]4875ba12011-03-30 22:31:51188int ChromeNetworkDelegate::OnBeforeSendHeaders(
[email protected]636eccd2011-06-28 12:28:01189 net::URLRequest* request,
[email protected]084262c2011-12-01 21:12:47190 const net::CompletionCallback& callback,
[email protected]4c76d7c2011-04-15 19:14:12191 net::HttpRequestHeaders* headers) {
[email protected]4875ba12011-03-30 22:31:51192 return ExtensionWebRequestEventRouter::GetInstance()->OnBeforeSendHeaders(
[email protected]673514522011-07-13 18:17:18193 profile_, extension_info_map_.get(), request, callback, headers);
[email protected]ac039522010-06-15 16:39:44194}
[email protected]8202d0c2011-02-23 08:31:14195
[email protected]5796dc942011-07-14 19:26:10196void ChromeNetworkDelegate::OnSendHeaders(
197 net::URLRequest* request,
[email protected]783573b2011-05-13 11:05:15198 const net::HttpRequestHeaders& headers) {
[email protected]5796dc942011-07-14 19:26:10199 ExtensionWebRequestEventRouter::GetInstance()->OnSendHeaders(
200 profile_, extension_info_map_.get(), request, headers);
[email protected]82b42302011-04-20 16:28:16201}
202
[email protected]ea8141e2011-10-05 13:12:51203int ChromeNetworkDelegate::OnHeadersReceived(
204 net::URLRequest* request,
[email protected]084262c2011-12-01 21:12:47205 const net::CompletionCallback& callback,
[email protected]ea8141e2011-10-05 13:12:51206 net::HttpResponseHeaders* original_response_headers,
207 scoped_refptr<net::HttpResponseHeaders>* override_response_headers) {
208 return ExtensionWebRequestEventRouter::GetInstance()->OnHeadersReceived(
209 profile_, extension_info_map_.get(), request, callback,
210 original_response_headers, override_response_headers);
211}
212
[email protected]31b2e5f2011-04-20 16:58:32213void ChromeNetworkDelegate::OnBeforeRedirect(net::URLRequest* request,
214 const GURL& new_location) {
215 ExtensionWebRequestEventRouter::GetInstance()->OnBeforeRedirect(
[email protected]673514522011-07-13 18:17:18216 profile_, extension_info_map_.get(), request, new_location);
[email protected]31b2e5f2011-04-20 16:58:32217}
218
219
[email protected]8202d0c2011-02-23 08:31:14220void ChromeNetworkDelegate::OnResponseStarted(net::URLRequest* request) {
[email protected]62fecae2011-04-21 11:08:24221 ExtensionWebRequestEventRouter::GetInstance()->OnResponseStarted(
[email protected]673514522011-07-13 18:17:18222 profile_, extension_info_map_.get(), request);
223 ForwardProxyErrors(request, event_router_.get(), profile_);
[email protected]8202d0c2011-02-23 08:31:14224}
225
[email protected]8523ba52011-05-22 19:00:58226void ChromeNetworkDelegate::OnRawBytesRead(const net::URLRequest& request,
227 int bytes_read) {
[email protected]44879ed2012-04-06 01:11:02228#if defined(ENABLE_TASK_MANAGER)
[email protected]8523ba52011-05-22 19:00:58229 TaskManager::GetInstance()->model()->NotifyBytesRead(request, bytes_read);
[email protected]44879ed2012-04-06 01:11:02230#endif // defined(ENABLE_TASK_MANAGER)
[email protected]8523ba52011-05-22 19:00:58231}
232
[email protected]9045b8822012-01-13 20:35:35233void ChromeNetworkDelegate::OnCompleted(net::URLRequest* request,
234 bool started) {
[email protected]a83dd332011-07-13 10:41:01235 if (request->status().status() == net::URLRequestStatus::SUCCESS ||
236 request->status().status() == net::URLRequestStatus::HANDLED_EXTERNALLY) {
[email protected]48944382011-04-23 13:28:16237 bool is_redirect = request->response_headers() &&
238 net::HttpResponseHeaders::IsRedirectResponseCode(
239 request->response_headers()->response_code());
240 if (!is_redirect) {
241 ExtensionWebRequestEventRouter::GetInstance()->OnCompleted(
[email protected]673514522011-07-13 18:17:18242 profile_, extension_info_map_.get(), request);
[email protected]48944382011-04-23 13:28:16243 }
[email protected]a83dd332011-07-13 10:41:01244 } else if (request->status().status() == net::URLRequestStatus::FAILED ||
245 request->status().status() == net::URLRequestStatus::CANCELED) {
[email protected]05b6ab42011-04-23 13:46:04246 ExtensionWebRequestEventRouter::GetInstance()->OnErrorOccurred(
[email protected]9045b8822012-01-13 20:35:35247 profile_, extension_info_map_.get(), request, started);
[email protected]a83dd332011-07-13 10:41:01248 } else {
249 NOTREACHED();
[email protected]48944382011-04-23 13:28:16250 }
[email protected]673514522011-07-13 18:17:18251 ForwardProxyErrors(request, event_router_.get(), profile_);
[email protected]6baff0b52012-03-06 01:30:18252
253 ForwardRequestStatus(REQUEST_DONE, request, profile_);
[email protected]8202d0c2011-02-23 08:31:14254}
[email protected]4b50cb52011-03-10 00:29:37255
[email protected]4875ba12011-03-30 22:31:51256void ChromeNetworkDelegate::OnURLRequestDestroyed(net::URLRequest* request) {
257 ExtensionWebRequestEventRouter::GetInstance()->OnURLRequestDestroyed(
[email protected]673514522011-07-13 18:17:18258 profile_, request);
[email protected]4875ba12011-03-30 22:31:51259}
260
[email protected]82a37672011-05-03 12:02:41261void ChromeNetworkDelegate::OnPACScriptError(int line_number,
262 const string16& error) {
[email protected]c454fe672012-03-12 21:18:01263 extensions::ProxyEventRouter::GetInstance()->OnPACScriptError(
[email protected]673514522011-07-13 18:17:18264 event_router_.get(), profile_, line_number, error);
[email protected]82a37672011-05-03 12:02:41265}
[email protected]7efc582d2011-08-03 20:46:35266
[email protected]c2911d72011-10-03 22:16:36267net::NetworkDelegate::AuthRequiredResponse
268ChromeNetworkDelegate::OnAuthRequired(
[email protected]7efc582d2011-08-03 20:46:35269 net::URLRequest* request,
[email protected]c2911d72011-10-03 22:16:36270 const net::AuthChallengeInfo& auth_info,
271 const AuthCallback& callback,
272 net::AuthCredentials* credentials) {
[email protected]90449ab2011-10-11 15:36:45273 return ExtensionWebRequestEventRouter::GetInstance()->OnAuthRequired(
274 profile_, extension_info_map_.get(), request, auth_info,
275 callback, credentials);
[email protected]7efc582d2011-08-03 20:46:35276}
[email protected]9c8ae8c2012-03-09 13:13:35277
[email protected]4c219e22012-05-05 19:41:04278bool ChromeNetworkDelegate::OnCanGetCookies(
279 const net::URLRequest& request,
[email protected]9c8ae8c2012-03-09 13:13:35280 const net::CookieList& cookie_list) {
281 // NULL during tests, or when we're running in the system context.
282 if (!cookie_settings_)
283 return true;
284
285 bool allow = cookie_settings_->IsReadingCookieAllowed(
[email protected]4c219e22012-05-05 19:41:04286 request.url(), request.first_party_for_cookies());
[email protected]9c8ae8c2012-03-09 13:13:35287
288 int render_process_id = -1;
289 int render_view_id = -1;
290 if (content::ResourceRequestInfo::GetRenderViewForRequest(
[email protected]4c219e22012-05-05 19:41:04291 &request, &render_process_id, &render_view_id)) {
[email protected]9c8ae8c2012-03-09 13:13:35292 BrowserThread::PostTask(
293 BrowserThread::UI, FROM_HERE,
294 base::Bind(&TabSpecificContentSettings::CookiesRead,
295 render_process_id, render_view_id,
[email protected]4c219e22012-05-05 19:41:04296 request.url(), request.first_party_for_cookies(),
[email protected]fd473d12012-04-05 11:38:43297 cookie_list, !allow));
[email protected]9c8ae8c2012-03-09 13:13:35298 }
299
300 return allow;
301}
302
[email protected]4c219e22012-05-05 19:41:04303bool ChromeNetworkDelegate::OnCanSetCookie(const net::URLRequest& request,
304 const std::string& cookie_line,
305 net::CookieOptions* options) {
[email protected]9c8ae8c2012-03-09 13:13:35306 // NULL during tests, or when we're running in the system context.
307 if (!cookie_settings_)
308 return true;
309
310 bool allow = cookie_settings_->IsSettingCookieAllowed(
[email protected]4c219e22012-05-05 19:41:04311 request.url(), request.first_party_for_cookies());
[email protected]9c8ae8c2012-03-09 13:13:35312
[email protected]9c8ae8c2012-03-09 13:13:35313 int render_process_id = -1;
314 int render_view_id = -1;
315 if (content::ResourceRequestInfo::GetRenderViewForRequest(
[email protected]4c219e22012-05-05 19:41:04316 &request, &render_process_id, &render_view_id)) {
[email protected]9c8ae8c2012-03-09 13:13:35317 BrowserThread::PostTask(
318 BrowserThread::UI, FROM_HERE,
319 base::Bind(&TabSpecificContentSettings::CookieChanged,
320 render_process_id, render_view_id,
[email protected]4c219e22012-05-05 19:41:04321 request.url(), request.first_party_for_cookies(),
[email protected]fd473d12012-04-05 11:38:43322 cookie_line, *options, !allow));
[email protected]9c8ae8c2012-03-09 13:13:35323 }
324
325 return allow;
326}
[email protected]4c219e22012-05-05 19:41:04327
328bool ChromeNetworkDelegate::OnCanAccessFile(const net::URLRequest& request,
329 const FilePath& path) const {
330 if (g_allow_file_access_)
331 return true;
332
333#if defined(OS_CHROMEOS)
334 // ChromeOS uses a whitelist to only allow access to files residing in the
335 // list of directories below.
336 static const char* const kLocalAccessWhiteList[] = {
337 "/home/chronos/user/Downloads",
338 "/home/chronos/user/log",
339 "/media",
340 "/opt/oem",
341 "/usr/share/chromeos-assets",
342 "/tmp",
343 "/var/log",
344 };
345
346 // If we're running Chrome for ChromeOS on Linux, we want to allow file
347 // access.
348 if (!base::chromeos::IsRunningOnChromeOS())
349 return true;
350
351 for (size_t i = 0; i < arraysize(kLocalAccessWhiteList); ++i) {
352 const FilePath white_listed_path(kLocalAccessWhiteList[i]);
353 // FilePath::operator== should probably handle trailing separators.
354 if (white_listed_path == path.StripTrailingSeparators() ||
355 white_listed_path.IsParent(path)) {
356 return true;
357 }
358 }
359 return false;
360#else
361 return true;
362#endif // defined(OS_CHROMEOS)
363}
[email protected]a1d4ab072012-06-07 13:21:15364
365bool ChromeNetworkDelegate::OnCanThrottleRequest(
366 const net::URLRequest& request) const {
367 if (never_throttle_requests_) {
368 return false;
369 }
370
371 return request.first_party_for_cookies().scheme() !=
372 chrome::kExtensionScheme;
373}
[email protected]aa28181e2012-06-13 00:53:58374
375int ChromeNetworkDelegate::OnBeforeSocketStreamConnect(
376 net::SocketStream* socket,
377 const net::CompletionCallback& callback) {
378#if defined(ENABLE_CONFIGURATION_POLICY)
379 if (url_blacklist_manager_ &&
380 url_blacklist_manager_->IsURLBlocked(socket->url())) {
381 // URL access blocked by policy.
[email protected]aa28181e2012-06-13 00:53:58382 socket->net_log()->AddEvent(
[email protected]2fa08912012-06-14 20:56:26383 net::NetLog::TYPE_CHROME_POLICY_ABORTED_REQUEST,
384 net::NetLog::StringCallback("url",
385 &socket->url().possibly_invalid_spec()));
[email protected]aa28181e2012-06-13 00:53:58386 return net::ERR_NETWORK_ACCESS_DENIED;
387 }
388#endif
389 return net::OK;
390}