Remove obsolete for_web_contents parameter in FontRenderParamsQuery.
[chromium-blink-merge.git] / chrome / browser / renderer_host / safe_browsing_resource_throttle.cc
blob5eb2f6a577a23d59706cf1e7d63c9266fb739c83
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.
5 #include "chrome/browser/renderer_host/safe_browsing_resource_throttle.h"
7 #include "base/logging.h"
8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/prerender/prerender_contents.h"
10 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/render_view_host.h"
13 #include "content/public/browser/resource_controller.h"
14 #include "content/public/browser/resource_request_info.h"
15 #include "content/public/browser/web_contents.h"
16 #include "net/base/load_flags.h"
17 #include "net/url_request/redirect_info.h"
18 #include "net/url_request/url_request.h"
20 // Maximum time in milliseconds to wait for the safe browsing service to
21 // verify a URL. After this amount of time the outstanding check will be
22 // aborted, and the URL will be treated as if it were safe.
23 static const int kCheckUrlTimeoutMs = 5000;
25 // TODO(eroman): Downgrade these CHECK()s to DCHECKs once there is more
26 // unit test coverage.
28 SafeBrowsingResourceThrottle::SafeBrowsingResourceThrottle(
29 const net::URLRequest* request,
30 content::ResourceType resource_type,
31 SafeBrowsingService* safe_browsing)
32 : state_(STATE_NONE),
33 defer_state_(DEFERRED_NONE),
34 threat_type_(SB_THREAT_TYPE_SAFE),
35 database_manager_(safe_browsing->database_manager()),
36 ui_manager_(safe_browsing->ui_manager()),
37 request_(request),
38 is_subresource_(resource_type != content::RESOURCE_TYPE_MAIN_FRAME),
39 is_subframe_(resource_type == content::RESOURCE_TYPE_SUB_FRAME) {
42 SafeBrowsingResourceThrottle::~SafeBrowsingResourceThrottle() {
43 if (state_ == STATE_CHECKING_URL)
44 database_manager_->CancelCheck(this);
47 void SafeBrowsingResourceThrottle::WillStartRequest(bool* defer) {
48 // We need to check the new URL before starting the request.
49 if (CheckUrl(request_->url()))
50 return;
52 // If the URL couldn't be verified synchronously, defer starting the
53 // request until the check has completed.
54 defer_state_ = DEFERRED_START;
55 *defer = true;
58 void SafeBrowsingResourceThrottle::WillRedirectRequest(
59 const net::RedirectInfo& redirect_info,
60 bool* defer) {
61 CHECK(state_ == STATE_NONE);
62 CHECK(defer_state_ == DEFERRED_NONE);
64 // Save the redirect urls for possible malware detail reporting later.
65 redirect_urls_.push_back(redirect_info.new_url);
67 // We need to check the new URL before following the redirect.
68 if (CheckUrl(redirect_info.new_url))
69 return;
71 // If the URL couldn't be verified synchronously, defer following the
72 // redirect until the SafeBrowsing check is complete. Store the redirect
73 // context so we can pass it on to other handlers once we have completed
74 // our check.
75 defer_state_ = DEFERRED_REDIRECT;
76 *defer = true;
79 const char* SafeBrowsingResourceThrottle::GetNameForLogging() const {
80 return "SafeBrowsingResourceThrottle";
83 // SafeBrowsingService::Client implementation, called on the IO thread once
84 // the URL has been classified.
85 void SafeBrowsingResourceThrottle::OnCheckBrowseUrlResult(
86 const GURL& url,
87 SBThreatType threat_type,
88 const std::string& metadata) {
89 CHECK(state_ == STATE_CHECKING_URL);
90 CHECK(defer_state_ != DEFERRED_NONE);
91 CHECK(url == url_being_checked_) << "Was expecting: " << url_being_checked_
92 << " but got: " << url;
94 #if defined(OS_ANDROID)
95 // Temporarily disable SB interstitial during Finch experiment.
96 // The database check is still exercised, but the interstitial never shown.
97 threat_type = SB_THREAT_TYPE_SAFE;
98 #endif
100 timer_.Stop(); // Cancel the timeout timer.
101 threat_type_ = threat_type;
102 state_ = STATE_NONE;
104 if (threat_type == SB_THREAT_TYPE_SAFE) {
105 // Log how much time the safe browsing check cost us.
106 ui_manager_->LogPauseDelay(base::TimeTicks::Now() - url_check_start_time_);
108 // Continue the request.
109 ResumeRequest();
110 return;
113 if (request_->load_flags() & net::LOAD_PREFETCH) {
114 // Don't prefetch resources that fail safe browsing, disallow
115 // them.
116 controller()->Cancel();
117 return;
120 const content::ResourceRequestInfo* info =
121 content::ResourceRequestInfo::ForRequest(request_);
123 SafeBrowsingUIManager::UnsafeResource resource;
124 resource.url = url;
125 resource.original_url = request_->original_url();
126 resource.redirect_urls = redirect_urls_;
127 resource.is_subresource = is_subresource_;
128 resource.is_subframe = is_subframe_;
129 resource.threat_type = threat_type;
130 resource.threat_metadata = metadata;
131 resource.callback = base::Bind(
132 &SafeBrowsingResourceThrottle::OnBlockingPageComplete, AsWeakPtr());
133 resource.render_process_host_id = info->GetChildID();
134 resource.render_view_id = info->GetRouteID();
136 state_ = STATE_DISPLAYING_BLOCKING_PAGE;
138 content::BrowserThread::PostTask(
139 content::BrowserThread::UI,
140 FROM_HERE,
141 base::Bind(&SafeBrowsingResourceThrottle::StartDisplayingBlockingPage,
142 AsWeakPtr(), ui_manager_, resource));
145 void SafeBrowsingResourceThrottle::StartDisplayingBlockingPage(
146 const base::WeakPtr<SafeBrowsingResourceThrottle>& throttle,
147 scoped_refptr<SafeBrowsingUIManager> ui_manager,
148 const SafeBrowsingUIManager::UnsafeResource& resource) {
149 bool should_show_blocking_page = true;
151 content::RenderViewHost* rvh = content::RenderViewHost::FromID(
152 resource.render_process_host_id, resource.render_view_id);
153 if (rvh) {
154 content::WebContents* web_contents =
155 content::WebContents::FromRenderViewHost(rvh);
156 prerender::PrerenderContents* prerender_contents =
157 prerender::PrerenderContents::FromWebContents(web_contents);
158 if (prerender_contents) {
159 prerender_contents->Destroy(prerender::FINAL_STATUS_SAFE_BROWSING);
160 should_show_blocking_page = false;
163 if (should_show_blocking_page) {
164 ui_manager->DisplayBlockingPage(resource);
165 return;
169 // Tab is gone or it's being prerendered.
170 content::BrowserThread::PostTask(
171 content::BrowserThread::IO,
172 FROM_HERE,
173 base::Bind(&SafeBrowsingResourceThrottle::Cancel, throttle));
176 void SafeBrowsingResourceThrottle::Cancel() {
177 controller()->Cancel();
180 // SafeBrowsingService::UrlCheckCallback implementation, called on the IO
181 // thread when the user has decided to proceed with the current request, or
182 // go back.
183 void SafeBrowsingResourceThrottle::OnBlockingPageComplete(bool proceed) {
184 CHECK(state_ == STATE_DISPLAYING_BLOCKING_PAGE);
185 state_ = STATE_NONE;
187 if (proceed) {
188 threat_type_ = SB_THREAT_TYPE_SAFE;
189 ResumeRequest();
190 } else {
191 controller()->Cancel();
195 bool SafeBrowsingResourceThrottle::CheckUrl(const GURL& url) {
196 CHECK(state_ == STATE_NONE);
197 bool succeeded_synchronously = database_manager_->CheckBrowseUrl(url, this);
198 if (succeeded_synchronously) {
199 threat_type_ = SB_THREAT_TYPE_SAFE;
200 ui_manager_->LogPauseDelay(base::TimeDelta()); // No delay.
201 return true;
204 state_ = STATE_CHECKING_URL;
205 url_being_checked_ = url;
207 // Record the start time of the check.
208 url_check_start_time_ = base::TimeTicks::Now();
210 // Start a timer to abort the check if it takes too long.
211 timer_.Start(FROM_HERE,
212 base::TimeDelta::FromMilliseconds(kCheckUrlTimeoutMs),
213 this, &SafeBrowsingResourceThrottle::OnCheckUrlTimeout);
215 return false;
218 void SafeBrowsingResourceThrottle::OnCheckUrlTimeout() {
219 CHECK(state_ == STATE_CHECKING_URL);
220 CHECK(defer_state_ != DEFERRED_NONE);
222 database_manager_->CancelCheck(this);
223 OnCheckBrowseUrlResult(
224 url_being_checked_, SB_THREAT_TYPE_SAFE, std::string());
227 void SafeBrowsingResourceThrottle::ResumeRequest() {
228 CHECK(state_ == STATE_NONE);
229 CHECK(defer_state_ != DEFERRED_NONE);
231 defer_state_ = DEFERRED_NONE;
232 controller()->Resume();