Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(378)

Side by Side Diff: content/browser/renderer_host/buffered_resource_handler.cc

Issue 8680036: Move ResourceResponse struct into the Content API, since it's used in Chrome. While at it, I also... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: add gypi changes Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/buffered_resource_handler.h" 5 #include "content/browser/renderer_host/buffered_resource_handler.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "base/string_util.h" 12 #include "base/string_util.h"
13 #include "content/browser/download/download_id_factory.h" 13 #include "content/browser/download/download_id_factory.h"
14 #include "content/browser/download/download_resource_handler.h" 14 #include "content/browser/download/download_resource_handler.h"
15 #include "content/browser/download/download_types.h" 15 #include "content/browser/download/download_types.h"
16 #include "content/browser/plugin_service.h" 16 #include "content/browser/plugin_service.h"
17 #include "content/browser/renderer_host/resource_dispatcher_host.h" 17 #include "content/browser/renderer_host/resource_dispatcher_host.h"
18 #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" 18 #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
19 #include "content/browser/renderer_host/x509_user_cert_resource_handler.h" 19 #include "content/browser/renderer_host/x509_user_cert_resource_handler.h"
20 #include "content/browser/resource_context.h" 20 #include "content/browser/resource_context.h"
21 #include "content/common/resource_response.h"
22 #include "content/public/browser/browser_thread.h" 21 #include "content/public/browser/browser_thread.h"
23 #include "content/public/browser/content_browser_client.h" 22 #include "content/public/browser/content_browser_client.h"
24 #include "content/public/browser/resource_dispatcher_host_delegate.h" 23 #include "content/public/browser/resource_dispatcher_host_delegate.h"
24 #include "content/public/common/resource_response.h"
25 #include "net/base/io_buffer.h" 25 #include "net/base/io_buffer.h"
26 #include "net/base/mime_sniffer.h" 26 #include "net/base/mime_sniffer.h"
27 #include "net/base/mime_util.h" 27 #include "net/base/mime_util.h"
28 #include "net/base/net_errors.h" 28 #include "net/base/net_errors.h"
29 #include "net/http/http_response_headers.h" 29 #include "net/http/http_response_headers.h"
30 #include "webkit/plugins/webplugininfo.h" 30 #include "webkit/plugins/webplugininfo.h"
31 31
32 namespace { 32 namespace {
33 33
34 void RecordSnifferMetrics(bool sniffing_blocked, 34 void RecordSnifferMetrics(bool sniffing_blocked,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 buffering_(false), 71 buffering_(false),
72 finished_(false) { 72 finished_(false) {
73 } 73 }
74 74
75 bool BufferedResourceHandler::OnUploadProgress(int request_id, 75 bool BufferedResourceHandler::OnUploadProgress(int request_id,
76 uint64 position, 76 uint64 position,
77 uint64 size) { 77 uint64 size) {
78 return real_handler_->OnUploadProgress(request_id, position, size); 78 return real_handler_->OnUploadProgress(request_id, position, size);
79 } 79 }
80 80
81 bool BufferedResourceHandler::OnRequestRedirected(int request_id, 81 bool BufferedResourceHandler::OnRequestRedirected(
82 const GURL& new_url, 82 int request_id,
83 ResourceResponse* response, 83 const GURL& new_url,
84 bool* defer) { 84 content::ResourceResponse* response,
85 bool* defer) {
85 return real_handler_->OnRequestRedirected( 86 return real_handler_->OnRequestRedirected(
86 request_id, new_url, response, defer); 87 request_id, new_url, response, defer);
87 } 88 }
88 89
89 bool BufferedResourceHandler::OnResponseStarted(int request_id, 90 bool BufferedResourceHandler::OnResponseStarted(
90 ResourceResponse* response) { 91 int request_id,
92 content::ResourceResponse* response) {
91 response_ = response; 93 response_ = response;
92 if (!DelayResponse()) 94 if (!DelayResponse())
93 return CompleteResponseStarted(request_id, false); 95 return CompleteResponseStarted(request_id, false);
94 return true; 96 return true;
95 } 97 }
96 98
97 bool BufferedResourceHandler::OnResponseCompleted( 99 bool BufferedResourceHandler::OnResponseCompleted(
98 int request_id, 100 int request_id,
99 const net::URLRequestStatus& status, 101 const net::URLRequestStatus& status,
100 const std::string& security_info) { 102 const std::string& security_info) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 std::string mime_type; 170 std::string mime_type;
169 request_->GetMimeType(&mime_type); 171 request_->GetMimeType(&mime_type);
170 172
171 std::string content_type_options; 173 std::string content_type_options;
172 request_->GetResponseHeaderByName("x-content-type-options", 174 request_->GetResponseHeaderByName("x-content-type-options",
173 &content_type_options); 175 &content_type_options);
174 176
175 const bool sniffing_blocked = 177 const bool sniffing_blocked =
176 LowerCaseEqualsASCII(content_type_options, "nosniff"); 178 LowerCaseEqualsASCII(content_type_options, "nosniff");
177 const bool not_modified_status = 179 const bool not_modified_status =
178 response_->response_head.headers && 180 response_->headers && response_->headers->response_code() == 304;
179 response_->response_head.headers->response_code() == 304;
180 const bool we_would_like_to_sniff = not_modified_status ? 181 const bool we_would_like_to_sniff = not_modified_status ?
181 false : net::ShouldSniffMimeType(request_->url(), mime_type); 182 false : net::ShouldSniffMimeType(request_->url(), mime_type);
182 183
183 RecordSnifferMetrics(sniffing_blocked, we_would_like_to_sniff, mime_type); 184 RecordSnifferMetrics(sniffing_blocked, we_would_like_to_sniff, mime_type);
184 185
185 if (!sniffing_blocked && we_would_like_to_sniff) { 186 if (!sniffing_blocked && we_would_like_to_sniff) {
186 // We're going to look at the data before deciding what the content type 187 // We're going to look at the data before deciding what the content type
187 // is. That means we need to delay sending the ResponseStarted message 188 // is. That means we need to delay sending the ResponseStarted message
188 // over the IPC channel. 189 // over the IPC channel.
189 sniff_content_ = true; 190 sniff_content_ = true;
190 VLOG(1) << "To buffer: " << request_->url().spec(); 191 VLOG(1) << "To buffer: " << request_->url().spec();
191 return true; 192 return true;
192 } 193 }
193 194
194 if (sniffing_blocked && mime_type.empty() && !not_modified_status) { 195 if (sniffing_blocked && mime_type.empty() && !not_modified_status) {
195 // Ugg. The server told us not to sniff the content but didn't give us a 196 // Ugg. The server told us not to sniff the content but didn't give us a
196 // mime type. What's a browser to do? Turns out, we're supposed to treat 197 // mime type. What's a browser to do? Turns out, we're supposed to treat
197 // the response as "text/plain". This is the most secure option. 198 // the response as "text/plain". This is the most secure option.
198 mime_type.assign("text/plain"); 199 mime_type.assign("text/plain");
199 response_->response_head.mime_type.assign(mime_type); 200 response_->mime_type.assign(mime_type);
200 } 201 }
201 202
202 if (mime_type == "application/rss+xml" || 203 if (mime_type == "application/rss+xml" ||
203 mime_type == "application/atom+xml") { 204 mime_type == "application/atom+xml") {
204 // Sad face. The server told us that they wanted us to treat the response 205 // Sad face. The server told us that they wanted us to treat the response
205 // as RSS or Atom. Unfortunately, we don't have a built-in feed previewer 206 // as RSS or Atom. Unfortunately, we don't have a built-in feed previewer
206 // like other browsers. We can't just render the content as XML because 207 // like other browsers. We can't just render the content as XML because
207 // web sites let third parties inject arbitrary script into their RSS 208 // web sites let third parties inject arbitrary script into their RSS
208 // feeds. That leaves us with little choice but to practically ignore the 209 // feeds. That leaves us with little choice but to practically ignore the
209 // response. In the future, when we have an RSS feed previewer, we can 210 // response. In the future, when we have an RSS feed previewer, we can
210 // remove this logic. 211 // remove this logic.
211 mime_type.assign("text/plain"); 212 mime_type.assign("text/plain");
212 response_->response_head.mime_type.assign(mime_type); 213 response_->mime_type.assign(mime_type);
213 } 214 }
214 215
215 if (!not_modified_status && ShouldWaitForPlugins()) { 216 if (!not_modified_status && ShouldWaitForPlugins()) {
216 wait_for_plugins_ = true; 217 wait_for_plugins_ = true;
217 return true; 218 return true;
218 } 219 }
219 220
220 return false; 221 return false;
221 } 222 }
222 223
(...skipping 26 matching lines...) Expand all
249 // SniffMimeType() returns false if there is not enough data to determine 250 // SniffMimeType() returns false if there is not enough data to determine
250 // the mime type. However, even if it returns false, it returns a new type 251 // the mime type. However, even if it returns false, it returns a new type
251 // that is probably better than the current one. 252 // that is probably better than the current one.
252 DCHECK_LT(bytes_read_, net::kMaxBytesToSniff); 253 DCHECK_LT(bytes_read_, net::kMaxBytesToSniff);
253 if (!finished_) { 254 if (!finished_) {
254 buffering_ = true; 255 buffering_ = true;
255 return true; 256 return true;
256 } 257 }
257 } 258 }
258 sniff_content_ = false; 259 sniff_content_ = false;
259 response_->response_head.mime_type.assign(new_type); 260 response_->mime_type.assign(new_type);
260 261
261 // We just sniffed the mime type, maybe there is a doctype to process. 262 // We just sniffed the mime type, maybe there is a doctype to process.
262 if (ShouldWaitForPlugins()) 263 if (ShouldWaitForPlugins())
263 wait_for_plugins_ = true; 264 wait_for_plugins_ = true;
264 } 265 }
265 266
266 buffering_ = false; 267 buffering_ = false;
267 268
268 if (wait_for_plugins_) 269 if (wait_for_plugins_)
269 return true; 270 return true;
270 271
271 return false; 272 return false;
272 } 273 }
273 274
274 bool BufferedResourceHandler::CompleteResponseStarted(int request_id, 275 bool BufferedResourceHandler::CompleteResponseStarted(int request_id,
275 bool in_complete) { 276 bool in_complete) {
276 ResourceDispatcherHostRequestInfo* info = 277 ResourceDispatcherHostRequestInfo* info =
277 ResourceDispatcherHost::InfoForRequest(request_); 278 ResourceDispatcherHost::InfoForRequest(request_);
278 std::string mime_type; 279 std::string mime_type;
279 request_->GetMimeType(&mime_type); 280 request_->GetMimeType(&mime_type);
280 281
281 // Check if this is an X.509 certificate, if yes, let it be handled 282 // Check if this is an X.509 certificate, if yes, let it be handled
282 // by X509UserCertResourceHandler. 283 // by X509UserCertResourceHandler.
283 if (mime_type == "application/x-x509-user-cert") { 284 if (mime_type == "application/x-x509-user-cert") {
284 // This is entirely similar to how DownloadThrottlingResourceHandler 285 // This is entirely similar to how DownloadThrottlingResourceHandler
285 // works except we are doing it for an X.509 client certificates. 286 // works except we are doing it for an X.509 client certificates.
286 287
287 if (response_->response_head.headers && // Can be NULL if FTP. 288 if (response_->headers && // Can be NULL if FTP.
288 response_->response_head.headers->response_code() / 100 != 2) { 289 response_->headers->response_code() / 100 != 2) {
289 // The response code indicates that this is an error page, but we are 290 // The response code indicates that this is an error page, but we are
290 // expecting an X.509 user certificate. We follow Firefox here and show 291 // expecting an X.509 user certificate. We follow Firefox here and show
291 // our own error page instead of handling the error page as a 292 // our own error page instead of handling the error page as a
292 // certificate. 293 // certificate.
293 // TODO(abarth): We should abstract the response_code test, but this kind 294 // TODO(abarth): We should abstract the response_code test, but this kind
294 // of check is scattered throughout our codebase. 295 // of check is scattered throughout our codebase.
295 request_->SimulateError(net::ERR_FILE_NOT_FOUND); 296 request_->SimulateError(net::ERR_FILE_NOT_FOUND);
296 return false; 297 return false;
297 } 298 }
298 299
299 X509UserCertResourceHandler* x509_cert_handler = 300 X509UserCertResourceHandler* x509_cert_handler =
300 new X509UserCertResourceHandler(host_, request_, 301 new X509UserCertResourceHandler(host_, request_,
301 info->child_id(), info->route_id()); 302 info->child_id(), info->route_id());
302 UseAlternateResourceHandler(request_id, x509_cert_handler); 303 UseAlternateResourceHandler(request_id, x509_cert_handler);
303 } 304 }
304 305
305 // Check to see if we should forward the data from this request to the 306 // Check to see if we should forward the data from this request to the
306 // download thread. 307 // download thread.
307 // TODO(paulg): Only download if the context from the renderer allows it. 308 // TODO(paulg): Only download if the context from the renderer allows it.
308 if (info->allow_download() && ShouldDownload(NULL)) { 309 if (info->allow_download() && ShouldDownload(NULL)) {
309 if (response_->response_head.headers && // Can be NULL if FTP. 310 if (response_->headers && // Can be NULL if FTP.
310 response_->response_head.headers->response_code() / 100 != 2) { 311 response_->headers->response_code() / 100 != 2) {
311 // The response code indicates that this is an error page, but we don't 312 // The response code indicates that this is an error page, but we don't
312 // know how to display the content. We follow Firefox here and show our 313 // know how to display the content. We follow Firefox here and show our
313 // own error page instead of triggering a download. 314 // own error page instead of triggering a download.
314 // TODO(abarth): We should abstract the response_code test, but this kind 315 // TODO(abarth): We should abstract the response_code test, but this kind
315 // of check is scattered throughout our codebase. 316 // of check is scattered throughout our codebase.
316 request_->SimulateError(net::ERR_FILE_NOT_FOUND); 317 request_->SimulateError(net::ERR_FILE_NOT_FOUND);
317 return false; 318 return false;
318 } 319 }
319 320
320 info->set_is_download(true); 321 info->set_is_download(true);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 PluginService::GetInstance()->GetPlugins( 360 PluginService::GetInstance()->GetPlugins(
360 base::Bind(&BufferedResourceHandler::OnPluginsLoaded, this)); 361 base::Bind(&BufferedResourceHandler::OnPluginsLoaded, this));
361 return true; 362 return true;
362 } 363 }
363 364
364 // This test mirrors the decision that WebKit makes in 365 // This test mirrors the decision that WebKit makes in
365 // WebFrameLoaderClient::dispatchDecidePolicyForMIMEType. 366 // WebFrameLoaderClient::dispatchDecidePolicyForMIMEType.
366 bool BufferedResourceHandler::ShouldDownload(bool* need_plugin_list) { 367 bool BufferedResourceHandler::ShouldDownload(bool* need_plugin_list) {
367 if (need_plugin_list) 368 if (need_plugin_list)
368 *need_plugin_list = false; 369 *need_plugin_list = false;
369 std::string type = StringToLowerASCII(response_->response_head.mime_type); 370 std::string type = StringToLowerASCII(response_->mime_type);
370 std::string disposition; 371 std::string disposition;
371 request_->GetResponseHeaderByName("content-disposition", &disposition); 372 request_->GetResponseHeaderByName("content-disposition", &disposition);
372 disposition = StringToLowerASCII(disposition); 373 disposition = StringToLowerASCII(disposition);
373 374
374 // First, examine content-disposition. 375 // First, examine content-disposition.
375 if (!disposition.empty()) { 376 if (!disposition.empty()) {
376 bool should_download = true; 377 bool should_download = true;
377 378
378 // Some broken sites just send ... 379 // Some broken sites just send ...
379 // Content-Disposition: ; filename="file" 380 // Content-Disposition: ; filename="file"
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 wait_for_plugins_ = false; 469 wait_for_plugins_ = false;
469 if (!request_) 470 if (!request_)
470 return; 471 return;
471 472
472 ResourceDispatcherHostRequestInfo* info = 473 ResourceDispatcherHostRequestInfo* info =
473 ResourceDispatcherHost::InfoForRequest(request_); 474 ResourceDispatcherHost::InfoForRequest(request_);
474 host_->PauseRequest(info->child_id(), info->request_id(), false); 475 host_->PauseRequest(info->child_id(), info->request_id(), false);
475 if (!CompleteResponseStarted(info->request_id(), false)) 476 if (!CompleteResponseStarted(info->request_id(), false))
476 host_->CancelRequest(info->child_id(), info->request_id(), false); 477 host_->CancelRequest(info->child_id(), info->request_id(), false);
477 } 478 }
OLDNEW
« no previous file with comments | « content/browser/renderer_host/buffered_resource_handler.h ('k') | content/browser/renderer_host/cross_site_resource_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698