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 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 return false; | 288 return false; |
288 } | 289 } |
289 | 290 |
290 bool BufferedResourceHandler::CompleteResponseStarted(int request_id, | 291 bool BufferedResourceHandler::CompleteResponseStarted(int request_id, |
291 bool in_complete) { | 292 bool in_complete) { |
292 // Check to see if we should forward the data from this request to the | 293 // Check to see if we should forward the data from this request to the |
293 // download thread. | 294 // download thread. |
294 // TODO(paulg): Only download if the context from the renderer allows it. | 295 // TODO(paulg): Only download if the context from the renderer allows it. |
295 ResourceDispatcherHostRequestInfo* info = | 296 ResourceDispatcherHostRequestInfo* info = |
296 ResourceDispatcherHost::InfoForRequest(request_); | 297 ResourceDispatcherHost::InfoForRequest(request_); |
| 298 std::string mime_type; |
| 299 request_->GetMimeType(&mime_type); |
| 300 |
| 301 // Check if this is an X509 certificate, if yes, let it be handled |
| 302 // by X509UserCertResourceHandler. |
| 303 if (mime_type == "application/x-x509-user-cert") { |
| 304 |
| 305 // This is entirely similar to how DownloadThrottlingResourceHandler |
| 306 // works except we are doing it for a X509 client certificates. |
| 307 |
| 308 if (response_->response_head.headers && // Can be NULL if FTP. |
| 309 response_->response_head.headers->response_code() / 100 != 2) { |
| 310 // The response code indicates that this is an error page, but we are |
| 311 // expecting a X509 user certificate. We follow Firefox here and show our |
| 312 // own error page instead of handling this resource. |
| 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 } |
297 | 341 |
298 if (info->allow_download() && ShouldDownload(NULL)) { | 342 if (info->allow_download() && ShouldDownload(NULL)) { |
299 if (response_->response_head.headers && // Can be NULL if FTP. | 343 if (response_->response_head.headers && // Can be NULL if FTP. |
300 response_->response_head.headers->response_code() / 100 != 2) { | 344 response_->response_head.headers->response_code() / 100 != 2) { |
301 // 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 |
302 // 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 |
303 // own error page instead of triggering a download. | 347 // own error page instead of triggering a download. |
304 // 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 |
305 // of check is scattered throughout our codebase. | 349 // of check is scattered throughout our codebase. |
306 request_->SimulateError(net::ERR_FILE_NOT_FOUND); | 350 request_->SimulateError(net::ERR_FILE_NOT_FOUND); |
307 return false; | 351 return false; |
308 } | 352 } |
309 | 353 |
310 info->set_is_download(true); | 354 info->set_is_download(true); |
311 | 355 |
312 scoped_refptr<DownloadThrottlingResourceHandler> download_handler = | 356 scoped_refptr<DownloadThrottlingResourceHandler> download_handler = |
313 new DownloadThrottlingResourceHandler(host_, | 357 new DownloadThrottlingResourceHandler(host_, |
314 request_, | 358 request_, |
315 request_->url(), | 359 request_->url(), |
316 info->child_id(), | 360 info->child_id(), |
317 info->route_id(), | 361 info->route_id(), |
318 request_id, | 362 request_id, |
319 in_complete); | 363 in_complete); |
320 if (bytes_read_) { | 364 if (bytes_read_) { |
321 // 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 |
322 // EventHandler. | 366 // EventHandler. |
323 net::IOBuffer* buf = NULL; | 367 net::IOBuffer* buf = NULL; |
324 int buf_len = 0; | 368 int buf_len = 0; |
325 download_handler->OnWillRead(request_id, &buf, &buf_len, bytes_read_); | 369 download_handler->OnWillRead(request_id, &buf, &buf_len, bytes_read_); |
326 CHECK((buf_len >= bytes_read_) && (bytes_read_ >= 0)); | 370 CHECK((buf_len >= bytes_read_) && (bytes_read_ >= 0)); |
327 memcpy(buf->data(), read_buffer_->data(), bytes_read_); | 371 memcpy(buf->data(), read_buffer_->data(), bytes_read_); |
328 } | 372 } |
329 | 373 |
330 // 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 |
331 // 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... |
448 wait_for_plugins_ = false; | 492 wait_for_plugins_ = false; |
449 if (request_) { | 493 if (request_) { |
450 ResourceDispatcherHostRequestInfo* info = | 494 ResourceDispatcherHostRequestInfo* info = |
451 ResourceDispatcherHost::InfoForRequest(request_); | 495 ResourceDispatcherHost::InfoForRequest(request_); |
452 host_->PauseRequest(info->child_id(), info->request_id(), false); | 496 host_->PauseRequest(info->child_id(), info->request_id(), false); |
453 if (!CompleteResponseStarted(info->request_id(), false)) | 497 if (!CompleteResponseStarted(info->request_id(), false)) |
454 host_->CancelRequest(info->child_id(), info->request_id(), false); | 498 host_->CancelRequest(info->child_id(), info->request_id(), false); |
455 } | 499 } |
456 Release(); | 500 Release(); |
457 } | 501 } |
OLD | NEW |