1 // Copyright 2014 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_extensions_network_delegate.h"
7 #include "net/base/net_errors.h"
9 #if defined(ENABLE_EXTENSIONS)
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/extensions/api/proxy/proxy_api.h"
12 #include "chrome/browser/extensions/event_router_forwarder.h"
13 #include "chrome/browser/profiles/profile_manager.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/render_frame_host.h"
16 #include "content/public/browser/resource_request_info.h"
17 #include "extensions/browser/api/web_request/web_request_api.h"
18 #include "extensions/browser/info_map.h"
19 #include "extensions/browser/process_manager.h"
20 #include "net/url_request/url_request.h"
22 using content::BrowserThread
;
23 using content::ResourceRequestInfo
;
27 enum RequestStatus
{ REQUEST_STARTED
, REQUEST_DONE
};
29 // Notifies the extensions::ProcessManager that a request has started or stopped
30 // for a particular RenderFrame.
31 void NotifyEPMRequestStatus(RequestStatus status
,
34 int render_frame_id
) {
35 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
36 Profile
* profile
= reinterpret_cast<Profile
*>(profile_id
);
37 if (!g_browser_process
->profile_manager()->IsValidProfile(profile
))
40 extensions::ProcessManager
* process_manager
=
41 extensions::ProcessManager::Get(profile
);
42 DCHECK(process_manager
);
44 // Will be NULL if the request was not issued on behalf of a renderer (e.g. a
45 // system-level request).
46 content::RenderFrameHost
* render_frame_host
=
47 content::RenderFrameHost::FromID(process_id
, render_frame_id
);
48 if (render_frame_host
) {
49 if (status
== REQUEST_STARTED
) {
50 process_manager
->OnNetworkRequestStarted(render_frame_host
);
51 } else if (status
== REQUEST_DONE
) {
52 process_manager
->OnNetworkRequestDone(render_frame_host
);
59 void ForwardRequestStatus(
60 RequestStatus status
, net::URLRequest
* request
, void* profile_id
) {
61 const ResourceRequestInfo
* info
= ResourceRequestInfo::ForRequest(request
);
65 if (status
== REQUEST_STARTED
&& request
->url_chain().size() > 1) {
66 // It's a redirect, this request has already been counted.
70 int process_id
, render_frame_id
;
71 if (info
->GetAssociatedRenderFrame(&process_id
, &render_frame_id
)) {
72 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
73 base::Bind(&NotifyEPMRequestStatus
,
74 status
, profile_id
, process_id
, render_frame_id
));
78 class ChromeExtensionsNetworkDelegateImpl
79 : public ChromeExtensionsNetworkDelegate
{
81 explicit ChromeExtensionsNetworkDelegateImpl(
82 extensions::EventRouterForwarder
* event_router
);
83 ~ChromeExtensionsNetworkDelegateImpl() override
;
86 // ChromeExtensionsNetworkDelegate implementation.
87 void ForwardProxyErrors(net::URLRequest
* request
) override
;
88 void ForwardStartRequestStatus(net::URLRequest
* request
) override
;
89 void ForwardDoneRequestStatus(net::URLRequest
* request
) override
;
90 int OnBeforeURLRequest(net::URLRequest
* request
,
91 const net::CompletionCallback
& callback
,
92 GURL
* new_url
) override
;
93 int OnBeforeSendHeaders(net::URLRequest
* request
,
94 const net::CompletionCallback
& callback
,
95 net::HttpRequestHeaders
* headers
) override
;
96 void OnSendHeaders(net::URLRequest
* request
,
97 const net::HttpRequestHeaders
& headers
) override
;
98 int OnHeadersReceived(
99 net::URLRequest
* request
,
100 const net::CompletionCallback
& callback
,
101 const net::HttpResponseHeaders
* original_response_headers
,
102 scoped_refptr
<net::HttpResponseHeaders
>* override_response_headers
,
103 GURL
* allowed_unsafe_redirect_url
) override
;
104 void OnBeforeRedirect(net::URLRequest
* request
,
105 const GURL
& new_location
) override
;
106 void OnResponseStarted(net::URLRequest
* request
) override
;
107 void OnCompleted(net::URLRequest
* request
, bool started
) override
;
108 void OnURLRequestDestroyed(net::URLRequest
* request
) override
;
109 void OnPACScriptError(int line_number
, const base::string16
& error
) override
;
110 net::NetworkDelegate::AuthRequiredResponse
OnAuthRequired(
111 net::URLRequest
* request
,
112 const net::AuthChallengeInfo
& auth_info
,
113 const AuthCallback
& callback
,
114 net::AuthCredentials
* credentials
) override
;
116 scoped_refptr
<extensions::EventRouterForwarder
> event_router_
;
118 DISALLOW_COPY_AND_ASSIGN(ChromeExtensionsNetworkDelegateImpl
);
121 ChromeExtensionsNetworkDelegateImpl::ChromeExtensionsNetworkDelegateImpl(
122 extensions::EventRouterForwarder
* event_router
) {
123 DCHECK(event_router
);
124 event_router_
= event_router
;
127 ChromeExtensionsNetworkDelegateImpl::~ChromeExtensionsNetworkDelegateImpl() {}
129 void ChromeExtensionsNetworkDelegateImpl::ForwardProxyErrors(
130 net::URLRequest
* request
) {
131 if (request
->status().status() == net::URLRequestStatus::FAILED
) {
132 switch (request
->status().error()) {
133 case net::ERR_PROXY_AUTH_UNSUPPORTED
:
134 case net::ERR_PROXY_CONNECTION_FAILED
:
135 case net::ERR_TUNNEL_CONNECTION_FAILED
:
136 extensions::ProxyEventRouter::GetInstance()->OnProxyError(
137 event_router_
.get(), profile_
, request
->status().error());
142 void ChromeExtensionsNetworkDelegateImpl::ForwardStartRequestStatus(
143 net::URLRequest
* request
) {
144 ForwardRequestStatus(REQUEST_STARTED
, request
, profile_
);
147 void ChromeExtensionsNetworkDelegateImpl::ForwardDoneRequestStatus(
148 net::URLRequest
* request
) {
149 ForwardRequestStatus(REQUEST_DONE
, request
, profile_
);
152 int ChromeExtensionsNetworkDelegateImpl::OnBeforeURLRequest(
153 net::URLRequest
* request
,
154 const net::CompletionCallback
& callback
,
156 return ExtensionWebRequestEventRouter::GetInstance()->OnBeforeRequest(
157 profile_
, extension_info_map_
.get(), request
, callback
, new_url
);
160 int ChromeExtensionsNetworkDelegateImpl::OnBeforeSendHeaders(
161 net::URLRequest
* request
,
162 const net::CompletionCallback
& callback
,
163 net::HttpRequestHeaders
* headers
) {
164 return ExtensionWebRequestEventRouter::GetInstance()->OnBeforeSendHeaders(
165 profile_
, extension_info_map_
.get(), request
, callback
, headers
);
168 void ChromeExtensionsNetworkDelegateImpl::OnSendHeaders(
169 net::URLRequest
* request
,
170 const net::HttpRequestHeaders
& headers
) {
171 ExtensionWebRequestEventRouter::GetInstance()->OnSendHeaders(
172 profile_
, extension_info_map_
.get(), request
, headers
);
175 int ChromeExtensionsNetworkDelegateImpl::OnHeadersReceived(
176 net::URLRequest
* request
,
177 const net::CompletionCallback
& callback
,
178 const net::HttpResponseHeaders
* original_response_headers
,
179 scoped_refptr
<net::HttpResponseHeaders
>* override_response_headers
,
180 GURL
* allowed_unsafe_redirect_url
) {
181 return ExtensionWebRequestEventRouter::GetInstance()->OnHeadersReceived(
183 extension_info_map_
.get(),
186 original_response_headers
,
187 override_response_headers
,
188 allowed_unsafe_redirect_url
);
191 void ChromeExtensionsNetworkDelegateImpl::OnBeforeRedirect(
192 net::URLRequest
* request
,
193 const GURL
& new_location
) {
194 ExtensionWebRequestEventRouter::GetInstance()->OnBeforeRedirect(
195 profile_
, extension_info_map_
.get(), request
, new_location
);
199 void ChromeExtensionsNetworkDelegateImpl::OnResponseStarted(
200 net::URLRequest
* request
) {
201 ExtensionWebRequestEventRouter::GetInstance()->OnResponseStarted(
202 profile_
, extension_info_map_
.get(), request
);
203 ForwardProxyErrors(request
);
206 void ChromeExtensionsNetworkDelegateImpl::OnCompleted(
207 net::URLRequest
* request
,
209 if (request
->status().status() == net::URLRequestStatus::SUCCESS
) {
210 bool is_redirect
= request
->response_headers() &&
211 net::HttpResponseHeaders::IsRedirectResponseCode(
212 request
->response_headers()->response_code());
214 ExtensionWebRequestEventRouter::GetInstance()->OnCompleted(
215 profile_
, extension_info_map_
.get(), request
);
220 if (request
->status().status() == net::URLRequestStatus::FAILED
||
221 request
->status().status() == net::URLRequestStatus::CANCELED
) {
222 ExtensionWebRequestEventRouter::GetInstance()->OnErrorOccurred(
223 profile_
, extension_info_map_
.get(), request
, started
);
230 void ChromeExtensionsNetworkDelegateImpl::OnURLRequestDestroyed(
231 net::URLRequest
* request
) {
232 ExtensionWebRequestEventRouter::GetInstance()->OnURLRequestDestroyed(
236 void ChromeExtensionsNetworkDelegateImpl::OnPACScriptError(
238 const base::string16
& error
) {
239 extensions::ProxyEventRouter::GetInstance()->OnPACScriptError(
240 event_router_
.get(), profile_
, line_number
, error
);
243 net::NetworkDelegate::AuthRequiredResponse
244 ChromeExtensionsNetworkDelegateImpl::OnAuthRequired(
245 net::URLRequest
* request
,
246 const net::AuthChallengeInfo
& auth_info
,
247 const AuthCallback
& callback
,
248 net::AuthCredentials
* credentials
) {
249 return ExtensionWebRequestEventRouter::GetInstance()->OnAuthRequired(
250 profile_
, extension_info_map_
.get(), request
, auth_info
, callback
,
256 #endif // defined(ENABLE_EXTENSIONS)
259 ChromeExtensionsNetworkDelegate
* ChromeExtensionsNetworkDelegate::Create(
260 extensions::EventRouterForwarder
* event_router
) {
261 #if defined(ENABLE_EXTENSIONS)
262 return new ChromeExtensionsNetworkDelegateImpl(event_router
);
264 return new ChromeExtensionsNetworkDelegate();
268 ChromeExtensionsNetworkDelegate::ChromeExtensionsNetworkDelegate()
272 ChromeExtensionsNetworkDelegate::~ChromeExtensionsNetworkDelegate() {}
274 void ChromeExtensionsNetworkDelegate::set_extension_info_map(
275 extensions::InfoMap
* extension_info_map
) {
276 #if defined(ENABLE_EXTENSIONS)
277 extension_info_map_
= extension_info_map
;
281 void ChromeExtensionsNetworkDelegate::ForwardProxyErrors(
282 net::URLRequest
* request
) {
285 void ChromeExtensionsNetworkDelegate::ForwardStartRequestStatus(
286 net::URLRequest
* request
) {
289 void ChromeExtensionsNetworkDelegate::ForwardDoneRequestStatus(
290 net::URLRequest
* request
) {
293 int ChromeExtensionsNetworkDelegate::OnBeforeURLRequest(
294 net::URLRequest
* request
,
295 const net::CompletionCallback
& callback
,
300 int ChromeExtensionsNetworkDelegate::OnBeforeSendHeaders(
301 net::URLRequest
* request
,
302 const net::CompletionCallback
& callback
,
303 net::HttpRequestHeaders
* headers
) {
307 void ChromeExtensionsNetworkDelegate::OnSendHeaders(
308 net::URLRequest
* request
,
309 const net::HttpRequestHeaders
& headers
) {
312 int ChromeExtensionsNetworkDelegate::OnHeadersReceived(
313 net::URLRequest
* request
,
314 const net::CompletionCallback
& callback
,
315 const net::HttpResponseHeaders
* original_response_headers
,
316 scoped_refptr
<net::HttpResponseHeaders
>* override_response_headers
,
317 GURL
* allowed_unsafe_redirect_url
) {
321 void ChromeExtensionsNetworkDelegate::OnBeforeRedirect(
322 net::URLRequest
* request
,
323 const GURL
& new_location
) {
327 void ChromeExtensionsNetworkDelegate::OnResponseStarted(
328 net::URLRequest
* request
) {
331 void ChromeExtensionsNetworkDelegate::OnCompleted(
332 net::URLRequest
* request
,
336 void ChromeExtensionsNetworkDelegate::OnURLRequestDestroyed(
337 net::URLRequest
* request
) {
340 void ChromeExtensionsNetworkDelegate::OnPACScriptError(
342 const base::string16
& error
) {
345 net::NetworkDelegate::AuthRequiredResponse
346 ChromeExtensionsNetworkDelegate::OnAuthRequired(
347 net::URLRequest
* request
,
348 const net::AuthChallengeInfo
& auth_info
,
349 const AuthCallback
& callback
,
350 net::AuthCredentials
* credentials
) {
351 return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION
;