Refactor SharedMemory::Create and fix a rare file leak.
[chromium-blink-merge.git] / chrome / browser / android / spdy_proxy_resource_throttle.cc
blob67d5b3c7dc35ead5f1c5ac6ccae423b6050a20d4
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/android/spdy_proxy_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/renderer_host/safe_browsing_resource_throttle_factory.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 #if defined(SAFE_BROWSING_DB_LOCAL) || defined(SAFE_BROWSING_DB_REMOTE)
23 #include "chrome/browser/profiles/profile_io_data.h"
24 #include "chrome/browser/renderer_host/safe_browsing_resource_throttle.h"
25 #endif
27 using content::BrowserThread;
28 using content::ResourceThrottle;
30 // TODO(eroman): Downgrade these CHECK()s to DCHECKs once there is more
31 // unit test coverage.
32 // TODO(sgurun) following the comment above, also provide tests for
33 // checking whether the headers are injected correctly and the SPDY proxy
34 // origin is tested properly.
36 const char* SpdyProxyResourceThrottle::kUnsafeUrlProceedHeader =
37 "X-Unsafe-Url-Proceed";
39 ResourceThrottle* SpdyProxyResourceThrottleFactory::CreateResourceThrottle(
40 net::URLRequest* request,
41 content::ResourceContext* resource_context,
42 content::ResourceType resource_type,
43 SafeBrowsingService* service) {
44 #if defined(SAFE_BROWSING_DB_LOCAL) || defined(SAFE_BROWSING_DB_REMOTE)
45 ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context);
46 if (io_data->IsOffTheRecord() ||
47 !io_data->IsDataReductionProxyEnabled() ||
48 request->url().SchemeIsSecure())
49 return new SafeBrowsingResourceThrottle(request, resource_type, service);
50 #endif
51 return new SpdyProxyResourceThrottle(request, resource_type, service);
54 SpdyProxyResourceThrottle::SpdyProxyResourceThrottle(
55 net::URLRequest* request,
56 content::ResourceType resource_type,
57 SafeBrowsingService* safe_browsing)
58 : state_(STATE_NONE),
59 safe_browsing_(safe_browsing),
60 request_(request),
61 is_subresource_(resource_type != content::RESOURCE_TYPE_MAIN_FRAME),
62 is_subframe_(resource_type == content::RESOURCE_TYPE_SUB_FRAME) {
65 SpdyProxyResourceThrottle::~SpdyProxyResourceThrottle() { }
67 void SpdyProxyResourceThrottle::WillRedirectRequest(
68 const net::RedirectInfo& redirect_info,
69 bool* defer) {
70 CHECK(state_ == STATE_NONE);
72 // Save the redirect urls for possible malware detail reporting later.
73 redirect_urls_.push_back(redirect_info.new_url);
75 // We need to check the new URL before following the redirect.
76 SBThreatType threat_type = CheckUrl();
77 if (threat_type == SB_THREAT_TYPE_SAFE)
78 return;
80 if (request_->load_flags() & net::LOAD_PREFETCH) {
81 controller()->Cancel();
82 return;
84 const content::ResourceRequestInfo* info =
85 content::ResourceRequestInfo::ForRequest(request_);
87 state_ = STATE_DISPLAYING_BLOCKING_PAGE;
88 SafeBrowsingUIManager::UnsafeResource unsafe_resource;
89 unsafe_resource.url = redirect_info.new_url;
90 unsafe_resource.original_url = request_->original_url();
91 unsafe_resource.redirect_urls = redirect_urls_;
92 unsafe_resource.is_subresource = is_subresource_;
93 unsafe_resource.is_subframe = is_subframe_;
94 unsafe_resource.threat_type = threat_type;
95 unsafe_resource.callback = base::Bind(
96 &SpdyProxyResourceThrottle::OnBlockingPageComplete, AsWeakPtr());
97 unsafe_resource.render_process_host_id = info->GetChildID();
98 unsafe_resource.render_view_id = info->GetRouteID();
100 *defer = true;
102 content::BrowserThread::PostTask(
103 content::BrowserThread::UI,
104 FROM_HERE,
105 base::Bind(&SpdyProxyResourceThrottle::StartDisplayingBlockingPage,
106 AsWeakPtr(),
107 safe_browsing_->ui_manager(),
108 unsafe_resource));
111 const char* SpdyProxyResourceThrottle::GetNameForLogging() const {
112 return "SpdyProxyResourceThrottle";
115 // static
116 void SpdyProxyResourceThrottle::StartDisplayingBlockingPage(
117 const base::WeakPtr<SpdyProxyResourceThrottle>& throttle,
118 scoped_refptr<SafeBrowsingUIManager> ui_manager,
119 const SafeBrowsingUIManager::UnsafeResource& resource) {
120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
122 content::RenderViewHost* rvh = content::RenderViewHost::FromID(
123 resource.render_process_host_id, resource.render_view_id);
124 if (rvh) {
125 content::WebContents* web_contents =
126 content::WebContents::FromRenderViewHost(rvh);
127 prerender::PrerenderContents* prerender_contents =
128 prerender::PrerenderContents::FromWebContents(web_contents);
129 if (prerender_contents) {
130 prerender_contents->Destroy(prerender::FINAL_STATUS_SAFE_BROWSING);
131 content::BrowserThread::PostTask(
132 content::BrowserThread::IO,
133 FROM_HERE,
134 base::Bind(resource.callback, false));
135 return;
138 ui_manager->DisplayBlockingPage(resource);
141 // SafeBrowsingService::UrlCheckCallback implementation, called on the IO
142 // thread when the user has decided to proceed with the current request, or
143 // go back.
144 void SpdyProxyResourceThrottle::OnBlockingPageComplete(bool proceed) {
145 CHECK(state_ == STATE_DISPLAYING_BLOCKING_PAGE);
146 state_ = STATE_NONE;
148 if (proceed)
149 ResumeRequest();
150 else
151 controller()->Cancel();
154 SBThreatType SpdyProxyResourceThrottle::CheckUrl() {
155 SBThreatType result = SB_THREAT_TYPE_SAFE;
157 // TODO(sgurun) Check for spdy proxy origin.
158 if (request_->response_headers() == NULL)
159 return result;
161 if (request_->response_headers()->HasHeader("X-Phishing-Url"))
162 result = SB_THREAT_TYPE_URL_PHISHING;
163 else if (request_->response_headers()->HasHeader("X-Malware-Url"))
164 result = SB_THREAT_TYPE_URL_MALWARE;
166 // If safe browsing is disabled and the request is sent to the DRP server,
167 // we need to break the redirect loop by setting the extra header.
168 if (result != SB_THREAT_TYPE_SAFE && !safe_browsing_->enabled()) {
169 request_->SetExtraRequestHeaderByName(kUnsafeUrlProceedHeader, "1", true);
170 result = SB_THREAT_TYPE_SAFE;
173 return result;
176 void SpdyProxyResourceThrottle::ResumeRequest() {
177 CHECK(state_ == STATE_NONE);
179 // Inject the header before resuming the request.
180 request_->SetExtraRequestHeaderByName(kUnsafeUrlProceedHeader, "1", true);
181 controller()->Resume();