Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / renderer_host / data_reduction_proxy_resource_throttle_android.cc
blob73cf8379c6c0078e95ec99639736442e37935b27
1 // Copyright 2015 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/data_reduction_proxy_resource_throttle_android.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/profiles/profile_io_data.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/render_view_host.h"
13 #include "content/public/browser/resource_context.h"
14 #include "content/public/browser/resource_controller.h"
15 #include "content/public/browser/resource_request_info.h"
16 #include "content/public/browser/web_contents.h"
17 #include "net/base/load_flags.h"
18 #include "net/http/http_response_headers.h"
19 #include "net/url_request/redirect_info.h"
20 #include "net/url_request/url_request.h"
22 using content::BrowserThread;
23 using content::ResourceThrottle;
25 // TODO(eroman): Downgrade these CHECK()s to DCHECKs once there is more
26 // unit test coverage.
27 // TODO(sgurun) following the comment above, also provide tests for
28 // checking whether the headers are injected correctly and the SPDY proxy
29 // origin is tested properly.
31 const char* DataReductionProxyResourceThrottle::kUnsafeUrlProceedHeader =
32 "X-Unsafe-Url-Proceed";
34 // static
35 DataReductionProxyResourceThrottle*
36 DataReductionProxyResourceThrottle::MaybeCreate(
37 net::URLRequest* request,
38 content::ResourceContext* resource_context,
39 content::ResourceType resource_type,
40 SafeBrowsingService* sb_service) {
41 ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context);
42 // Don't create the throttle if we can't handle the request.
43 if (io_data->IsOffTheRecord() || !io_data->IsDataReductionProxyEnabled() ||
44 request->url().SchemeIsCryptographic()) {
45 return NULL;
48 return new DataReductionProxyResourceThrottle(request, resource_type,
49 sb_service);
52 DataReductionProxyResourceThrottle::DataReductionProxyResourceThrottle(
53 net::URLRequest* request,
54 content::ResourceType resource_type,
55 SafeBrowsingService* safe_browsing)
56 : state_(STATE_NONE),
57 safe_browsing_(safe_browsing),
58 request_(request),
59 is_subresource_(resource_type != content::RESOURCE_TYPE_MAIN_FRAME),
60 is_subframe_(resource_type == content::RESOURCE_TYPE_SUB_FRAME) {
63 DataReductionProxyResourceThrottle::~DataReductionProxyResourceThrottle() { }
65 void DataReductionProxyResourceThrottle::WillRedirectRequest(
66 const net::RedirectInfo& redirect_info,
67 bool* defer) {
68 CHECK(state_ == STATE_NONE);
70 // Save the redirect urls for possible malware detail reporting later.
71 redirect_urls_.push_back(redirect_info.new_url);
73 // We need to check the new URL before following the redirect.
74 SBThreatType threat_type = CheckUrl();
75 if (threat_type == SB_THREAT_TYPE_SAFE)
76 return;
78 if (request_->load_flags() & net::LOAD_PREFETCH) {
79 controller()->Cancel();
80 return;
82 const content::ResourceRequestInfo* info =
83 content::ResourceRequestInfo::ForRequest(request_);
85 state_ = STATE_DISPLAYING_BLOCKING_PAGE;
86 SafeBrowsingUIManager::UnsafeResource unsafe_resource;
87 unsafe_resource.url = redirect_info.new_url;
88 unsafe_resource.original_url = request_->original_url();
89 unsafe_resource.redirect_urls = redirect_urls_;
90 unsafe_resource.is_subresource = is_subresource_;
91 unsafe_resource.is_subframe = is_subframe_;
92 unsafe_resource.threat_type = threat_type;
93 unsafe_resource.callback = base::Bind(
94 &DataReductionProxyResourceThrottle::OnBlockingPageComplete, AsWeakPtr());
95 unsafe_resource.render_process_host_id = info->GetChildID();
96 unsafe_resource.render_view_id = info->GetRouteID();
97 unsafe_resource.threat_source = SafeBrowsingUIManager::FROM_DATA_SAVER;
99 *defer = true;
101 content::BrowserThread::PostTask(
102 content::BrowserThread::UI, FROM_HERE,
103 base::Bind(
104 &DataReductionProxyResourceThrottle::StartDisplayingBlockingPage,
105 AsWeakPtr(), safe_browsing_->ui_manager(), unsafe_resource));
108 const char* DataReductionProxyResourceThrottle::GetNameForLogging() const {
109 return "DataReductionProxyResourceThrottle";
112 // static
113 void DataReductionProxyResourceThrottle::StartDisplayingBlockingPage(
114 const base::WeakPtr<DataReductionProxyResourceThrottle>& throttle,
115 scoped_refptr<SafeBrowsingUIManager> ui_manager,
116 const SafeBrowsingUIManager::UnsafeResource& resource) {
117 DCHECK_CURRENTLY_ON(BrowserThread::UI);
119 content::RenderViewHost* rvh = content::RenderViewHost::FromID(
120 resource.render_process_host_id, resource.render_view_id);
121 if (rvh) {
122 content::WebContents* web_contents =
123 content::WebContents::FromRenderViewHost(rvh);
124 prerender::PrerenderContents* prerender_contents =
125 prerender::PrerenderContents::FromWebContents(web_contents);
126 if (prerender_contents) {
127 prerender_contents->Destroy(prerender::FINAL_STATUS_SAFE_BROWSING);
128 content::BrowserThread::PostTask(
129 content::BrowserThread::IO,
130 FROM_HERE,
131 base::Bind(resource.callback, false));
132 return;
135 ui_manager->DisplayBlockingPage(resource);
138 // SafeBrowsingService::UrlCheckCallback implementation, called on the IO
139 // thread when the user has decided to proceed with the current request, or
140 // go back.
141 void DataReductionProxyResourceThrottle::OnBlockingPageComplete(bool proceed) {
142 CHECK(state_ == STATE_DISPLAYING_BLOCKING_PAGE);
143 state_ = STATE_NONE;
145 if (proceed)
146 ResumeRequest();
147 else
148 controller()->Cancel();
151 SBThreatType DataReductionProxyResourceThrottle::CheckUrl() {
152 SBThreatType result = SB_THREAT_TYPE_SAFE;
154 // TODO(sgurun) Check for spdy proxy origin.
155 if (request_->response_headers() == NULL)
156 return result;
158 if (request_->response_headers()->HasHeader("X-Phishing-Url"))
159 result = SB_THREAT_TYPE_URL_PHISHING;
160 else if (request_->response_headers()->HasHeader("X-Malware-Url"))
161 result = SB_THREAT_TYPE_URL_MALWARE;
163 // If safe browsing is disabled and the request is sent to the DRP server,
164 // we need to break the redirect loop by setting the extra header.
165 if (result != SB_THREAT_TYPE_SAFE && !safe_browsing_->enabled()) {
166 request_->SetExtraRequestHeaderByName(kUnsafeUrlProceedHeader, "1", true);
167 result = SB_THREAT_TYPE_SAFE;
170 return result;
173 void DataReductionProxyResourceThrottle::ResumeRequest() {
174 CHECK(state_ == STATE_NONE);
176 // Inject the header before resuming the request.
177 request_->SetExtraRequestHeaderByName(kUnsafeUrlProceedHeader, "1", true);
178 controller()->Resume();