| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/browser/renderer_host/buffered_resource_handler.h" | 5 #include "chrome/browser/renderer_host/buffered_resource_handler.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/histogram.h" | 9 #include "base/histogram.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 12 #include "chrome/browser/browser_process.h" | 12 #include "chrome/browser/browser_process.h" |
| 13 #include "chrome/browser/chrome_thread.h" | 13 #include "chrome/browser/chrome_thread.h" |
| 14 #include "chrome/browser/renderer_host/download_throttling_resource_handler.h" | 14 #include "chrome/browser/renderer_host/download_throttling_resource_handler.h" |
| 15 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" | 15 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" |
| 16 #include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h" | 16 #include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h" |
| 17 #include "chrome/browser/renderer_host/x509_user_cert_resource_handler.h" |
| 17 #include "chrome/common/url_constants.h" | 18 #include "chrome/common/url_constants.h" |
| 18 #include "net/base/io_buffer.h" | 19 #include "net/base/io_buffer.h" |
| 19 #include "net/base/mime_sniffer.h" | 20 #include "net/base/mime_sniffer.h" |
| 20 #include "net/base/mime_util.h" | 21 #include "net/base/mime_util.h" |
| 21 #include "net/base/net_errors.h" | 22 #include "net/base/net_errors.h" |
| 22 #include "net/http/http_response_headers.h" | 23 #include "net/http/http_response_headers.h" |
| 23 #include "webkit/glue/plugins/plugin_list.h" | 24 #include "webkit/glue/plugins/plugin_list.h" |
| 24 | 25 |
| 25 namespace { | 26 namespace { |
| 26 | 27 |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 return false; | 287 return false; |
| 287 } | 288 } |
| 288 | 289 |
| 289 bool BufferedResourceHandler::CompleteResponseStarted(int request_id, | 290 bool BufferedResourceHandler::CompleteResponseStarted(int request_id, |
| 290 bool in_complete) { | 291 bool in_complete) { |
| 291 // Check to see if we should forward the data from this request to the | 292 // Check to see if we should forward the data from this request to the |
| 292 // download thread. | 293 // download thread. |
| 293 // TODO(paulg): Only download if the context from the renderer allows it. | 294 // TODO(paulg): Only download if the context from the renderer allows it. |
| 294 ResourceDispatcherHostRequestInfo* info = | 295 ResourceDispatcherHostRequestInfo* info = |
| 295 ResourceDispatcherHost::InfoForRequest(request_); | 296 ResourceDispatcherHost::InfoForRequest(request_); |
| 297 std::string mime_type; |
| 298 request_->GetMimeType(&mime_type); |
| 299 |
| 300 // Check if this is an X.509 certificate, if yes, let it be handled |
| 301 // by X509UserCertResourceHandler. |
| 302 if (mime_type == "application/x-x509-user-cert") { |
| 303 |
| 304 // This is entirely similar to how DownloadThrottlingResourceHandler |
| 305 // works except we are doing it for an X.509 client certificates. |
| 306 |
| 307 if (response_->response_head.headers && // Can be NULL if FTP. |
| 308 response_->response_head.headers->response_code() / 100 != 2) { |
| 309 // The response code indicates that this is an error page, but we are |
| 310 // expecting an X.509 user certificate. We follow Firefox here and show |
| 311 // our own error page instead of handling the error page as a |
| 312 // certificate. |
| 313 // TODO(abarth): We should abstract the response_code test, but this kind |
| 314 // of check is scattered throughout our codebase. |
| 315 request_->SimulateError(net::ERR_FILE_NOT_FOUND); |
| 316 return false; |
| 317 } |
| 318 |
| 319 scoped_refptr<X509UserCertResourceHandler> x509_cert_handler = |
| 320 new X509UserCertResourceHandler(host_, request_); |
| 321 |
| 322 if (bytes_read_) { |
| 323 // A Read has already occured and we need to copy the data into the |
| 324 // EventHandler. |
| 325 net::IOBuffer* buf = NULL; |
| 326 int buf_len = 0; |
| 327 x509_cert_handler->OnWillRead(request_id, &buf, &buf_len, bytes_read_); |
| 328 CHECK((buf_len >= bytes_read_) && (bytes_read_ >= 0)); |
| 329 memcpy(buf->data(), read_buffer_->data(), bytes_read_); |
| 330 } |
| 331 |
| 332 // Inform the renderer that this will be handled entirely by the browser. |
| 333 real_handler_->OnResponseStarted(info->request_id(), response_); |
| 334 URLRequestStatus status(URLRequestStatus::HANDLED_EXTERNALLY, 0); |
| 335 real_handler_->OnResponseCompleted(info->request_id(), status, |
| 336 std::string()); |
| 337 |
| 338 // This is handled entirely within the browser, so just reset the handler. |
| 339 real_handler_ = x509_cert_handler; |
| 340 } |
| 296 | 341 |
| 297 if (info->allow_download() && ShouldDownload(NULL)) { | 342 if (info->allow_download() && ShouldDownload(NULL)) { |
| 298 if (response_->response_head.headers && // Can be NULL if FTP. | 343 if (response_->response_head.headers && // Can be NULL if FTP. |
| 299 response_->response_head.headers->response_code() / 100 != 2) { | 344 response_->response_head.headers->response_code() / 100 != 2) { |
| 300 // The response code indicates that this is an error page, but we don't | 345 // The response code indicates that this is an error page, but we don't |
| 301 // know how to display the content. We follow Firefox here and show our | 346 // know how to display the content. We follow Firefox here and show our |
| 302 // own error page instead of triggering a download. | 347 // own error page instead of triggering a download. |
| 303 // TODO(abarth): We should abstract the response_code test, but this kind | 348 // TODO(abarth): We should abstract the response_code test, but this kind |
| 304 // of check is scattered throughout our codebase. | 349 // of check is scattered throughout our codebase. |
| 305 request_->SimulateError(net::ERR_FILE_NOT_FOUND); | 350 request_->SimulateError(net::ERR_FILE_NOT_FOUND); |
| 306 return false; | 351 return false; |
| 307 } | 352 } |
| 308 | 353 |
| 309 info->set_is_download(true); | 354 info->set_is_download(true); |
| 310 | 355 |
| 311 scoped_refptr<DownloadThrottlingResourceHandler> download_handler = | 356 scoped_refptr<DownloadThrottlingResourceHandler> download_handler = |
| 312 new DownloadThrottlingResourceHandler(host_, | 357 new DownloadThrottlingResourceHandler(host_, |
| 313 request_, | 358 request_, |
| 314 request_->url(), | 359 request_->url(), |
| 315 info->child_id(), | 360 info->child_id(), |
| 316 info->route_id(), | 361 info->route_id(), |
| 317 request_id, | 362 request_id, |
| 318 in_complete); | 363 in_complete); |
| 319 if (bytes_read_) { | 364 if (bytes_read_) { |
| 320 // a Read has already occurred and we need to copy the data into the | 365 // A Read has already occurred and we need to copy the data into the |
| 321 // EventHandler. | 366 // EventHandler. |
| 322 net::IOBuffer* buf = NULL; | 367 net::IOBuffer* buf = NULL; |
| 323 int buf_len = 0; | 368 int buf_len = 0; |
| 324 download_handler->OnWillRead(request_id, &buf, &buf_len, bytes_read_); | 369 download_handler->OnWillRead(request_id, &buf, &buf_len, bytes_read_); |
| 325 CHECK((buf_len >= bytes_read_) && (bytes_read_ >= 0)); | 370 CHECK((buf_len >= bytes_read_) && (bytes_read_ >= 0)); |
| 326 memcpy(buf->data(), read_buffer_->data(), bytes_read_); | 371 memcpy(buf->data(), read_buffer_->data(), bytes_read_); |
| 327 } | 372 } |
| 328 | 373 |
| 329 // Send the renderer a response that indicates that the request will be | 374 // Send the renderer a response that indicates that the request will be |
| 330 // handled by an external source (the browser's DownloadManager). | 375 // handled by an external source (the browser's DownloadManager). |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 wait_for_plugins_ = false; | 492 wait_for_plugins_ = false; |
| 448 if (request_) { | 493 if (request_) { |
| 449 ResourceDispatcherHostRequestInfo* info = | 494 ResourceDispatcherHostRequestInfo* info = |
| 450 ResourceDispatcherHost::InfoForRequest(request_); | 495 ResourceDispatcherHost::InfoForRequest(request_); |
| 451 host_->PauseRequest(info->child_id(), info->request_id(), false); | 496 host_->PauseRequest(info->child_id(), info->request_id(), false); |
| 452 if (!CompleteResponseStarted(info->request_id(), false)) | 497 if (!CompleteResponseStarted(info->request_id(), false)) |
| 453 host_->CancelRequest(info->child_id(), info->request_id(), false); | 498 host_->CancelRequest(info->child_id(), info->request_id(), false); |
| 454 } | 499 } |
| 455 Release(); | 500 Release(); |
| 456 } | 501 } |
| OLD | NEW |