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

Side by Side Diff: chrome/browser/renderer_host/resource_dispatcher_host.cc

Issue 501082: Implement delaying resource requests until privacy blacklists are ready. (Closed)
Patch Set: don't get stuck on errors Created 10 years, 11 months 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
OLDNEW
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
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/blacklist_listener.h"
33 #include "chrome/browser/privacy_blacklist/blacklist_manager.h"
34 #include "chrome/browser/privacy_blacklist/blacklist_request_info.h"
32 #include "chrome/browser/profile.h" 35 #include "chrome/browser/profile.h"
33 #include "chrome/browser/renderer_host/async_resource_handler.h" 36 #include "chrome/browser/renderer_host/async_resource_handler.h"
34 #include "chrome/browser/renderer_host/buffered_resource_handler.h" 37 #include "chrome/browser/renderer_host/buffered_resource_handler.h"
35 #include "chrome/browser/renderer_host/cross_site_resource_handler.h" 38 #include "chrome/browser/renderer_host/cross_site_resource_handler.h"
36 #include "chrome/browser/renderer_host/download_resource_handler.h" 39 #include "chrome/browser/renderer_host/download_resource_handler.h"
37 #include "chrome/browser/renderer_host/global_request_id.h" 40 #include "chrome/browser/renderer_host/global_request_id.h"
38 #include "chrome/browser/renderer_host/render_view_host.h" 41 #include "chrome/browser/renderer_host/render_view_host.h"
39 #include "chrome/browser/renderer_host/render_view_host_delegate.h" 42 #include "chrome/browser/renderer_host/render_view_host_delegate.h"
40 #include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h" 43 #include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h"
41 #include "chrome/browser/renderer_host/resource_queue.h" 44 #include "chrome/browser/renderer_host/resource_queue.h"
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 safe_browsing_(new SafeBrowsingService), 256 safe_browsing_(new SafeBrowsingService),
254 socket_stream_dispatcher_host_(new SocketStreamDispatcherHost), 257 socket_stream_dispatcher_host_(new SocketStreamDispatcherHost),
255 webkit_thread_(new WebKitThread), 258 webkit_thread_(new WebKitThread),
256 request_id_(-1), 259 request_id_(-1),
257 ALLOW_THIS_IN_INITIALIZER_LIST(method_runner_(this)), 260 ALLOW_THIS_IN_INITIALIZER_LIST(method_runner_(this)),
258 is_shutdown_(false), 261 is_shutdown_(false),
259 max_outstanding_requests_cost_per_process_( 262 max_outstanding_requests_cost_per_process_(
260 kMaxOutstandingRequestsCostPerProcess), 263 kMaxOutstandingRequestsCostPerProcess),
261 receiver_(NULL) { 264 receiver_(NULL) {
262 ResourceQueue::DelegateSet resource_queue_delegates; 265 ResourceQueue::DelegateSet resource_queue_delegates;
266 if (CommandLine::ForCurrentProcess()->HasSwitch(
267 switches::kEnablePrivacyBlacklists)) {
268 blacklist_listener_ = new BlacklistListener(&resource_queue_);
269 resource_queue_delegates.insert(blacklist_listener_.get());
270 }
263 resource_queue_delegates.insert(user_script_listener_.get()); 271 resource_queue_delegates.insert(user_script_listener_.get());
264 resource_queue_.Initialize(resource_queue_delegates); 272 resource_queue_.Initialize(resource_queue_delegates);
265 } 273 }
266 274
267 ResourceDispatcherHost::~ResourceDispatcherHost() { 275 ResourceDispatcherHost::~ResourceDispatcherHost() {
268 AsyncResourceHandler::GlobalCleanup(); 276 AsyncResourceHandler::GlobalCleanup();
269 STLDeleteValues(&pending_requests_); 277 STLDeleteValues(&pending_requests_);
270 278
271 // Clear blocked requests if any left. 279 // Clear blocked requests if any left.
272 // Note that we have to do this in 2 passes as we cannot call 280 // Note that we have to do this in 2 passes as we cannot call
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 // Tell the renderer that this request was disallowed. 425 // Tell the renderer that this request was disallowed.
418 receiver_->Send(new ViewMsg_Resource_RequestComplete( 426 receiver_->Send(new ViewMsg_Resource_RequestComplete(
419 route_id, 427 route_id,
420 request_id, 428 request_id,
421 status, 429 status,
422 std::string())); // No security info needed, connection was not 430 std::string())); // No security info needed, connection was not
423 // established. 431 // established.
424 } 432 }
425 return; 433 return;
426 } 434 }
427 std::string url = request_data.url.spec();
428
429 // Note that context can still be NULL here when running unit tests.
430 Blacklist::Match* match = context && context->GetBlacklist() ?
431 context->GetBlacklist()->findMatch(request_data.url) : NULL;
432 if (match && match->IsBlocked(request_data.url)) {
433 // This is a special path where calling happens without the URLRequest
434 // being created, so we must delete the match ourselves. Ensures this
435 // happens by using a scoped pointer.
436 scoped_ptr<Blacklist::Match> match_scope(match);
437
438 URLRequestStatus status(URLRequestStatus::SUCCESS, 0);
439 std::string data =
440 request_data.resource_type != ResourceType::SUB_RESOURCE ?
441 blocked_.GetHTML(url, match) : blocked_.GetImage(match);
442 std::string headers = blocked_.GetHeaders(url);
443
444 if (sync_result) {
445 SyncLoadResult result;
446 result.status = status;
447 result.final_url = request_data.url;
448 result.data.swap(data);
449 ViewHostMsg_SyncLoad::WriteReplyParams(sync_result, result);
450 receiver_->Send(sync_result);
451 } else {
452 bool success = false;
453 base::SharedMemory shared;
454 if (shared.Create(std::wstring(), false, false, data.size())) {
455 if (shared.Map(data.size())) {
456 std::copy(data.c_str(), data.c_str() + data.size(),
457 static_cast<std::string::value_type*>(shared.memory()));
458 base::SharedMemoryHandle handle;
459 if (shared.GiveToProcess(receiver_->handle(), &handle)) {
460 ResourceResponseHead header;
461 header.mime_type = "text/html";
462 header.content_length = -1;
463 header.status = status;
464 header.headers = new net::HttpResponseHeaders(headers);
465 receiver_->Send(new ViewMsg_Resource_ReceivedResponse(
466 route_id, request_id, header));
467 receiver_->Send(new ViewMsg_Resource_DataReceived(
468 route_id, request_id, handle, data.size()));
469 receiver_->Send(new ViewMsg_Resource_RequestComplete(
470 route_id, request_id, status, std::string()));
471 success = true;
472 }
473 }
474 }
475 if (!success) {
476 // Cannot send a substitution response, just cancel.
477 receiver_->Send(new ViewMsg_Resource_RequestComplete(
478 route_id,
479 request_id,
480 URLRequestStatus(URLRequestStatus::CANCELED, net::ERR_ABORTED),
481 std::string()));
482 }
483 }
484 return;
485 }
486 435
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
491 // Ensure the Chrome plugins are loaded, as they may intercept network 436 // Ensure the Chrome plugins are loaded, as they may intercept network
492 // requests. Does nothing if they are already loaded. 437 // requests. Does nothing if they are already loaded.
493 // TODO(mpcomplete): This takes 200 ms! Investigate parallelizing this by 438 // TODO(mpcomplete): This takes 200 ms! Investigate parallelizing this by
494 // starting the load earlier in a BG thread. 439 // starting the load earlier in a BG thread.
495 PluginService::GetInstance()->LoadChromePlugins(this); 440 PluginService::GetInstance()->LoadChromePlugins(this);
496 441
497 // Construct the event handler. 442 // Construct the event handler.
498 scoped_refptr<ResourceHandler> handler; 443 scoped_refptr<ResourceHandler> handler;
499 if (sync_result) { 444 if (sync_result) {
500 handler = new SyncResourceHandler(receiver_, gurl, sync_result); 445 handler = new SyncResourceHandler(receiver_, request_data.url, sync_result);
501 } else { 446 } else {
502 handler = new AsyncResourceHandler(receiver_, 447 handler = new AsyncResourceHandler(receiver_,
503 child_id, 448 child_id,
504 route_id, 449 route_id,
505 receiver_->handle(), 450 receiver_->handle(),
506 gurl, 451 request_data.url,
507 this); 452 this);
508 } 453 }
509 454
510 if (HandleExternalProtocol(request_id, child_id, route_id, 455 if (HandleExternalProtocol(request_id, child_id, route_id,
511 gurl, request_data.resource_type, 456 request_data.url, request_data.resource_type,
512 handler)) { 457 handler)) {
513 return; 458 return;
514 } 459 }
515 460
516 // Construct the request. 461 // Construct the request.
517 URLRequest* request = new URLRequest(gurl, this); 462 URLRequest* request = new URLRequest(request_data.url, this);
518 if (match) {
519 request->SetUserData(&Blacklist::kRequestDataKey, match);
520 }
521 request->set_method(request_data.method); 463 request->set_method(request_data.method);
522 request->set_first_party_for_cookies(request_data.first_party_for_cookies); 464 request->set_first_party_for_cookies(request_data.first_party_for_cookies);
523 465 request->set_referrer(request_data.referrer.spec());
524 if (!match || !(match->attributes() & Blacklist::kDontSendReferrer))
525 request->set_referrer(request_data.referrer.spec());
526
527 request->SetExtraRequestHeaders(request_data.headers); 466 request->SetExtraRequestHeaders(request_data.headers);
528 467
529 int load_flags = request_data.load_flags; 468 int load_flags = request_data.load_flags;
530 // EV certificate verification could be expensive. We don't want to spend 469 // EV certificate verification could be expensive. We don't want to spend
531 // time performing EV certificate verification on all resources because 470 // time performing EV certificate verification on all resources because
532 // EV status is irrelevant to sub-frames and sub-resources. 471 // EV status is irrelevant to sub-frames and sub-resources.
533 if (request_data.resource_type == ResourceType::MAIN_FRAME) 472 if (request_data.resource_type == ResourceType::MAIN_FRAME)
534 load_flags |= net::LOAD_VERIFY_EV_CERT; 473 load_flags |= net::LOAD_VERIFY_EV_CERT;
535 request->set_load_flags(load_flags); 474 request->set_load_flags(load_flags);
536 request->set_context(context); 475 request->set_context(context);
(...skipping 21 matching lines...) Expand all
558 uint64 upload_size = 0; 497 uint64 upload_size = 0;
559 if (request_data.upload_data) { 498 if (request_data.upload_data) {
560 request->set_upload(request_data.upload_data); 499 request->set_upload(request_data.upload_data);
561 upload_size = request_data.upload_data->GetContentLength(); 500 upload_size = request_data.upload_data->GetContentLength();
562 } 501 }
563 502
564 // Install a CrossSiteResourceHandler if this request is coming from a 503 // Install a CrossSiteResourceHandler if this request is coming from a
565 // RenderViewHost with a pending cross-site request. We only check this for 504 // RenderViewHost with a pending cross-site request. We only check this for
566 // MAIN_FRAME requests. Unblock requests only come from a blocked page, do 505 // MAIN_FRAME requests. Unblock requests only come from a blocked page, do
567 // not count as cross-site, otherwise it gets blocked indefinitely. 506 // not count as cross-site, otherwise it gets blocked indefinitely.
568 if (request_data.url.scheme() != chrome::kUnblockScheme && 507 if (request_data.resource_type == ResourceType::MAIN_FRAME &&
569 request_data.resource_type == ResourceType::MAIN_FRAME &&
570 process_type == ChildProcessInfo::RENDER_PROCESS && 508 process_type == ChildProcessInfo::RENDER_PROCESS &&
571 Singleton<CrossSiteRequestManager>::get()-> 509 Singleton<CrossSiteRequestManager>::get()->
572 HasPendingCrossSiteRequest(child_id, route_id)) { 510 HasPendingCrossSiteRequest(child_id, route_id)) {
573 // Wrap the event handler to be sure the current page's onunload handler 511 // Wrap the event handler to be sure the current page's onunload handler
574 // has a chance to run before we render the new page. 512 // has a chance to run before we render the new page.
575 handler = new CrossSiteResourceHandler(handler, 513 handler = new CrossSiteResourceHandler(handler,
576 child_id, 514 child_id,
577 route_id, 515 route_id,
578 this); 516 this);
579 } 517 }
580 518
581 if (safe_browsing_->enabled() && 519 if (safe_browsing_->enabled() &&
582 safe_browsing_->CanCheckUrl(gurl)) { 520 safe_browsing_->CanCheckUrl(request_data.url)) {
583 handler = new SafeBrowsingResourceHandler(handler, 521 handler = new SafeBrowsingResourceHandler(handler,
584 child_id, 522 child_id,
585 route_id, 523 route_id,
586 gurl, 524 request_data.url,
587 request_data.resource_type, 525 request_data.resource_type,
588 safe_browsing_, 526 safe_browsing_,
589 this, 527 this,
590 receiver_); 528 receiver_);
591 } 529 }
592 530
593 // Insert a buffered event handler before the actual one. 531 // Insert a buffered event handler before the actual one.
594 handler = new BufferedResourceHandler(handler, this, request); 532 handler = new BufferedResourceHandler(handler, this, request);
595 533
596 // Make extra info and read footer (contains request ID). 534 // Make extra info and read footer (contains request ID).
(...skipping 14 matching lines...) Expand all
611 request_data.host_render_view_id); 549 request_data.host_render_view_id);
612 SetRequestInfo(request, extra_info); // Request takes ownership. 550 SetRequestInfo(request, extra_info); // Request takes ownership.
613 chrome_browser_net::SetOriginProcessUniqueIDForRequest( 551 chrome_browser_net::SetOriginProcessUniqueIDForRequest(
614 request_data.origin_child_id, request); 552 request_data.origin_child_id, request);
615 553
616 // Have the appcache associate its extra info with the request. 554 // Have the appcache associate its extra info with the request.
617 appcache::AppCacheInterceptor::SetExtraRequestInfo( 555 appcache::AppCacheInterceptor::SetExtraRequestInfo(
618 request, context ? context->appcache_service() : NULL, child_id, 556 request, context ? context->appcache_service() : NULL, child_id,
619 request_data.appcache_host_id, request_data.resource_type); 557 request_data.appcache_host_id, request_data.resource_type);
620 558
559 // Associate Privacy Blacklist information with the request.
560 if (CommandLine::ForCurrentProcess()->HasSwitch(
561 switches::kEnablePrivacyBlacklists)) {
562 request->SetUserData(&BlacklistRequestInfo::kURLRequestDataKey,
563 new BlacklistRequestInfo(request_data.url, request_data.resource_type,
564 context ? context->GetBlacklistManager() : NULL));
565 }
566
621 BeginRequestInternal(request); 567 BeginRequestInternal(request);
622 } 568 }
623 569
624 void ResourceDispatcherHost::OnDataReceivedACK(int request_id) { 570 void ResourceDispatcherHost::OnDataReceivedACK(int request_id) {
625 DataReceivedACK(receiver_->id(), request_id); 571 DataReceivedACK(receiver_->id(), request_id);
626 } 572 }
627 573
628 void ResourceDispatcherHost::DataReceivedACK(int child_id, 574 void ResourceDispatcherHost::DataReceivedACK(int child_id,
629 int request_id) { 575 int request_id) {
630 PendingRequestList::iterator i = pending_requests_.find( 576 PendingRequestList::iterator i = pending_requests_.find(
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after
1140 OnResponseCompleted(request); 1086 OnResponseCompleted(request);
1141 } 1087 }
1142 } 1088 }
1143 1089
1144 bool ResourceDispatcherHost::CompleteResponseStarted(URLRequest* request) { 1090 bool ResourceDispatcherHost::CompleteResponseStarted(URLRequest* request) {
1145 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request); 1091 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request);
1146 1092
1147 scoped_refptr<ResourceResponse> response = new ResourceResponse; 1093 scoped_refptr<ResourceResponse> response = new ResourceResponse;
1148 PopulateResourceResponse(request, info->filter_policy(), response); 1094 PopulateResourceResponse(request, info->filter_policy(), response);
1149 1095
1150 const URLRequest::UserData* d = 1096 BlacklistRequestInfo* request_info =
1151 request->GetUserData(&Blacklist::kRequestDataKey); 1097 BlacklistRequestInfo::FromURLRequest(request);
1152 if (d) { 1098 if (request_info) {
1153 const Blacklist::Match* match = static_cast<const Blacklist::Match*>(d); 1099 const BlacklistManager* blacklist_manager =
1154 if (match->attributes() & Blacklist::kBlockByType) { 1100 request_info->GetBlacklistManager();
1101 const Blacklist* blacklist = blacklist_manager->GetCompiledBlacklist();
1102 scoped_ptr<Blacklist::Match> match(blacklist->findMatch(request->url()));
1103 if (match.get() && match->attributes() & Blacklist::kBlockByType) {
1155 if (match->MatchType(response->response_head.mime_type)) 1104 if (match->MatchType(response->response_head.mime_type))
1156 return false; // TODO(idanan): Generate a replacement response. 1105 return false; // TODO(idanan): Generate a replacement response.
1157 } 1106 }
1158 } 1107 }
1159 1108
1160 if (request->ssl_info().cert) { 1109 if (request->ssl_info().cert) {
1161 int cert_id = 1110 int cert_id =
1162 CertStore::GetSharedInstance()->StoreCert(request->ssl_info().cert, 1111 CertStore::GetSharedInstance()->StoreCert(request->ssl_info().cert,
1163 info->child_id()); 1112 info->child_id());
1164 response->response_head.security_info = 1113 response->response_head.security_info =
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after
1822 case ViewHostMsg_UploadProgress_ACK::ID: 1771 case ViewHostMsg_UploadProgress_ACK::ID:
1823 case ViewHostMsg_SyncLoad::ID: 1772 case ViewHostMsg_SyncLoad::ID:
1824 return true; 1773 return true;
1825 1774
1826 default: 1775 default:
1827 break; 1776 break;
1828 } 1777 }
1829 1778
1830 return false; 1779 return false;
1831 } 1780 }
OLDNEW
« no previous file with comments | « chrome/browser/renderer_host/resource_dispatcher_host.h ('k') | chrome/browser/renderer_host/resource_message_filter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698