Data Reduction Proxy Blocking page and resources
[chromium-blink-merge.git] / chrome / renderer / security_filter_peer.cc
blobe43e7ec7edc687cc82ca6d68c26329c562802faa
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/renderer/security_filter_peer.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/strings/stringprintf.h"
9 #include "chrome/grit/generated_resources.h"
10 #include "net/base/net_errors.h"
11 #include "net/http/http_response_headers.h"
12 #include "ui/base/l10n/l10n_util.h"
14 SecurityFilterPeer::SecurityFilterPeer(content::RequestPeer* peer)
15 : original_peer_(peer) {
18 SecurityFilterPeer::~SecurityFilterPeer() {
21 // static
22 SecurityFilterPeer*
23 SecurityFilterPeer::CreateSecurityFilterPeerForDeniedRequest(
24 content::ResourceType resource_type,
25 content::RequestPeer* peer,
26 int os_error) {
27 // Create a filter for SSL and CERT errors.
28 switch (os_error) {
29 case net::ERR_SSL_PROTOCOL_ERROR:
30 case net::ERR_CERT_COMMON_NAME_INVALID:
31 case net::ERR_CERT_DATE_INVALID:
32 case net::ERR_CERT_AUTHORITY_INVALID:
33 case net::ERR_CERT_CONTAINS_ERRORS:
34 case net::ERR_CERT_NO_REVOCATION_MECHANISM:
35 case net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION:
36 case net::ERR_CERT_REVOKED:
37 case net::ERR_CERT_INVALID:
38 case net::ERR_CERT_WEAK_SIGNATURE_ALGORITHM:
39 case net::ERR_CERT_WEAK_KEY:
40 case net::ERR_CERT_NAME_CONSTRAINT_VIOLATION:
41 case net::ERR_INSECURE_RESPONSE:
42 case net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN:
43 if (content::IsResourceTypeFrame(resource_type))
44 return CreateSecurityFilterPeerForFrame(peer, os_error);
45 // Any other content is entirely filtered-out.
46 return new ReplaceContentPeer(peer, std::string(), std::string());
47 default:
48 // For other errors, we use our normal error handling.
49 return NULL;
53 // static
54 SecurityFilterPeer* SecurityFilterPeer::CreateSecurityFilterPeerForFrame(
55 content::RequestPeer* peer,
56 int os_error) {
57 // TODO(jcampan): use a different message when getting a phishing/malware
58 // error.
59 std::string html = base::StringPrintf(
60 "<html><meta charset='UTF-8'>"
61 "<body style='background-color:#990000;color:white;'>"
62 "%s</body></html>",
63 l10n_util::GetStringUTF8(IDS_UNSAFE_FRAME_MESSAGE).c_str());
64 return new ReplaceContentPeer(peer, "text/html", html);
67 void SecurityFilterPeer::OnUploadProgress(uint64 position, uint64 size) {
68 original_peer_->OnUploadProgress(position, size);
71 bool SecurityFilterPeer::OnReceivedRedirect(
72 const net::RedirectInfo& redirect_info,
73 const content::ResourceResponseInfo& info) {
74 NOTREACHED();
75 return false;
78 void SecurityFilterPeer::OnReceivedResponse(
79 const content::ResourceResponseInfo& info) {
80 NOTREACHED();
83 void SecurityFilterPeer::OnReceivedData(const char* data,
84 int data_length,
85 int encoded_data_length) {
86 NOTREACHED();
89 void SecurityFilterPeer::OnCompletedRequest(
90 int error_code,
91 bool was_ignored_by_handler,
92 bool stale_copy_in_cache,
93 const std::string& security_info,
94 const base::TimeTicks& completion_time,
95 int64 total_transfer_size) {
96 NOTREACHED();
99 // static
100 void ProcessResponseInfo(const content::ResourceResponseInfo& info_in,
101 content::ResourceResponseInfo* info_out,
102 const std::string& mime_type) {
103 DCHECK(info_out);
104 *info_out = info_in;
105 info_out->mime_type = mime_type;
106 // Let's create our own HTTP headers.
107 std::string raw_headers;
108 raw_headers.append("HTTP/1.1 200 OK");
109 raw_headers.push_back('\0');
110 // Don't cache the data we are serving, it is not the real data for that URL
111 // (if the filtered resource were to make it into the WebCore cache, then the
112 // same URL loaded in a safe scenario would still return the filtered
113 // resource).
114 raw_headers.append("cache-control: no-cache");
115 raw_headers.push_back('\0');
116 if (!mime_type.empty()) {
117 raw_headers.append("content-type: ");
118 raw_headers.append(mime_type);
119 raw_headers.push_back('\0');
121 raw_headers.push_back('\0');
122 net::HttpResponseHeaders* new_headers =
123 new net::HttpResponseHeaders(raw_headers);
124 info_out->headers = new_headers;
127 ////////////////////////////////////////////////////////////////////////////////
128 // BufferedPeer
130 BufferedPeer::BufferedPeer(content::RequestPeer* peer,
131 const std::string& mime_type)
132 : SecurityFilterPeer(peer), mime_type_(mime_type) {}
134 BufferedPeer::~BufferedPeer() {
137 void BufferedPeer::OnReceivedResponse(
138 const content::ResourceResponseInfo& info) {
139 ProcessResponseInfo(info, &response_info_, mime_type_);
142 void BufferedPeer::OnReceivedData(const char* data,
143 int data_length,
144 int encoded_data_length) {
145 data_.append(data, data_length);
148 void BufferedPeer::OnCompletedRequest(int error_code,
149 bool was_ignored_by_handler,
150 bool stale_copy_in_cache,
151 const std::string& security_info,
152 const base::TimeTicks& completion_time,
153 int64 total_transfer_size) {
154 // Make sure we delete ourselves at the end of this call.
155 scoped_ptr<BufferedPeer> this_deleter(this);
157 // Give sub-classes a chance at altering the data.
158 if (error_code != net::OK || !DataReady()) {
159 // Pretend we failed to load the resource.
160 original_peer_->OnReceivedResponse(response_info_);
161 original_peer_->OnCompletedRequest(net::ERR_ABORTED, false,
162 stale_copy_in_cache,
163 security_info, completion_time,
164 total_transfer_size);
165 return;
168 original_peer_->OnReceivedResponse(response_info_);
169 if (!data_.empty())
170 original_peer_->OnReceivedData(data_.data(),
171 static_cast<int>(data_.size()),
172 -1);
173 original_peer_->OnCompletedRequest(error_code, was_ignored_by_handler,
174 stale_copy_in_cache, security_info,
175 completion_time, total_transfer_size);
178 ////////////////////////////////////////////////////////////////////////////////
179 // ReplaceContentPeer
181 ReplaceContentPeer::ReplaceContentPeer(content::RequestPeer* peer,
182 const std::string& mime_type,
183 const std::string& data)
184 : SecurityFilterPeer(peer),
185 mime_type_(mime_type),
186 data_(data) {}
188 ReplaceContentPeer::~ReplaceContentPeer() {
191 void ReplaceContentPeer::OnReceivedResponse(
192 const content::ResourceResponseInfo& info) {
193 // Ignore this, we'll serve some alternate content in OnCompletedRequest.
196 void ReplaceContentPeer::OnReceivedData(const char* data,
197 int data_length,
198 int encoded_data_length) {
199 // Ignore this, we'll serve some alternate content in OnCompletedRequest.
202 void ReplaceContentPeer::OnCompletedRequest(
203 int error_code,
204 bool was_ignored_by_handler,
205 bool stale_copy_in_cache,
206 const std::string& security_info,
207 const base::TimeTicks& completion_time,
208 int64 total_transfer_size) {
209 content::ResourceResponseInfo info;
210 ProcessResponseInfo(info, &info, mime_type_);
211 info.security_info = security_info;
212 info.content_length = static_cast<int>(data_.size());
213 original_peer_->OnReceivedResponse(info);
214 if (!data_.empty())
215 original_peer_->OnReceivedData(data_.data(),
216 static_cast<int>(data_.size()),
217 -1);
218 original_peer_->OnCompletedRequest(net::OK,
219 false,
220 stale_copy_in_cache,
221 security_info,
222 completion_time,
223 total_transfer_size);
225 // The request processing is complete, we must delete ourselves.
226 delete this;