Fix build break
[chromium-blink-merge.git] / chrome / browser / renderer_host / safe_browsing_resource_throttle.cc
blob8c9cc6f98c7d3ea7c5836d3b9cae0da36feb7c01
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_tracker.h"
10 #include "chrome/browser/renderer_host/chrome_url_request_user_data.h"
11 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
12 #include "content/public/browser/resource_controller.h"
13 #include "net/base/load_flags.h"
14 #include "net/url_request/url_request.h"
16 // Maximum time in milliseconds to wait for the safe browsing service to
17 // verify a URL. After this amount of time the outstanding check will be
18 // aborted, and the URL will be treated as if it were safe.
19 static const int kCheckUrlTimeoutMs = 5000;
21 // TODO(eroman): Downgrade these CHECK()s to DCHECKs once there is more
22 // unit test coverage.
24 SafeBrowsingResourceThrottle::SafeBrowsingResourceThrottle(
25 const net::URLRequest* request,
26 int render_process_host_id,
27 int render_view_id,
28 bool is_subresource,
29 SafeBrowsingService* safe_browsing)
30 : state_(STATE_NONE),
31 defer_state_(DEFERRED_NONE),
32 threat_type_(SB_THREAT_TYPE_SAFE),
33 render_process_host_id_(render_process_host_id),
34 render_view_id_(render_view_id),
35 database_manager_(safe_browsing->database_manager()),
36 ui_manager_(safe_browsing->ui_manager()),
37 request_(request),
38 is_subresource_(is_subresource) {
41 SafeBrowsingResourceThrottle::~SafeBrowsingResourceThrottle() {
42 if (state_ == STATE_CHECKING_URL)
43 database_manager_->CancelCheck(this);
46 void SafeBrowsingResourceThrottle::WillStartRequest(bool* defer) {
47 // We need to check the new URL before starting the request.
48 if (CheckUrl(request_->url()))
49 return;
51 // If the URL couldn't be verified synchronously, defer starting the
52 // request until the check has completed.
53 defer_state_ = DEFERRED_START;
54 *defer = true;
57 void SafeBrowsingResourceThrottle::WillRedirectRequest(const GURL& new_url,
58 bool* defer) {
59 CHECK(state_ == STATE_NONE);
60 CHECK(defer_state_ == DEFERRED_NONE);
62 // Save the redirect urls for possible malware detail reporting later.
63 redirect_urls_.push_back(new_url);
65 // We need to check the new URL before following the redirect.
66 if (CheckUrl(new_url))
67 return;
69 // If the URL couldn't be verified synchronously, defer following the
70 // redirect until the SafeBrowsing check is complete. Store the redirect
71 // context so we can pass it on to other handlers once we have completed
72 // our check.
73 defer_state_ = DEFERRED_REDIRECT;
74 *defer = true;
77 // SafeBrowsingService::Client implementation, called on the IO thread once
78 // the URL has been classified.
79 void SafeBrowsingResourceThrottle::OnCheckBrowseUrlResult(
80 const GURL& url, SBThreatType threat_type) {
81 CHECK(state_ == STATE_CHECKING_URL);
82 CHECK(defer_state_ != DEFERRED_NONE);
83 CHECK(url == url_being_checked_) << "Was expecting: " << url_being_checked_
84 << " but got: " << url;
86 timer_.Stop(); // Cancel the timeout timer.
87 threat_type_ = threat_type;
88 state_ = STATE_NONE;
90 if (threat_type == SB_THREAT_TYPE_SAFE) {
91 // Log how much time the safe browsing check cost us.
92 ui_manager_->LogPauseDelay(base::TimeTicks::Now() - url_check_start_time_);
94 // Continue the request.
95 ResumeRequest();
96 } else {
97 bool should_show_blocking_page = true;
98 if (request_->load_flags() & net::LOAD_PREFETCH) {
99 // Don't prefetch resources that fail safe browsing, disallow
100 // them.
101 controller()->Cancel();
102 should_show_blocking_page = false;
103 } else {
104 ChromeURLRequestUserData* user_data =
105 ChromeURLRequestUserData::Get(request_);
106 if (user_data && user_data->is_prerender()) {
107 prerender::PrerenderTracker* prerender_tracker = g_browser_process->
108 prerender_tracker();
109 if (prerender_tracker->TryCancelOnIOThread(
110 render_process_host_id_,
111 render_view_id_,
112 prerender::FINAL_STATUS_SAFE_BROWSING)) {
113 controller()->Cancel();
114 should_show_blocking_page = false;
118 if (should_show_blocking_page)
119 StartDisplayingBlockingPage(url, threat_type);
123 void SafeBrowsingResourceThrottle::StartDisplayingBlockingPage(
124 const GURL& url, SBThreatType threat_type) {
125 CHECK(state_ == STATE_NONE);
126 CHECK(defer_state_ != DEFERRED_NONE);
128 state_ = STATE_DISPLAYING_BLOCKING_PAGE;
130 ui_manager_->DisplayBlockingPage(
131 url,
132 request_->original_url(),
133 redirect_urls_,
134 is_subresource_,
135 threat_type,
136 base::Bind(
137 &SafeBrowsingResourceThrottle::OnBlockingPageComplete, AsWeakPtr()),
138 render_process_host_id_,
139 render_view_id_);
142 // SafeBrowsingService::UrlCheckCallback implementation, called on the IO
143 // thread when the user has decided to proceed with the current request, or
144 // go back.
145 void SafeBrowsingResourceThrottle::OnBlockingPageComplete(bool proceed) {
146 CHECK(state_ == STATE_DISPLAYING_BLOCKING_PAGE);
147 state_ = STATE_NONE;
149 if (proceed) {
150 threat_type_ = SB_THREAT_TYPE_SAFE;
151 ResumeRequest();
152 } else {
153 controller()->Cancel();
157 bool SafeBrowsingResourceThrottle::CheckUrl(const GURL& url) {
158 CHECK(state_ == STATE_NONE);
159 bool succeeded_synchronously = database_manager_->CheckBrowseUrl(url, this);
160 if (succeeded_synchronously) {
161 threat_type_ = SB_THREAT_TYPE_SAFE;
162 ui_manager_->LogPauseDelay(base::TimeDelta()); // No delay.
163 return true;
166 state_ = STATE_CHECKING_URL;
167 url_being_checked_ = url;
169 // Record the start time of the check.
170 url_check_start_time_ = base::TimeTicks::Now();
172 // Start a timer to abort the check if it takes too long.
173 timer_.Start(FROM_HERE,
174 base::TimeDelta::FromMilliseconds(kCheckUrlTimeoutMs),
175 this, &SafeBrowsingResourceThrottle::OnCheckUrlTimeout);
177 return false;
180 void SafeBrowsingResourceThrottle::OnCheckUrlTimeout() {
181 CHECK(state_ == STATE_CHECKING_URL);
182 CHECK(defer_state_ != DEFERRED_NONE);
184 database_manager_->CancelCheck(this);
185 OnCheckBrowseUrlResult(url_being_checked_, SB_THREAT_TYPE_SAFE);
188 void SafeBrowsingResourceThrottle::ResumeRequest() {
189 CHECK(state_ == STATE_NONE);
190 CHECK(defer_state_ != DEFERRED_NONE);
192 defer_state_ = DEFERRED_NONE;
193 controller()->Resume();