Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / net / chrome_extensions_network_delegate.cc
blob331d94112281da49a5404c8cec9ffc3c095f4209
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;
24 using extensions::ExtensionWebRequestEventRouter;
26 namespace {
28 enum RequestStatus { REQUEST_STARTED, REQUEST_DONE };
30 // Notifies the extensions::ProcessManager that a request has started or stopped
31 // for a particular RenderFrame.
32 void NotifyEPMRequestStatus(RequestStatus status,
33 void* profile_id,
34 uint64 request_id,
35 int process_id,
36 int render_frame_id) {
37 DCHECK_CURRENTLY_ON(BrowserThread::UI);
38 Profile* profile = reinterpret_cast<Profile*>(profile_id);
39 if (!g_browser_process->profile_manager()->IsValidProfile(profile))
40 return;
42 extensions::ProcessManager* process_manager =
43 extensions::ProcessManager::Get(profile);
44 DCHECK(process_manager);
46 // Will be NULL if the request was not issued on behalf of a renderer (e.g. a
47 // system-level request).
48 content::RenderFrameHost* render_frame_host =
49 content::RenderFrameHost::FromID(process_id, render_frame_id);
50 if (render_frame_host) {
51 if (status == REQUEST_STARTED) {
52 process_manager->OnNetworkRequestStarted(render_frame_host, request_id);
53 } else if (status == REQUEST_DONE) {
54 process_manager->OnNetworkRequestDone(render_frame_host, request_id);
55 } else {
56 NOTREACHED();
61 void ForwardRequestStatus(
62 RequestStatus status, net::URLRequest* request, void* profile_id) {
63 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
64 if (!info)
65 return;
67 if (status == REQUEST_STARTED && request->url_chain().size() > 1) {
68 // It's a redirect, this request has already been counted.
69 return;
72 int process_id, render_frame_id;
73 if (info->GetAssociatedRenderFrame(&process_id, &render_frame_id)) {
74 BrowserThread::PostTask(
75 BrowserThread::UI, FROM_HERE,
76 base::Bind(&NotifyEPMRequestStatus, status, profile_id,
77 request->identifier(), process_id, render_frame_id));
81 class ChromeExtensionsNetworkDelegateImpl
82 : public ChromeExtensionsNetworkDelegate {
83 public:
84 explicit ChromeExtensionsNetworkDelegateImpl(
85 extensions::EventRouterForwarder* event_router);
86 ~ChromeExtensionsNetworkDelegateImpl() override;
88 private:
89 // ChromeExtensionsNetworkDelegate implementation.
90 void ForwardProxyErrors(net::URLRequest* request) override;
91 void ForwardStartRequestStatus(net::URLRequest* request) override;
92 void ForwardDoneRequestStatus(net::URLRequest* request) override;
93 int OnBeforeURLRequest(net::URLRequest* request,
94 const net::CompletionCallback& callback,
95 GURL* new_url) override;
96 int OnBeforeSendHeaders(net::URLRequest* request,
97 const net::CompletionCallback& callback,
98 net::HttpRequestHeaders* headers) override;
99 void OnSendHeaders(net::URLRequest* request,
100 const net::HttpRequestHeaders& headers) override;
101 int OnHeadersReceived(
102 net::URLRequest* request,
103 const net::CompletionCallback& callback,
104 const net::HttpResponseHeaders* original_response_headers,
105 scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
106 GURL* allowed_unsafe_redirect_url) override;
107 void OnBeforeRedirect(net::URLRequest* request,
108 const GURL& new_location) override;
109 void OnResponseStarted(net::URLRequest* request) override;
110 void OnCompleted(net::URLRequest* request, bool started) override;
111 void OnURLRequestDestroyed(net::URLRequest* request) override;
112 void OnPACScriptError(int line_number, const base::string16& error) override;
113 net::NetworkDelegate::AuthRequiredResponse OnAuthRequired(
114 net::URLRequest* request,
115 const net::AuthChallengeInfo& auth_info,
116 const AuthCallback& callback,
117 net::AuthCredentials* credentials) override;
119 scoped_refptr<extensions::EventRouterForwarder> event_router_;
121 DISALLOW_COPY_AND_ASSIGN(ChromeExtensionsNetworkDelegateImpl);
124 ChromeExtensionsNetworkDelegateImpl::ChromeExtensionsNetworkDelegateImpl(
125 extensions::EventRouterForwarder* event_router) {
126 DCHECK(event_router);
127 event_router_ = event_router;
130 ChromeExtensionsNetworkDelegateImpl::~ChromeExtensionsNetworkDelegateImpl() {}
132 void ChromeExtensionsNetworkDelegateImpl::ForwardProxyErrors(
133 net::URLRequest* request) {
134 if (request->status().status() == net::URLRequestStatus::FAILED) {
135 switch (request->status().error()) {
136 case net::ERR_PROXY_AUTH_UNSUPPORTED:
137 case net::ERR_PROXY_CONNECTION_FAILED:
138 case net::ERR_TUNNEL_CONNECTION_FAILED:
139 extensions::ProxyEventRouter::GetInstance()->OnProxyError(
140 event_router_.get(), profile_, request->status().error());
145 void ChromeExtensionsNetworkDelegateImpl::ForwardStartRequestStatus(
146 net::URLRequest* request) {
147 ForwardRequestStatus(REQUEST_STARTED, request, profile_);
150 void ChromeExtensionsNetworkDelegateImpl::ForwardDoneRequestStatus(
151 net::URLRequest* request) {
152 ForwardRequestStatus(REQUEST_DONE, request, profile_);
155 int ChromeExtensionsNetworkDelegateImpl::OnBeforeURLRequest(
156 net::URLRequest* request,
157 const net::CompletionCallback& callback,
158 GURL* new_url) {
159 return ExtensionWebRequestEventRouter::GetInstance()->OnBeforeRequest(
160 profile_, extension_info_map_.get(), request, callback, new_url);
163 int ChromeExtensionsNetworkDelegateImpl::OnBeforeSendHeaders(
164 net::URLRequest* request,
165 const net::CompletionCallback& callback,
166 net::HttpRequestHeaders* headers) {
167 return ExtensionWebRequestEventRouter::GetInstance()->OnBeforeSendHeaders(
168 profile_, extension_info_map_.get(), request, callback, headers);
171 void ChromeExtensionsNetworkDelegateImpl::OnSendHeaders(
172 net::URLRequest* request,
173 const net::HttpRequestHeaders& headers) {
174 ExtensionWebRequestEventRouter::GetInstance()->OnSendHeaders(
175 profile_, extension_info_map_.get(), request, headers);
178 int ChromeExtensionsNetworkDelegateImpl::OnHeadersReceived(
179 net::URLRequest* request,
180 const net::CompletionCallback& callback,
181 const net::HttpResponseHeaders* original_response_headers,
182 scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
183 GURL* allowed_unsafe_redirect_url) {
184 return ExtensionWebRequestEventRouter::GetInstance()->OnHeadersReceived(
185 profile_,
186 extension_info_map_.get(),
187 request,
188 callback,
189 original_response_headers,
190 override_response_headers,
191 allowed_unsafe_redirect_url);
194 void ChromeExtensionsNetworkDelegateImpl::OnBeforeRedirect(
195 net::URLRequest* request,
196 const GURL& new_location) {
197 ExtensionWebRequestEventRouter::GetInstance()->OnBeforeRedirect(
198 profile_, extension_info_map_.get(), request, new_location);
202 void ChromeExtensionsNetworkDelegateImpl::OnResponseStarted(
203 net::URLRequest* request) {
204 ExtensionWebRequestEventRouter::GetInstance()->OnResponseStarted(
205 profile_, extension_info_map_.get(), request);
206 ForwardProxyErrors(request);
209 void ChromeExtensionsNetworkDelegateImpl::OnCompleted(
210 net::URLRequest* request,
211 bool started) {
212 if (request->status().status() == net::URLRequestStatus::SUCCESS) {
213 bool is_redirect = request->response_headers() &&
214 net::HttpResponseHeaders::IsRedirectResponseCode(
215 request->response_headers()->response_code());
216 if (!is_redirect) {
217 ExtensionWebRequestEventRouter::GetInstance()->OnCompleted(
218 profile_, extension_info_map_.get(), request);
220 return;
223 if (request->status().status() == net::URLRequestStatus::FAILED ||
224 request->status().status() == net::URLRequestStatus::CANCELED) {
225 ExtensionWebRequestEventRouter::GetInstance()->OnErrorOccurred(
226 profile_, extension_info_map_.get(), request, started);
227 return;
230 NOTREACHED();
233 void ChromeExtensionsNetworkDelegateImpl::OnURLRequestDestroyed(
234 net::URLRequest* request) {
235 ExtensionWebRequestEventRouter::GetInstance()->OnURLRequestDestroyed(
236 profile_, request);
239 void ChromeExtensionsNetworkDelegateImpl::OnPACScriptError(
240 int line_number,
241 const base::string16& error) {
242 extensions::ProxyEventRouter::GetInstance()->OnPACScriptError(
243 event_router_.get(), profile_, line_number, error);
246 net::NetworkDelegate::AuthRequiredResponse
247 ChromeExtensionsNetworkDelegateImpl::OnAuthRequired(
248 net::URLRequest* request,
249 const net::AuthChallengeInfo& auth_info,
250 const AuthCallback& callback,
251 net::AuthCredentials* credentials) {
252 return ExtensionWebRequestEventRouter::GetInstance()->OnAuthRequired(
253 profile_, extension_info_map_.get(), request, auth_info, callback,
254 credentials);
257 } // namespace
259 #endif // defined(ENABLE_EXTENSIONS)
261 // static
262 ChromeExtensionsNetworkDelegate* ChromeExtensionsNetworkDelegate::Create(
263 extensions::EventRouterForwarder* event_router) {
264 #if defined(ENABLE_EXTENSIONS)
265 return new ChromeExtensionsNetworkDelegateImpl(event_router);
266 #else
267 return new ChromeExtensionsNetworkDelegate();
268 #endif
271 ChromeExtensionsNetworkDelegate::ChromeExtensionsNetworkDelegate()
272 : profile_(NULL) {
275 ChromeExtensionsNetworkDelegate::~ChromeExtensionsNetworkDelegate() {}
277 void ChromeExtensionsNetworkDelegate::set_extension_info_map(
278 extensions::InfoMap* extension_info_map) {
279 #if defined(ENABLE_EXTENSIONS)
280 extension_info_map_ = extension_info_map;
281 #endif
284 void ChromeExtensionsNetworkDelegate::ForwardProxyErrors(
285 net::URLRequest* request) {
288 void ChromeExtensionsNetworkDelegate::ForwardStartRequestStatus(
289 net::URLRequest* request) {
292 void ChromeExtensionsNetworkDelegate::ForwardDoneRequestStatus(
293 net::URLRequest* request) {
296 int ChromeExtensionsNetworkDelegate::OnBeforeURLRequest(
297 net::URLRequest* request,
298 const net::CompletionCallback& callback,
299 GURL* new_url) {
300 return net::OK;
303 int ChromeExtensionsNetworkDelegate::OnBeforeSendHeaders(
304 net::URLRequest* request,
305 const net::CompletionCallback& callback,
306 net::HttpRequestHeaders* headers) {
307 return net::OK;
310 void ChromeExtensionsNetworkDelegate::OnSendHeaders(
311 net::URLRequest* request,
312 const net::HttpRequestHeaders& headers) {
315 int ChromeExtensionsNetworkDelegate::OnHeadersReceived(
316 net::URLRequest* request,
317 const net::CompletionCallback& callback,
318 const net::HttpResponseHeaders* original_response_headers,
319 scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
320 GURL* allowed_unsafe_redirect_url) {
321 return net::OK;
324 void ChromeExtensionsNetworkDelegate::OnBeforeRedirect(
325 net::URLRequest* request,
326 const GURL& new_location) {
330 void ChromeExtensionsNetworkDelegate::OnResponseStarted(
331 net::URLRequest* request) {
334 void ChromeExtensionsNetworkDelegate::OnCompleted(
335 net::URLRequest* request,
336 bool started) {
339 void ChromeExtensionsNetworkDelegate::OnURLRequestDestroyed(
340 net::URLRequest* request) {
343 void ChromeExtensionsNetworkDelegate::OnPACScriptError(
344 int line_number,
345 const base::string16& error) {
348 net::NetworkDelegate::AuthRequiredResponse
349 ChromeExtensionsNetworkDelegate::OnAuthRequired(
350 net::URLRequest* request,
351 const net::AuthChallengeInfo& auth_info,
352 const AuthCallback& callback,
353 net::AuthCredentials* credentials) {
354 return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION;