Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / net / chrome_extensions_network_delegate.cc
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.
4
5 #include "chrome/browser/net/chrome_extensions_network_delegate.h"
6
7 #include "net/base/net_errors.h"
8
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/api/web_request/web_request_api.h"
13 #include "chrome/browser/extensions/event_router_forwarder.h"
14 #include "chrome/browser/profiles/profile_manager.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/render_frame_host.h"
17 #include "content/public/browser/resource_request_info.h"
18 #include "extensions/browser/extension_system.h"
19 #include "extensions/browser/info_map.h"
20 #include "extensions/browser/process_manager.h"
21 #include "net/url_request/url_request.h"
22
23 using content::BrowserThread;
24 using content::ResourceRequestInfo;
25
26 namespace {
27
28 enum RequestStatus { REQUEST_STARTED, REQUEST_DONE };
29
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                             int process_id,
35                             int render_frame_id) {
36   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
37   Profile* profile = reinterpret_cast<Profile*>(profile_id);
38   if (!g_browser_process->profile_manager()->IsValidProfile(profile))
39     return;
40
41   extensions::ProcessManager* process_manager =
42       extensions::ExtensionSystem::Get(profile)->process_manager();
43   // This may be NULL in unit tests.
44   if (!process_manager)
45     return;
46
47   // Will be NULL if the request was not issued on behalf of a renderer (e.g. a
48   // system-level request).
49   content::RenderFrameHost* render_frame_host =
50       content::RenderFrameHost::FromID(process_id, render_frame_id);
51   if (render_frame_host) {
52     if (status == REQUEST_STARTED) {
53       process_manager->OnNetworkRequestStarted(render_frame_host);
54     } else if (status == REQUEST_DONE) {
55       process_manager->OnNetworkRequestDone(render_frame_host);
56     } else {
57       NOTREACHED();
58     }
59   }
60 }
61
62 void ForwardRequestStatus(
63     RequestStatus status, net::URLRequest* request, void* profile_id) {
64   const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
65   if (!info)
66     return;
67
68   if (status == REQUEST_STARTED && request->url_chain().size() > 1) {
69     // It's a redirect, this request has already been counted.
70     return;
71   }
72
73   int process_id, render_frame_id;
74   if (info->GetAssociatedRenderFrame(&process_id, &render_frame_id)) {
75     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
76         base::Bind(&NotifyEPMRequestStatus,
77                    status, profile_id, process_id, render_frame_id));
78   }
79 }
80
81 class ChromeExtensionsNetworkDelegateImpl
82     : public ChromeExtensionsNetworkDelegate {
83  public:
84   explicit ChromeExtensionsNetworkDelegateImpl(
85       extensions::EventRouterForwarder* event_router);
86   virtual ~ChromeExtensionsNetworkDelegateImpl();
87
88  private:
89   // ChromeExtensionsNetworkDelegate implementation.
90   virtual void ForwardProxyErrors(net::URLRequest* request) OVERRIDE;
91   virtual void ForwardStartRequestStatus(net::URLRequest* request) OVERRIDE;
92   virtual void ForwardDoneRequestStatus(net::URLRequest* request) OVERRIDE;
93   virtual int OnBeforeURLRequest(net::URLRequest* request,
94                                  const net::CompletionCallback& callback,
95                                  GURL* new_url) OVERRIDE;
96   virtual int OnBeforeSendHeaders(net::URLRequest* request,
97                                   const net::CompletionCallback& callback,
98                                   net::HttpRequestHeaders* headers) OVERRIDE;
99   virtual void OnSendHeaders(net::URLRequest* request,
100                              const net::HttpRequestHeaders& headers) OVERRIDE;
101   virtual 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   virtual void OnBeforeRedirect(net::URLRequest* request,
108                                 const GURL& new_location) OVERRIDE;
109   virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE;
110   virtual void OnCompleted(net::URLRequest* request, bool started) OVERRIDE;
111   virtual void OnURLRequestDestroyed(net::URLRequest* request) OVERRIDE;
112   virtual void OnPACScriptError(int line_number,
113                                 const base::string16& error) OVERRIDE;
114   virtual net::NetworkDelegate::AuthRequiredResponse OnAuthRequired(
115       net::URLRequest* request,
116       const net::AuthChallengeInfo& auth_info,
117       const AuthCallback& callback,
118       net::AuthCredentials* credentials) OVERRIDE;
119
120   scoped_refptr<extensions::EventRouterForwarder> event_router_;
121
122   DISALLOW_COPY_AND_ASSIGN(ChromeExtensionsNetworkDelegateImpl);
123 };
124
125 ChromeExtensionsNetworkDelegateImpl::ChromeExtensionsNetworkDelegateImpl(
126     extensions::EventRouterForwarder* event_router) {
127   DCHECK(event_router);
128   event_router_ = event_router;
129 }
130
131 ChromeExtensionsNetworkDelegateImpl::~ChromeExtensionsNetworkDelegateImpl() {}
132
133 void ChromeExtensionsNetworkDelegateImpl::ForwardProxyErrors(
134     net::URLRequest* request) {
135   if (request->status().status() == net::URLRequestStatus::FAILED) {
136     switch (request->status().error()) {
137       case net::ERR_PROXY_AUTH_UNSUPPORTED:
138       case net::ERR_PROXY_CONNECTION_FAILED:
139       case net::ERR_TUNNEL_CONNECTION_FAILED:
140         extensions::ProxyEventRouter::GetInstance()->OnProxyError(
141             event_router_.get(), profile_, request->status().error());
142     }
143   }
144 }
145
146 void ChromeExtensionsNetworkDelegateImpl::ForwardStartRequestStatus(
147     net::URLRequest* request) {
148   ForwardRequestStatus(REQUEST_STARTED, request, profile_);
149 }
150
151 void ChromeExtensionsNetworkDelegateImpl::ForwardDoneRequestStatus(
152     net::URLRequest* request) {
153   ForwardRequestStatus(REQUEST_DONE, request, profile_);
154 }
155
156 int ChromeExtensionsNetworkDelegateImpl::OnBeforeURLRequest(
157     net::URLRequest* request,
158     const net::CompletionCallback& callback,
159     GURL* new_url) {
160   return ExtensionWebRequestEventRouter::GetInstance()->OnBeforeRequest(
161       profile_, extension_info_map_.get(), request, callback, new_url);
162 }
163
164 int ChromeExtensionsNetworkDelegateImpl::OnBeforeSendHeaders(
165     net::URLRequest* request,
166     const net::CompletionCallback& callback,
167     net::HttpRequestHeaders* headers) {
168   return ExtensionWebRequestEventRouter::GetInstance()->OnBeforeSendHeaders(
169       profile_, extension_info_map_.get(), request, callback, headers);
170 }
171
172 void ChromeExtensionsNetworkDelegateImpl::OnSendHeaders(
173     net::URLRequest* request,
174     const net::HttpRequestHeaders& headers) {
175   ExtensionWebRequestEventRouter::GetInstance()->OnSendHeaders(
176       profile_, extension_info_map_.get(), request, headers);
177 }
178
179 int ChromeExtensionsNetworkDelegateImpl::OnHeadersReceived(
180     net::URLRequest* request,
181     const net::CompletionCallback& callback,
182     const net::HttpResponseHeaders* original_response_headers,
183     scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
184     GURL* allowed_unsafe_redirect_url) {
185   return ExtensionWebRequestEventRouter::GetInstance()->OnHeadersReceived(
186       profile_,
187       extension_info_map_.get(),
188       request,
189       callback,
190       original_response_headers,
191       override_response_headers,
192       allowed_unsafe_redirect_url);
193 }
194
195 void ChromeExtensionsNetworkDelegateImpl::OnBeforeRedirect(
196     net::URLRequest* request,
197     const GURL& new_location) {
198   ExtensionWebRequestEventRouter::GetInstance()->OnBeforeRedirect(
199       profile_, extension_info_map_.get(), request, new_location);
200 }
201
202
203 void ChromeExtensionsNetworkDelegateImpl::OnResponseStarted(
204     net::URLRequest* request) {
205   ExtensionWebRequestEventRouter::GetInstance()->OnResponseStarted(
206       profile_, extension_info_map_.get(), request);
207   ForwardProxyErrors(request);
208 }
209
210 void ChromeExtensionsNetworkDelegateImpl::OnCompleted(
211     net::URLRequest* request,
212     bool started) {
213   if (request->status().status() == net::URLRequestStatus::SUCCESS) {
214     bool is_redirect = request->response_headers() &&
215         net::HttpResponseHeaders::IsRedirectResponseCode(
216             request->response_headers()->response_code());
217     if (!is_redirect) {
218       ExtensionWebRequestEventRouter::GetInstance()->OnCompleted(
219           profile_, extension_info_map_.get(), request);
220     }
221     return;
222   }
223
224   if (request->status().status() == net::URLRequestStatus::FAILED ||
225       request->status().status() == net::URLRequestStatus::CANCELED) {
226     ExtensionWebRequestEventRouter::GetInstance()->OnErrorOccurred(
227         profile_, extension_info_map_.get(), request, started);
228     return;
229   }
230
231   NOTREACHED();
232 }
233
234 void ChromeExtensionsNetworkDelegateImpl::OnURLRequestDestroyed(
235     net::URLRequest* request) {
236   ExtensionWebRequestEventRouter::GetInstance()->OnURLRequestDestroyed(
237       profile_, request);
238 }
239
240 void ChromeExtensionsNetworkDelegateImpl::OnPACScriptError(
241     int line_number,
242     const base::string16& error) {
243   extensions::ProxyEventRouter::GetInstance()->OnPACScriptError(
244       event_router_.get(), profile_, line_number, error);
245 }
246
247 net::NetworkDelegate::AuthRequiredResponse
248 ChromeExtensionsNetworkDelegateImpl::OnAuthRequired(
249     net::URLRequest* request,
250     const net::AuthChallengeInfo& auth_info,
251     const AuthCallback& callback,
252     net::AuthCredentials* credentials) {
253   return ExtensionWebRequestEventRouter::GetInstance()->OnAuthRequired(
254       profile_, extension_info_map_.get(), request, auth_info, callback,
255       credentials);
256 }
257
258 }  // namespace
259
260 #endif  // defined(ENABLE_EXTENSIONS)
261
262 // static
263 ChromeExtensionsNetworkDelegate* ChromeExtensionsNetworkDelegate::Create(
264     extensions::EventRouterForwarder* event_router) {
265 #if defined(ENABLE_EXTENSIONS)
266   return new ChromeExtensionsNetworkDelegateImpl(event_router);
267 #else
268   return new ChromeExtensionsNetworkDelegate();
269 #endif
270 }
271
272 ChromeExtensionsNetworkDelegate::ChromeExtensionsNetworkDelegate()
273     : profile_(NULL) {
274 }
275
276 ChromeExtensionsNetworkDelegate::~ChromeExtensionsNetworkDelegate() {}
277
278 void ChromeExtensionsNetworkDelegate::set_extension_info_map(
279     extensions::InfoMap* extension_info_map) {
280 #if defined(ENABLE_EXTENSIONS)
281   extension_info_map_ = extension_info_map;
282 #endif
283 }
284
285 void ChromeExtensionsNetworkDelegate::ForwardProxyErrors(
286     net::URLRequest* request) {
287 }
288
289 void ChromeExtensionsNetworkDelegate::ForwardStartRequestStatus(
290     net::URLRequest* request) {
291 }
292
293 void ChromeExtensionsNetworkDelegate::ForwardDoneRequestStatus(
294     net::URLRequest* request) {
295 }
296
297 int ChromeExtensionsNetworkDelegate::OnBeforeURLRequest(
298     net::URLRequest* request,
299     const net::CompletionCallback& callback,
300     GURL* new_url) {
301   return net::OK;
302 }
303
304 int ChromeExtensionsNetworkDelegate::OnBeforeSendHeaders(
305     net::URLRequest* request,
306     const net::CompletionCallback& callback,
307     net::HttpRequestHeaders* headers) {
308   return net::OK;
309 }
310
311 void ChromeExtensionsNetworkDelegate::OnSendHeaders(
312     net::URLRequest* request,
313     const net::HttpRequestHeaders& headers) {
314 }
315
316 int ChromeExtensionsNetworkDelegate::OnHeadersReceived(
317     net::URLRequest* request,
318     const net::CompletionCallback& callback,
319     const net::HttpResponseHeaders* original_response_headers,
320     scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
321     GURL* allowed_unsafe_redirect_url) {
322   return net::OK;
323 }
324
325 void ChromeExtensionsNetworkDelegate::OnBeforeRedirect(
326     net::URLRequest* request,
327     const GURL& new_location) {
328 }
329
330
331 void ChromeExtensionsNetworkDelegate::OnResponseStarted(
332     net::URLRequest* request) {
333 }
334
335 void ChromeExtensionsNetworkDelegate::OnCompleted(
336     net::URLRequest* request,
337     bool started) {
338 }
339
340 void ChromeExtensionsNetworkDelegate::OnURLRequestDestroyed(
341     net::URLRequest* request) {
342 }
343
344 void ChromeExtensionsNetworkDelegate::OnPACScriptError(
345     int line_number,
346     const base::string16& error) {
347 }
348
349 net::NetworkDelegate::AuthRequiredResponse
350 ChromeExtensionsNetworkDelegate::OnAuthRequired(
351     net::URLRequest* request,
352     const net::AuthChallengeInfo& auth_info,
353     const AuthCallback& callback,
354     net::AuthCredentials* credentials) {
355   return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION;
356 }