- add sources.
[platform/framework/web/crosswalk.git] / src / components / navigation_interception / intercept_navigation_resource_throttle.cc
1 // Copyright (c) 2012 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 "components/navigation_interception/intercept_navigation_resource_throttle.h"
6
7 #include "components/navigation_interception/navigation_params.h"
8 #include "content/public/browser/browser_thread.h"
9 #include "content/public/browser/child_process_security_policy.h"
10 #include "content/public/browser/render_process_host.h"
11 #include "content/public/browser/render_view_host.h"
12 #include "content/public/browser/resource_controller.h"
13 #include "content/public/browser/resource_request_info.h"
14 #include "content/public/common/page_transition_types.h"
15 #include "content/public/common/referrer.h"
16 #include "net/http/http_response_headers.h"
17 #include "net/url_request/url_request.h"
18
19 using content::BrowserThread;
20 using content::ChildProcessSecurityPolicy;
21 using content::PageTransition;
22 using content::Referrer;
23 using content::RenderViewHost;
24 using content::ResourceRequestInfo;
25
26 namespace navigation_interception {
27
28 namespace {
29
30 void CheckIfShouldIgnoreNavigationOnUIThread(
31     int render_process_id,
32     int render_view_id,
33     const NavigationParams& navigation_params,
34     InterceptNavigationResourceThrottle::CheckOnUIThreadCallback
35     should_ignore_callback,
36     base::Callback<void(bool)> callback) {
37
38   bool should_ignore_navigation = false;
39   RenderViewHost* rvh =
40       RenderViewHost::FromID(render_process_id, render_view_id);
41
42   if (rvh) {
43     NavigationParams validated_params(navigation_params);
44     RenderViewHost::FilterURL(
45         rvh->GetProcess(), false, &validated_params.url());
46
47     should_ignore_navigation = should_ignore_callback.Run(rvh,
48                                                           validated_params);
49   }
50
51   BrowserThread::PostTask(
52       BrowserThread::IO,
53       FROM_HERE,
54       base::Bind(callback, should_ignore_navigation));
55 }
56
57 } // namespace
58
59 InterceptNavigationResourceThrottle::InterceptNavigationResourceThrottle(
60     net::URLRequest* request,
61     CheckOnUIThreadCallback should_ignore_callback)
62     : request_(request),
63       should_ignore_callback_(should_ignore_callback),
64       weak_ptr_factory_(this) {
65 }
66
67 InterceptNavigationResourceThrottle::~InterceptNavigationResourceThrottle() {
68   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
69 }
70
71 void InterceptNavigationResourceThrottle::WillStartRequest(bool* defer) {
72   *defer =
73       CheckIfShouldIgnoreNavigation(request_->url(), request_->method(), false);
74 }
75
76 void InterceptNavigationResourceThrottle::WillRedirectRequest(
77     const GURL& new_url,
78     bool* defer) {
79   *defer =
80       CheckIfShouldIgnoreNavigation(new_url, GetMethodAfterRedirect(), true);
81 }
82
83 std::string InterceptNavigationResourceThrottle::GetMethodAfterRedirect() {
84   net::HttpResponseHeaders* headers = request_->response_headers();
85   if (!headers)
86     return request_->method();
87   return net::URLRequest::ComputeMethodForRedirect(
88              request_->method(), headers->response_code());
89 }
90
91 bool InterceptNavigationResourceThrottle::CheckIfShouldIgnoreNavigation(
92     const GURL& url,
93     const std::string& method,
94     bool is_redirect) {
95   const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
96   if (!info)
97     return false;
98
99   int render_process_id, render_view_id;
100   if (!info->GetAssociatedRenderView(&render_process_id, &render_view_id))
101     return false;
102
103   NavigationParams navigation_params(url,
104                                      Referrer(GURL(request_->referrer()),
105                                               info->GetReferrerPolicy()),
106                                      info->HasUserGesture(),
107                                      method == "POST",
108                                      info->GetPageTransition(),
109                                      is_redirect);
110
111   BrowserThread::PostTask(
112       BrowserThread::UI,
113       FROM_HERE,
114       base::Bind(
115           &CheckIfShouldIgnoreNavigationOnUIThread,
116           render_process_id,
117           render_view_id,
118           navigation_params,
119           should_ignore_callback_,
120           base::Bind(
121               &InterceptNavigationResourceThrottle::OnResultObtained,
122               weak_ptr_factory_.GetWeakPtr())));
123
124   // Defer request while we wait for the UI thread to check if the navigation
125   // should be ignored.
126   return true;
127 }
128
129 void InterceptNavigationResourceThrottle::OnResultObtained(
130     bool should_ignore_navigation) {
131   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
132
133   if (should_ignore_navigation) {
134     controller()->CancelAndIgnore();
135   } else {
136     controller()->Resume();
137   }
138 }
139
140 }  // namespace navigation_interception