| 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 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc
e-loading | 5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc
e-loading |
| 6 | 6 |
| 7 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" | 7 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "chrome/browser/download/download_request_manager.h" | 22 #include "chrome/browser/download/download_request_manager.h" |
| 23 #include "chrome/browser/download/save_file_manager.h" | 23 #include "chrome/browser/download/save_file_manager.h" |
| 24 #include "chrome/browser/extensions/user_script_listener.h" | 24 #include "chrome/browser/extensions/user_script_listener.h" |
| 25 #include "chrome/browser/external_protocol_handler.h" | 25 #include "chrome/browser/external_protocol_handler.h" |
| 26 #include "chrome/browser/in_process_webkit/webkit_thread.h" | 26 #include "chrome/browser/in_process_webkit/webkit_thread.h" |
| 27 #include "chrome/browser/login_prompt.h" | 27 #include "chrome/browser/login_prompt.h" |
| 28 #include "chrome/browser/net/chrome_url_request_context.h" | 28 #include "chrome/browser/net/chrome_url_request_context.h" |
| 29 #include "chrome/browser/net/url_request_tracking.h" | 29 #include "chrome/browser/net/url_request_tracking.h" |
| 30 #include "chrome/browser/plugin_service.h" | 30 #include "chrome/browser/plugin_service.h" |
| 31 #include "chrome/browser/privacy_blacklist/blacklist.h" | 31 #include "chrome/browser/privacy_blacklist/blacklist.h" |
| 32 #include "chrome/browser/privacy_blacklist/blocked_response.h" | |
| 33 #include "chrome/browser/profile.h" | 32 #include "chrome/browser/profile.h" |
| 34 #include "chrome/browser/renderer_host/async_resource_handler.h" | 33 #include "chrome/browser/renderer_host/async_resource_handler.h" |
| 35 #include "chrome/browser/renderer_host/buffered_resource_handler.h" | 34 #include "chrome/browser/renderer_host/buffered_resource_handler.h" |
| 36 #include "chrome/browser/renderer_host/cross_site_resource_handler.h" | 35 #include "chrome/browser/renderer_host/cross_site_resource_handler.h" |
| 37 #include "chrome/browser/renderer_host/download_resource_handler.h" | 36 #include "chrome/browser/renderer_host/download_resource_handler.h" |
| 38 #include "chrome/browser/renderer_host/render_view_host.h" | 37 #include "chrome/browser/renderer_host/render_view_host.h" |
| 39 #include "chrome/browser/renderer_host/render_view_host_delegate.h" | 38 #include "chrome/browser/renderer_host/render_view_host_delegate.h" |
| 40 #include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h" | 39 #include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h" |
| 41 #include "chrome/browser/renderer_host/resource_request_details.h" | 40 #include "chrome/browser/renderer_host/resource_request_details.h" |
| 42 #include "chrome/browser/renderer_host/safe_browsing_resource_handler.h" | 41 #include "chrome/browser/renderer_host/safe_browsing_resource_handler.h" |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 // Tell the renderer that this request was disallowed. | 417 // Tell the renderer that this request was disallowed. |
| 419 receiver_->Send(new ViewMsg_Resource_RequestComplete( | 418 receiver_->Send(new ViewMsg_Resource_RequestComplete( |
| 420 route_id, | 419 route_id, |
| 421 request_id, | 420 request_id, |
| 422 status, | 421 status, |
| 423 std::string())); // No security info needed, connection was not | 422 std::string())); // No security info needed, connection was not |
| 424 // established. | 423 // established. |
| 425 } | 424 } |
| 426 return; | 425 return; |
| 427 } | 426 } |
| 427 std::string url = request_data.url.spec(); |
| 428 | 428 |
| 429 // Note that context can still be NULL here when running unit tests. | 429 // Note that context can still be NULL here when running unit tests. |
| 430 Blacklist::Match* match = context && context->blacklist() ? | 430 Blacklist::Match* match = context && context->blacklist() ? |
| 431 context->blacklist()->findMatch(request_data.url) : NULL; | 431 context->blacklist()->findMatch(request_data.url) : NULL; |
| 432 if (match && match->IsBlocked(request_data.url)) { | 432 if (match && match->IsBlocked(request_data.url)) { |
| 433 // This is a special path where calling happens without the URLRequest | 433 // This is a special path where calling happens without the URLRequest |
| 434 // being created, so we must delete the match ourselves. Ensures this | 434 // being created, so we must delete the match ourselves. Ensures this |
| 435 // happens by using a scoped pointer. | 435 // happens by using a scoped pointer. |
| 436 scoped_ptr<Blacklist::Match> match_scope(match); | 436 scoped_ptr<Blacklist::Match> match_scope(match); |
| 437 | 437 |
| 438 URLRequestStatus status(URLRequestStatus::SUCCESS, 0); | 438 URLRequestStatus status(URLRequestStatus::SUCCESS, 0); |
| 439 std::string data = | 439 std::string data = |
| 440 request_data.resource_type != ResourceType::SUB_RESOURCE ? | 440 request_data.resource_type != ResourceType::SUB_RESOURCE ? |
| 441 BlockedResponse::GetHTML(match) : BlockedResponse::GetImage(match); | 441 blocked_.GetHTML(url, match) : blocked_.GetImage(match); |
| 442 std::string headers = blocked_.GetHeaders(url); |
| 442 | 443 |
| 443 if (sync_result) { | 444 if (sync_result) { |
| 444 SyncLoadResult result; | 445 SyncLoadResult result; |
| 445 result.status = status; | 446 result.status = status; |
| 446 result.final_url = request_data.url; | 447 result.final_url = request_data.url; |
| 447 result.data.swap(data); | 448 result.data.swap(data); |
| 448 ViewHostMsg_SyncLoad::WriteReplyParams(sync_result, result); | 449 ViewHostMsg_SyncLoad::WriteReplyParams(sync_result, result); |
| 449 receiver_->Send(sync_result); | 450 receiver_->Send(sync_result); |
| 450 } else { | 451 } else { |
| 451 bool success = false; | 452 bool success = false; |
| 452 base::SharedMemory shared; | 453 base::SharedMemory shared; |
| 453 if (shared.Create(std::wstring(), false, false, data.size())) { | 454 if (shared.Create(std::wstring(), false, false, data.size())) { |
| 454 if (shared.Map(data.size())) { | 455 if (shared.Map(data.size())) { |
| 455 std::copy(data.c_str(), data.c_str() + data.size(), | 456 std::copy(data.c_str(), data.c_str() + data.size(), |
| 456 static_cast<std::string::value_type*>(shared.memory())); | 457 static_cast<std::string::value_type*>(shared.memory())); |
| 457 base::SharedMemoryHandle handle; | 458 base::SharedMemoryHandle handle; |
| 458 if (shared.GiveToProcess(receiver_->handle(), &handle)) { | 459 if (shared.GiveToProcess(receiver_->handle(), &handle)) { |
| 459 ResourceResponseHead header; | 460 ResourceResponseHead header; |
| 460 header.mime_type = "text/html"; | 461 header.mime_type = "text/html"; |
| 461 header.content_length = -1; | 462 header.content_length = -1; |
| 462 header.status = status; | 463 header.status = status; |
| 464 header.headers = new net::HttpResponseHeaders(headers); |
| 463 receiver_->Send(new ViewMsg_Resource_ReceivedResponse( | 465 receiver_->Send(new ViewMsg_Resource_ReceivedResponse( |
| 464 route_id, request_id, header)); | 466 route_id, request_id, header)); |
| 465 receiver_->Send(new ViewMsg_Resource_DataReceived( | 467 receiver_->Send(new ViewMsg_Resource_DataReceived( |
| 466 route_id, request_id, handle, data.size())); | 468 route_id, request_id, handle, data.size())); |
| 467 receiver_->Send(new ViewMsg_Resource_RequestComplete( | 469 receiver_->Send(new ViewMsg_Resource_RequestComplete( |
| 468 route_id, request_id, status, std::string())); | 470 route_id, request_id, status, std::string())); |
| 469 success = true; | 471 success = true; |
| 470 } | 472 } |
| 471 } | 473 } |
| 472 } | 474 } |
| 473 if (!success) { | 475 if (!success) { |
| 474 // Cannot send a substitution response, just cancel. | 476 // Cannot send a substitution response, just cancel. |
| 475 receiver_->Send(new ViewMsg_Resource_RequestComplete( | 477 receiver_->Send(new ViewMsg_Resource_RequestComplete( |
| 476 route_id, | 478 route_id, |
| 477 request_id, | 479 request_id, |
| 478 URLRequestStatus(URLRequestStatus::CANCELED, net::ERR_FAILED), | 480 URLRequestStatus(URLRequestStatus::CANCELED, net::ERR_FAILED), |
| 479 std::string())); | 481 std::string())); |
| 480 } | 482 } |
| 481 } | 483 } |
| 482 return; | 484 return; |
| 483 } | 485 } |
| 484 | 486 |
| 487 // To fetch a blocked resource, convert the unblock URL to the original one. |
| 488 GURL gurl = request_data.url.scheme() != chrome::kUnblockScheme ? |
| 489 request_data.url : GURL(blocked_.GetOriginalURL(url)); |
| 490 |
| 485 // Ensure the Chrome plugins are loaded, as they may intercept network | 491 // Ensure the Chrome plugins are loaded, as they may intercept network |
| 486 // requests. Does nothing if they are already loaded. | 492 // requests. Does nothing if they are already loaded. |
| 487 // TODO(mpcomplete): This takes 200 ms! Investigate parallelizing this by | 493 // TODO(mpcomplete): This takes 200 ms! Investigate parallelizing this by |
| 488 // starting the load earlier in a BG thread. | 494 // starting the load earlier in a BG thread. |
| 489 PluginService::GetInstance()->LoadChromePlugins(this); | 495 PluginService::GetInstance()->LoadChromePlugins(this); |
| 490 | 496 |
| 491 // Construct the event handler. | 497 // Construct the event handler. |
| 492 scoped_refptr<ResourceHandler> handler; | 498 scoped_refptr<ResourceHandler> handler; |
| 493 if (sync_result) { | 499 if (sync_result) { |
| 494 handler = new SyncResourceHandler(receiver_, request_data.url, sync_result); | 500 handler = new SyncResourceHandler(receiver_, gurl, sync_result); |
| 495 } else { | 501 } else { |
| 496 handler = new AsyncResourceHandler(receiver_, | 502 handler = new AsyncResourceHandler(receiver_, |
| 497 child_id, | 503 child_id, |
| 498 route_id, | 504 route_id, |
| 499 receiver_->handle(), | 505 receiver_->handle(), |
| 500 request_data.url, | 506 gurl, |
| 501 this); | 507 this); |
| 502 } | 508 } |
| 503 | 509 |
| 504 if (HandleExternalProtocol(request_id, child_id, route_id, | 510 if (HandleExternalProtocol(request_id, child_id, route_id, |
| 505 request_data.url, request_data.resource_type, | 511 gurl, request_data.resource_type, |
| 506 handler)) { | 512 handler)) { |
| 507 return; | 513 return; |
| 508 } | 514 } |
| 509 | 515 |
| 510 // Construct the request. | 516 // Construct the request. |
| 511 URLRequest* request = new URLRequest(request_data.url, this); | 517 URLRequest* request = new URLRequest(gurl, this); |
| 512 if (match) { | 518 if (match) { |
| 513 request->SetUserData(&Blacklist::kRequestDataKey, match); | 519 request->SetUserData(&Blacklist::kRequestDataKey, match); |
| 514 } | 520 } |
| 515 request->set_method(request_data.method); | 521 request->set_method(request_data.method); |
| 516 request->set_first_party_for_cookies(request_data.first_party_for_cookies); | 522 request->set_first_party_for_cookies(request_data.first_party_for_cookies); |
| 517 | 523 |
| 518 if (!match || !(match->attributes() & Blacklist::kDontSendReferrer)) | 524 if (!match || !(match->attributes() & Blacklist::kDontSendReferrer)) |
| 519 request->set_referrer(request_data.referrer.spec()); | 525 request->set_referrer(request_data.referrer.spec()); |
| 520 | 526 |
| 521 request->SetExtraRequestHeaders(request_data.headers); | 527 request->SetExtraRequestHeaders(request_data.headers); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 543 | 549 |
| 544 // Set upload data. | 550 // Set upload data. |
| 545 uint64 upload_size = 0; | 551 uint64 upload_size = 0; |
| 546 if (request_data.upload_data) { | 552 if (request_data.upload_data) { |
| 547 request->set_upload(request_data.upload_data); | 553 request->set_upload(request_data.upload_data); |
| 548 upload_size = request_data.upload_data->GetContentLength(); | 554 upload_size = request_data.upload_data->GetContentLength(); |
| 549 } | 555 } |
| 550 | 556 |
| 551 // Install a CrossSiteResourceHandler if this request is coming from a | 557 // Install a CrossSiteResourceHandler if this request is coming from a |
| 552 // RenderViewHost with a pending cross-site request. We only check this for | 558 // RenderViewHost with a pending cross-site request. We only check this for |
| 553 // MAIN_FRAME requests. | 559 // MAIN_FRAME requests. Unblock requests only come from a blocked page, do |
| 554 if (request_data.resource_type == ResourceType::MAIN_FRAME && | 560 // not count as cross-site, otherwise it gets blocked indefinitely. |
| 561 if (request_data.url.scheme() != chrome::kUnblockScheme && |
| 562 request_data.resource_type == ResourceType::MAIN_FRAME && |
| 555 process_type == ChildProcessInfo::RENDER_PROCESS && | 563 process_type == ChildProcessInfo::RENDER_PROCESS && |
| 556 Singleton<CrossSiteRequestManager>::get()-> | 564 Singleton<CrossSiteRequestManager>::get()-> |
| 557 HasPendingCrossSiteRequest(child_id, route_id)) { | 565 HasPendingCrossSiteRequest(child_id, route_id)) { |
| 558 // Wrap the event handler to be sure the current page's onunload handler | 566 // Wrap the event handler to be sure the current page's onunload handler |
| 559 // has a chance to run before we render the new page. | 567 // has a chance to run before we render the new page. |
| 560 handler = new CrossSiteResourceHandler(handler, | 568 handler = new CrossSiteResourceHandler(handler, |
| 561 child_id, | 569 child_id, |
| 562 route_id, | 570 route_id, |
| 563 this); | 571 this); |
| 564 } | 572 } |
| 565 | 573 |
| 566 if (safe_browsing_->enabled() && | 574 if (safe_browsing_->enabled() && |
| 567 safe_browsing_->CanCheckUrl(request_data.url)) { | 575 safe_browsing_->CanCheckUrl(gurl)) { |
| 568 handler = new SafeBrowsingResourceHandler(handler, | 576 handler = new SafeBrowsingResourceHandler(handler, |
| 569 child_id, | 577 child_id, |
| 570 route_id, | 578 route_id, |
| 571 request_data.url, | 579 gurl, |
| 572 request_data.resource_type, | 580 request_data.resource_type, |
| 573 safe_browsing_, | 581 safe_browsing_, |
| 574 this, | 582 this, |
| 575 receiver_); | 583 receiver_); |
| 576 } | 584 } |
| 577 | 585 |
| 578 // Insert a buffered event handler before the actual one. | 586 // Insert a buffered event handler before the actual one. |
| 579 handler = new BufferedResourceHandler(handler, this, request); | 587 handler = new BufferedResourceHandler(handler, this, request); |
| 580 | 588 |
| 581 // Make extra info and read footer (contains request ID). | 589 // Make extra info and read footer (contains request ID). |
| (...skipping 1185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1767 case ViewHostMsg_UploadProgress_ACK::ID: | 1775 case ViewHostMsg_UploadProgress_ACK::ID: |
| 1768 case ViewHostMsg_SyncLoad::ID: | 1776 case ViewHostMsg_SyncLoad::ID: |
| 1769 return true; | 1777 return true; |
| 1770 | 1778 |
| 1771 default: | 1779 default: |
| 1772 break; | 1780 break; |
| 1773 } | 1781 } |
| 1774 | 1782 |
| 1775 return false; | 1783 return false; |
| 1776 } | 1784 } |
| OLD | NEW |