blob: c0e350f94aef111d1d97fae8105f6f6a0755fee8 [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]8523ba52011-05-22 19:00:589#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
[email protected]6e672df2012-01-25 10:39:4710#include "chrome/browser/extensions/api/webrequest/webrequest_api.h"
[email protected]3ce02412011-03-01 12:01:1511#include "chrome/browser/extensions/extension_event_router_forwarder.h"
[email protected]c357acb42011-06-09 20:52:4212#include "chrome/browser/extensions/extension_info_map.h"
[email protected]6baff0b52012-03-06 01:30:1813#include "chrome/browser/extensions/extension_process_manager.h"
[email protected]8202d0c2011-02-23 08:31:1414#include "chrome/browser/extensions/extension_proxy_api.h"
[email protected]0a8db0d2011-04-13 15:15:4015#include "chrome/browser/prefs/pref_member.h"
[email protected]6baff0b52012-03-06 01:30:1816#include "chrome/browser/profiles/profile_manager.h"
[email protected]8523ba52011-05-22 19:00:5817#include "chrome/browser/task_manager/task_manager.h"
[email protected]0a8db0d2011-04-13 15:15:4018#include "chrome/common/pref_names.h"
[email protected]6baff0b52012-03-06 01:30:1819#include "content/browser/renderer_host/resource_dispatcher_host.h"
[email protected]c38831a12011-10-28 12:44:4920#include "content/public/browser/browser_thread.h"
[email protected]9c1662b2012-03-06 15:44:3321#include "content/public/browser/render_view_host.h"
[email protected]82b42302011-04-20 16:28:1622#include "net/base/host_port_pair.h"
[email protected]8202d0c2011-02-23 08:31:1423#include "net/base/net_errors.h"
[email protected]6a5f77c32011-09-04 19:19:5924#include "net/base/net_log.h"
[email protected]ac039522010-06-15 16:39:4425#include "net/http/http_request_headers.h"
[email protected]48944382011-04-23 13:28:1626#include "net/http/http_response_headers.h"
[email protected]d05ef99c2011-02-01 21:38:1627#include "net/url_request/url_request.h"
28
[email protected]3e598ff12011-09-06 11:22:3429#if defined(ENABLE_CONFIGURATION_POLICY)
30#include "chrome/browser/policy/url_blacklist_manager.h"
31#endif
32
[email protected]631bb742011-11-02 11:29:3933using content::BrowserThread;
[email protected]eaabba22012-03-07 15:02:1134using content::RenderViewHost;
[email protected]631bb742011-11-02 11:29:3935
[email protected]d05ef99c2011-02-01 21:38:1636namespace {
37
[email protected]8202d0c2011-02-23 08:31:1438// If the |request| failed due to problems with a proxy, forward the error to
39// the proxy extension API.
[email protected]0651b812011-02-24 00:22:5040void ForwardProxyErrors(net::URLRequest* request,
[email protected]3ce02412011-03-01 12:01:1541 ExtensionEventRouterForwarder* event_router,
[email protected]673514522011-07-13 18:17:1842 void* profile) {
[email protected]8202d0c2011-02-23 08:31:1443 if (request->status().status() == net::URLRequestStatus::FAILED) {
[email protected]d0cc35b2011-09-08 12:02:0544 switch (request->status().error()) {
[email protected]8202d0c2011-02-23 08:31:1445 case net::ERR_PROXY_AUTH_UNSUPPORTED:
46 case net::ERR_PROXY_CONNECTION_FAILED:
47 case net::ERR_TUNNEL_CONNECTION_FAILED:
48 ExtensionProxyEventRouter::GetInstance()->OnProxyError(
[email protected]d0cc35b2011-09-08 12:02:0549 event_router, profile, request->status().error());
[email protected]8202d0c2011-02-23 08:31:1450 }
51 }
52}
53
[email protected]6baff0b52012-03-06 01:30:1854enum RequestStatus { REQUEST_STARTED, REQUEST_DONE };
55
56// Notifies the ExtensionProcessManager that a request has started or stopped
57// for a particular RenderView.
58void NotifyEPMRequestStatus(RequestStatus status,
59 void* profile_id,
60 int process_id,
61 int render_view_id) {
62 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
63 Profile* profile = reinterpret_cast<Profile*>(profile_id);
64 if (!g_browser_process->profile_manager()->IsValidProfile(profile))
65 return;
66
67 RenderViewHost* render_view_host =
68 RenderViewHost::FromID(process_id, render_view_id);
69 // Will be NULL if the request was not issued on behalf of a renderer (e.g. a
70 // system-level request).
71 if (render_view_host) {
72 if (status == REQUEST_STARTED) {
73 profile->GetExtensionProcessManager()->OnNetworkRequestStarted(
74 render_view_host);
75 } else if (status == REQUEST_DONE) {
76 profile->GetExtensionProcessManager()->OnNetworkRequestDone(
77 render_view_host);
78 } else {
79 NOTREACHED();
80 }
81 }
82}
83
84void ForwardRequestStatus(
85 RequestStatus status, net::URLRequest* request, void* profile_id) {
86 int process_id, render_view_id;
87 if (ResourceDispatcherHost::RenderViewForRequest(
88 request, &process_id, &render_view_id)) {
89 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
90 base::Bind(&NotifyEPMRequestStatus,
91 status, profile_id, process_id, render_view_id));
92 }
93}
94
[email protected]d05ef99c2011-02-01 21:38:1695} // namespace
[email protected]ac039522010-06-15 16:39:4496
[email protected]0651b812011-02-24 00:22:5097ChromeNetworkDelegate::ChromeNetworkDelegate(
[email protected]3ce02412011-03-01 12:01:1598 ExtensionEventRouterForwarder* event_router,
[email protected]c357acb42011-06-09 20:52:4299 ExtensionInfoMap* extension_info_map,
[email protected]6a5f77c32011-09-04 19:19:59100 const policy::URLBlacklistManager* url_blacklist_manager,
[email protected]673514522011-07-13 18:17:18101 void* profile,
[email protected]a8c1e7452011-05-14 06:17:07102 BooleanPrefMember* enable_referrers)
[email protected]3ce02412011-03-01 12:01:15103 : event_router_(event_router),
[email protected]673514522011-07-13 18:17:18104 profile_(profile),
[email protected]c357acb42011-06-09 20:52:42105 extension_info_map_(extension_info_map),
[email protected]6a5f77c32011-09-04 19:19:59106 enable_referrers_(enable_referrers),
107 url_blacklist_manager_(url_blacklist_manager) {
[email protected]4b50cb52011-03-10 00:29:37108 DCHECK(event_router);
[email protected]0a8db0d2011-04-13 15:15:40109 DCHECK(enable_referrers);
[email protected]0651b812011-02-24 00:22:50110}
111
[email protected]ac039522010-06-15 16:39:44112ChromeNetworkDelegate::~ChromeNetworkDelegate() {}
113
[email protected]0a8db0d2011-04-13 15:15:40114// static
115void ChromeNetworkDelegate::InitializeReferrersEnabled(
116 BooleanPrefMember* enable_referrers,
117 PrefService* pref_service) {
118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
119 enable_referrers->Init(prefs::kEnableReferrers, pref_service, NULL);
120 enable_referrers->MoveToThread(BrowserThread::IO);
121}
122
[email protected]4875ba12011-03-30 22:31:51123int ChromeNetworkDelegate::OnBeforeURLRequest(
[email protected]4c76d7c2011-04-15 19:14:12124 net::URLRequest* request,
[email protected]084262c2011-12-01 21:12:47125 const net::CompletionCallback& callback,
[email protected]4c76d7c2011-04-15 19:14:12126 GURL* new_url) {
[email protected]3e598ff12011-09-06 11:22:34127#if defined(ENABLE_CONFIGURATION_POLICY)
[email protected]6a5f77c32011-09-04 19:19:59128 // TODO(joaodasilva): This prevents extensions from seeing URLs that are
129 // blocked. However, an extension might redirect the request to another URL,
130 // which is not blocked.
131 if (url_blacklist_manager_ &&
132 url_blacklist_manager_->IsURLBlocked(request->url())) {
133 // URL access blocked by policy.
134 scoped_refptr<net::NetLog::EventParameters> params;
135 params = new net::NetLogStringParameter("url", request->url().spec());
136 request->net_log().AddEvent(
137 net::NetLog::TYPE_CHROME_POLICY_ABORTED_REQUEST, params);
138 return net::ERR_NETWORK_ACCESS_DENIED;
139 }
[email protected]3e598ff12011-09-06 11:22:34140#endif
[email protected]6a5f77c32011-09-04 19:19:59141
[email protected]6baff0b52012-03-06 01:30:18142 ForwardRequestStatus(REQUEST_STARTED, request, profile_);
143
[email protected]0a8db0d2011-04-13 15:15:40144 if (!enable_referrers_->GetValue())
145 request->set_referrer(std::string());
[email protected]05cc4e72011-03-08 21:29:48146 return ExtensionWebRequestEventRouter::GetInstance()->OnBeforeRequest(
[email protected]673514522011-07-13 18:17:18147 profile_, extension_info_map_.get(), request, callback, new_url);
[email protected]d05ef99c2011-02-01 21:38:16148}
149
[email protected]4875ba12011-03-30 22:31:51150int ChromeNetworkDelegate::OnBeforeSendHeaders(
[email protected]636eccd2011-06-28 12:28:01151 net::URLRequest* request,
[email protected]084262c2011-12-01 21:12:47152 const net::CompletionCallback& callback,
[email protected]4c76d7c2011-04-15 19:14:12153 net::HttpRequestHeaders* headers) {
[email protected]4875ba12011-03-30 22:31:51154 return ExtensionWebRequestEventRouter::GetInstance()->OnBeforeSendHeaders(
[email protected]673514522011-07-13 18:17:18155 profile_, extension_info_map_.get(), request, callback, headers);
[email protected]ac039522010-06-15 16:39:44156}
[email protected]8202d0c2011-02-23 08:31:14157
[email protected]5796dc942011-07-14 19:26:10158void ChromeNetworkDelegate::OnSendHeaders(
159 net::URLRequest* request,
[email protected]783573b2011-05-13 11:05:15160 const net::HttpRequestHeaders& headers) {
[email protected]5796dc942011-07-14 19:26:10161 ExtensionWebRequestEventRouter::GetInstance()->OnSendHeaders(
162 profile_, extension_info_map_.get(), request, headers);
[email protected]82b42302011-04-20 16:28:16163}
164
[email protected]ea8141e2011-10-05 13:12:51165int ChromeNetworkDelegate::OnHeadersReceived(
166 net::URLRequest* request,
[email protected]084262c2011-12-01 21:12:47167 const net::CompletionCallback& callback,
[email protected]ea8141e2011-10-05 13:12:51168 net::HttpResponseHeaders* original_response_headers,
169 scoped_refptr<net::HttpResponseHeaders>* override_response_headers) {
170 return ExtensionWebRequestEventRouter::GetInstance()->OnHeadersReceived(
171 profile_, extension_info_map_.get(), request, callback,
172 original_response_headers, override_response_headers);
173}
174
[email protected]31b2e5f2011-04-20 16:58:32175void ChromeNetworkDelegate::OnBeforeRedirect(net::URLRequest* request,
176 const GURL& new_location) {
177 ExtensionWebRequestEventRouter::GetInstance()->OnBeforeRedirect(
[email protected]673514522011-07-13 18:17:18178 profile_, extension_info_map_.get(), request, new_location);
[email protected]31b2e5f2011-04-20 16:58:32179}
180
181
[email protected]8202d0c2011-02-23 08:31:14182void ChromeNetworkDelegate::OnResponseStarted(net::URLRequest* request) {
[email protected]62fecae2011-04-21 11:08:24183 ExtensionWebRequestEventRouter::GetInstance()->OnResponseStarted(
[email protected]673514522011-07-13 18:17:18184 profile_, extension_info_map_.get(), request);
185 ForwardProxyErrors(request, event_router_.get(), profile_);
[email protected]8202d0c2011-02-23 08:31:14186}
187
[email protected]8523ba52011-05-22 19:00:58188void ChromeNetworkDelegate::OnRawBytesRead(const net::URLRequest& request,
189 int bytes_read) {
190 TaskManager::GetInstance()->model()->NotifyBytesRead(request, bytes_read);
191}
192
[email protected]9045b8822012-01-13 20:35:35193void ChromeNetworkDelegate::OnCompleted(net::URLRequest* request,
194 bool started) {
[email protected]a83dd332011-07-13 10:41:01195 if (request->status().status() == net::URLRequestStatus::SUCCESS ||
196 request->status().status() == net::URLRequestStatus::HANDLED_EXTERNALLY) {
[email protected]48944382011-04-23 13:28:16197 bool is_redirect = request->response_headers() &&
198 net::HttpResponseHeaders::IsRedirectResponseCode(
199 request->response_headers()->response_code());
200 if (!is_redirect) {
201 ExtensionWebRequestEventRouter::GetInstance()->OnCompleted(
[email protected]673514522011-07-13 18:17:18202 profile_, extension_info_map_.get(), request);
[email protected]48944382011-04-23 13:28:16203 }
[email protected]a83dd332011-07-13 10:41:01204 } else if (request->status().status() == net::URLRequestStatus::FAILED ||
205 request->status().status() == net::URLRequestStatus::CANCELED) {
[email protected]05b6ab42011-04-23 13:46:04206 ExtensionWebRequestEventRouter::GetInstance()->OnErrorOccurred(
[email protected]9045b8822012-01-13 20:35:35207 profile_, extension_info_map_.get(), request, started);
[email protected]a83dd332011-07-13 10:41:01208 } else {
209 NOTREACHED();
[email protected]48944382011-04-23 13:28:16210 }
[email protected]673514522011-07-13 18:17:18211 ForwardProxyErrors(request, event_router_.get(), profile_);
[email protected]6baff0b52012-03-06 01:30:18212
213 ForwardRequestStatus(REQUEST_DONE, request, profile_);
[email protected]8202d0c2011-02-23 08:31:14214}
[email protected]4b50cb52011-03-10 00:29:37215
[email protected]4875ba12011-03-30 22:31:51216void ChromeNetworkDelegate::OnURLRequestDestroyed(net::URLRequest* request) {
217 ExtensionWebRequestEventRouter::GetInstance()->OnURLRequestDestroyed(
[email protected]673514522011-07-13 18:17:18218 profile_, request);
[email protected]4875ba12011-03-30 22:31:51219}
220
[email protected]82a37672011-05-03 12:02:41221void ChromeNetworkDelegate::OnPACScriptError(int line_number,
222 const string16& error) {
[email protected]3daf92302011-05-05 15:04:31223 ExtensionProxyEventRouter::GetInstance()->OnPACScriptError(
[email protected]673514522011-07-13 18:17:18224 event_router_.get(), profile_, line_number, error);
[email protected]82a37672011-05-03 12:02:41225}
[email protected]7efc582d2011-08-03 20:46:35226
[email protected]c2911d72011-10-03 22:16:36227net::NetworkDelegate::AuthRequiredResponse
228ChromeNetworkDelegate::OnAuthRequired(
[email protected]7efc582d2011-08-03 20:46:35229 net::URLRequest* request,
[email protected]c2911d72011-10-03 22:16:36230 const net::AuthChallengeInfo& auth_info,
231 const AuthCallback& callback,
232 net::AuthCredentials* credentials) {
[email protected]90449ab2011-10-11 15:36:45233 return ExtensionWebRequestEventRouter::GetInstance()->OnAuthRequired(
234 profile_, extension_info_map_.get(), request, auth_info,
235 callback, credentials);
[email protected]7efc582d2011-08-03 20:46:35236}