Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/extensions/api/web_request/web_request_api.h" | 5 #include "chrome/browser/extensions/api/web_request/web_request_api.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 448 } | 448 } |
| 449 | 449 |
| 450 ExtensionWebRequestEventRouter::ExtensionWebRequestEventRouter() | 450 ExtensionWebRequestEventRouter::ExtensionWebRequestEventRouter() |
| 451 : request_time_tracker_(new ExtensionWebRequestTimeTracker) { | 451 : request_time_tracker_(new ExtensionWebRequestTimeTracker) { |
| 452 } | 452 } |
| 453 | 453 |
| 454 ExtensionWebRequestEventRouter::~ExtensionWebRequestEventRouter() { | 454 ExtensionWebRequestEventRouter::~ExtensionWebRequestEventRouter() { |
| 455 } | 455 } |
| 456 | 456 |
| 457 void ExtensionWebRequestEventRouter::RegisterRulesRegistry( | 457 void ExtensionWebRequestEventRouter::RegisterRulesRegistry( |
| 458 void* profile, | |
| 458 scoped_refptr<extensions::WebRequestRulesRegistry> rules_registry) { | 459 scoped_refptr<extensions::WebRequestRulesRegistry> rules_registry) { |
| 459 rules_registry_ = rules_registry; | 460 if (rules_registry.get()) |
| 461 rules_registries_[profile] = rules_registry; | |
| 462 else | |
| 463 rules_registries_.erase(profile); | |
| 460 } | 464 } |
| 461 | 465 |
| 462 int ExtensionWebRequestEventRouter::OnBeforeRequest( | 466 int ExtensionWebRequestEventRouter::OnBeforeRequest( |
| 463 void* profile, | 467 void* profile, |
| 464 ExtensionInfoMap* extension_info_map, | 468 ExtensionInfoMap* extension_info_map, |
| 465 net::URLRequest* request, | 469 net::URLRequest* request, |
| 466 const net::CompletionCallback& callback, | 470 const net::CompletionCallback& callback, |
| 467 GURL* new_url) { | 471 GURL* new_url) { |
| 468 // We hide events from the system context as well as sensitive requests. | 472 // We hide events from the system context as well as sensitive requests. |
| 469 if (!profile || helpers::HideRequest(request)) | 473 if (!profile || WebRequestPermissions::HideRequest(request)) |
| 470 return net::OK; | 474 return net::OK; |
| 471 | 475 |
| 472 if (IsPageLoad(request)) | 476 if (IsPageLoad(request)) |
| 473 NotifyPageLoad(); | 477 NotifyPageLoad(); |
| 474 | 478 |
| 475 request_time_tracker_->LogRequestStartTime(request->identifier(), | 479 request_time_tracker_->LogRequestStartTime(request->identifier(), |
| 476 base::Time::Now(), | 480 base::Time::Now(), |
| 477 request->url(), | 481 request->url(), |
| 478 profile); | 482 profile); |
| 479 | 483 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 518 } | 522 } |
| 519 } | 523 } |
| 520 | 524 |
| 521 int ExtensionWebRequestEventRouter::OnBeforeSendHeaders( | 525 int ExtensionWebRequestEventRouter::OnBeforeSendHeaders( |
| 522 void* profile, | 526 void* profile, |
| 523 ExtensionInfoMap* extension_info_map, | 527 ExtensionInfoMap* extension_info_map, |
| 524 net::URLRequest* request, | 528 net::URLRequest* request, |
| 525 const net::CompletionCallback& callback, | 529 const net::CompletionCallback& callback, |
| 526 net::HttpRequestHeaders* headers) { | 530 net::HttpRequestHeaders* headers) { |
| 527 // We hide events from the system context as well as sensitive requests. | 531 // We hide events from the system context as well as sensitive requests. |
| 528 if (!profile || helpers::HideRequest(request)) | 532 if (!profile || WebRequestPermissions::HideRequest(request)) |
| 529 return net::OK; | 533 return net::OK; |
| 530 | 534 |
| 531 bool initialize_blocked_requests = false; | 535 bool initialize_blocked_requests = false; |
| 532 | 536 |
| 533 initialize_blocked_requests |= | 537 initialize_blocked_requests |= |
| 534 ProcessDeclarativeRules(profile, extension_info_map, | 538 ProcessDeclarativeRules(profile, extension_info_map, |
| 535 keys::kOnBeforeSendHeaders, request, | 539 keys::kOnBeforeSendHeaders, request, |
| 536 extensions::ON_BEFORE_SEND_HEADERS, NULL); | 540 extensions::ON_BEFORE_SEND_HEADERS, NULL); |
| 537 | 541 |
| 538 int extra_info_spec = 0; | 542 int extra_info_spec = 0; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 570 return net::ERR_IO_PENDING; | 574 return net::ERR_IO_PENDING; |
| 571 } | 575 } |
| 572 } | 576 } |
| 573 | 577 |
| 574 void ExtensionWebRequestEventRouter::OnSendHeaders( | 578 void ExtensionWebRequestEventRouter::OnSendHeaders( |
| 575 void* profile, | 579 void* profile, |
| 576 ExtensionInfoMap* extension_info_map, | 580 ExtensionInfoMap* extension_info_map, |
| 577 net::URLRequest* request, | 581 net::URLRequest* request, |
| 578 const net::HttpRequestHeaders& headers) { | 582 const net::HttpRequestHeaders& headers) { |
| 579 // We hide events from the system context as well as sensitive requests. | 583 // We hide events from the system context as well as sensitive requests. |
| 580 if (!profile || helpers::HideRequest(request)) | 584 if (!profile || WebRequestPermissions::HideRequest(request)) |
| 581 return; | 585 return; |
| 582 | 586 |
| 583 if (GetAndSetSignaled(request->identifier(), kOnSendHeaders)) | 587 if (GetAndSetSignaled(request->identifier(), kOnSendHeaders)) |
| 584 return; | 588 return; |
| 585 | 589 |
| 586 ClearSignaled(request->identifier(), kOnBeforeRedirect); | 590 ClearSignaled(request->identifier(), kOnBeforeRedirect); |
| 587 | 591 |
| 588 int extra_info_spec = 0; | 592 int extra_info_spec = 0; |
| 589 std::vector<const EventListener*> listeners = | 593 std::vector<const EventListener*> listeners = |
| 590 GetMatchingListeners(profile, extension_info_map, | 594 GetMatchingListeners(profile, extension_info_map, |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 603 } | 607 } |
| 604 | 608 |
| 605 int ExtensionWebRequestEventRouter::OnHeadersReceived( | 609 int ExtensionWebRequestEventRouter::OnHeadersReceived( |
| 606 void* profile, | 610 void* profile, |
| 607 ExtensionInfoMap* extension_info_map, | 611 ExtensionInfoMap* extension_info_map, |
| 608 net::URLRequest* request, | 612 net::URLRequest* request, |
| 609 const net::CompletionCallback& callback, | 613 const net::CompletionCallback& callback, |
| 610 net::HttpResponseHeaders* original_response_headers, | 614 net::HttpResponseHeaders* original_response_headers, |
| 611 scoped_refptr<net::HttpResponseHeaders>* override_response_headers) { | 615 scoped_refptr<net::HttpResponseHeaders>* override_response_headers) { |
| 612 // We hide events from the system context as well as sensitive requests. | 616 // We hide events from the system context as well as sensitive requests. |
| 613 if (!profile || helpers::HideRequest(request)) | 617 if (!profile || WebRequestPermissions::HideRequest(request)) |
| 614 return net::OK; | 618 return net::OK; |
| 615 | 619 |
| 616 bool initialize_blocked_requests = false; | 620 bool initialize_blocked_requests = false; |
| 617 | 621 |
| 618 initialize_blocked_requests |= | 622 initialize_blocked_requests |= |
| 619 ProcessDeclarativeRules(profile, extension_info_map, | 623 ProcessDeclarativeRules(profile, extension_info_map, |
| 620 keys::kOnHeadersReceived, request, | 624 keys::kOnHeadersReceived, request, |
| 621 extensions::ON_HEADERS_RECEIVED, | 625 extensions::ON_HEADERS_RECEIVED, |
| 622 original_response_headers); | 626 original_response_headers); |
| 623 | 627 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 668 net::NetworkDelegate::AuthRequiredResponse | 672 net::NetworkDelegate::AuthRequiredResponse |
| 669 ExtensionWebRequestEventRouter::OnAuthRequired( | 673 ExtensionWebRequestEventRouter::OnAuthRequired( |
| 670 void* profile, | 674 void* profile, |
| 671 ExtensionInfoMap* extension_info_map, | 675 ExtensionInfoMap* extension_info_map, |
| 672 net::URLRequest* request, | 676 net::URLRequest* request, |
| 673 const net::AuthChallengeInfo& auth_info, | 677 const net::AuthChallengeInfo& auth_info, |
| 674 const net::NetworkDelegate::AuthCallback& callback, | 678 const net::NetworkDelegate::AuthCallback& callback, |
| 675 net::AuthCredentials* credentials) { | 679 net::AuthCredentials* credentials) { |
| 676 // No profile means that this is for authentication challenges in the | 680 // No profile means that this is for authentication challenges in the |
| 677 // system context. Skip in that case. Also skip sensitive requests. | 681 // system context. Skip in that case. Also skip sensitive requests. |
| 678 if (!profile || helpers::HideRequest(request)) | 682 if (!profile || WebRequestPermissions::HideRequest(request)) |
| 679 return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; | 683 return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; |
| 680 | 684 |
| 681 int extra_info_spec = 0; | 685 int extra_info_spec = 0; |
| 682 std::vector<const EventListener*> listeners = | 686 std::vector<const EventListener*> listeners = |
| 683 GetMatchingListeners(profile, extension_info_map, | 687 GetMatchingListeners(profile, extension_info_map, |
| 684 keys::kOnAuthRequired, request, &extra_info_spec); | 688 keys::kOnAuthRequired, request, &extra_info_spec); |
| 685 if (listeners.empty()) | 689 if (listeners.empty()) |
| 686 return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; | 690 return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; |
| 687 | 691 |
| 688 ListValue args; | 692 ListValue args; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 713 } | 717 } |
| 714 return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; | 718 return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; |
| 715 } | 719 } |
| 716 | 720 |
| 717 void ExtensionWebRequestEventRouter::OnBeforeRedirect( | 721 void ExtensionWebRequestEventRouter::OnBeforeRedirect( |
| 718 void* profile, | 722 void* profile, |
| 719 ExtensionInfoMap* extension_info_map, | 723 ExtensionInfoMap* extension_info_map, |
| 720 net::URLRequest* request, | 724 net::URLRequest* request, |
| 721 const GURL& new_location) { | 725 const GURL& new_location) { |
| 722 // We hide events from the system context as well as sensitive requests. | 726 // We hide events from the system context as well as sensitive requests. |
| 723 if (!profile || helpers::HideRequest(request)) | 727 if (!profile || WebRequestPermissions::HideRequest(request)) |
| 724 return; | 728 return; |
| 725 | 729 |
| 726 if (GetAndSetSignaled(request->identifier(), kOnBeforeRedirect)) | 730 if (GetAndSetSignaled(request->identifier(), kOnBeforeRedirect)) |
| 727 return; | 731 return; |
| 728 | 732 |
| 729 ClearSignaled(request->identifier(), kOnBeforeRequest); | 733 ClearSignaled(request->identifier(), kOnBeforeRequest); |
| 730 ClearSignaled(request->identifier(), kOnBeforeSendHeaders); | 734 ClearSignaled(request->identifier(), kOnBeforeSendHeaders); |
| 731 ClearSignaled(request->identifier(), kOnSendHeaders); | 735 ClearSignaled(request->identifier(), kOnSendHeaders); |
| 732 ClearSignaled(request->identifier(), kOnHeadersReceived); | 736 ClearSignaled(request->identifier(), kOnHeadersReceived); |
| 733 | 737 |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 758 args.Append(dict); | 762 args.Append(dict); |
| 759 | 763 |
| 760 DispatchEvent(profile, request, listeners, args); | 764 DispatchEvent(profile, request, listeners, args); |
| 761 } | 765 } |
| 762 | 766 |
| 763 void ExtensionWebRequestEventRouter::OnResponseStarted( | 767 void ExtensionWebRequestEventRouter::OnResponseStarted( |
| 764 void* profile, | 768 void* profile, |
| 765 ExtensionInfoMap* extension_info_map, | 769 ExtensionInfoMap* extension_info_map, |
| 766 net::URLRequest* request) { | 770 net::URLRequest* request) { |
| 767 // We hide events from the system context as well as sensitive requests. | 771 // We hide events from the system context as well as sensitive requests. |
| 768 if (!profile || helpers::HideRequest(request)) | 772 if (!profile || WebRequestPermissions::HideRequest(request)) |
| 769 return; | 773 return; |
| 770 | 774 |
| 771 // OnResponseStarted is even triggered, when the request was cancelled. | 775 // OnResponseStarted is even triggered, when the request was cancelled. |
| 772 if (request->status().status() != net::URLRequestStatus::SUCCESS) | 776 if (request->status().status() != net::URLRequestStatus::SUCCESS) |
| 773 return; | 777 return; |
| 774 | 778 |
| 775 int extra_info_spec = 0; | 779 int extra_info_spec = 0; |
| 776 std::vector<const EventListener*> listeners = | 780 std::vector<const EventListener*> listeners = |
| 777 GetMatchingListeners(profile, extension_info_map, | 781 GetMatchingListeners(profile, extension_info_map, |
| 778 keys::kOnResponseStarted, request, &extra_info_spec); | 782 keys::kOnResponseStarted, request, &extra_info_spec); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 801 args.Append(dict); | 805 args.Append(dict); |
| 802 | 806 |
| 803 DispatchEvent(profile, request, listeners, args); | 807 DispatchEvent(profile, request, listeners, args); |
| 804 } | 808 } |
| 805 | 809 |
| 806 void ExtensionWebRequestEventRouter::OnCompleted( | 810 void ExtensionWebRequestEventRouter::OnCompleted( |
| 807 void* profile, | 811 void* profile, |
| 808 ExtensionInfoMap* extension_info_map, | 812 ExtensionInfoMap* extension_info_map, |
| 809 net::URLRequest* request) { | 813 net::URLRequest* request) { |
| 810 // We hide events from the system context as well as sensitive requests. | 814 // We hide events from the system context as well as sensitive requests. |
| 811 if (!profile || helpers::HideRequest(request)) | 815 if (!profile || WebRequestPermissions::HideRequest(request)) |
| 812 return; | 816 return; |
| 813 | 817 |
| 814 request_time_tracker_->LogRequestEndTime(request->identifier(), | 818 request_time_tracker_->LogRequestEndTime(request->identifier(), |
| 815 base::Time::Now()); | 819 base::Time::Now()); |
| 816 | 820 |
| 817 DCHECK(request->status().status() == net::URLRequestStatus::SUCCESS); | 821 DCHECK(request->status().status() == net::URLRequestStatus::SUCCESS); |
| 818 | 822 |
| 819 DCHECK(!GetAndSetSignaled(request->identifier(), kOnCompleted)); | 823 DCHECK(!GetAndSetSignaled(request->identifier(), kOnCompleted)); |
| 820 | 824 |
| 821 ClearPendingCallbacks(request); | 825 ClearPendingCallbacks(request); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 850 | 854 |
| 851 DispatchEvent(profile, request, listeners, args); | 855 DispatchEvent(profile, request, listeners, args); |
| 852 } | 856 } |
| 853 | 857 |
| 854 void ExtensionWebRequestEventRouter::OnErrorOccurred( | 858 void ExtensionWebRequestEventRouter::OnErrorOccurred( |
| 855 void* profile, | 859 void* profile, |
| 856 ExtensionInfoMap* extension_info_map, | 860 ExtensionInfoMap* extension_info_map, |
| 857 net::URLRequest* request, | 861 net::URLRequest* request, |
| 858 bool started) { | 862 bool started) { |
| 859 // We hide events from the system context as well as sensitive requests. | 863 // We hide events from the system context as well as sensitive requests. |
| 860 if (!profile || helpers::HideRequest(request)) | 864 if (!profile || WebRequestPermissions::HideRequest(request)) |
| 861 return; | 865 return; |
| 862 | 866 |
| 863 request_time_tracker_->LogRequestEndTime(request->identifier(), | 867 request_time_tracker_->LogRequestEndTime(request->identifier(), |
| 864 base::Time::Now()); | 868 base::Time::Now()); |
| 865 | 869 |
| 866 DCHECK(request->status().status() == net::URLRequestStatus::FAILED || | 870 DCHECK(request->status().status() == net::URLRequestStatus::FAILED || |
| 867 request->status().status() == net::URLRequestStatus::CANCELED); | 871 request->status().status() == net::URLRequestStatus::CANCELED); |
| 868 | 872 |
| 869 DCHECK(!GetAndSetSignaled(request->identifier(), kOnErrorOccurred)); | 873 DCHECK(!GetAndSetSignaled(request->identifier(), kOnErrorOccurred)); |
| 870 | 874 |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1039 } | 1043 } |
| 1040 | 1044 |
| 1041 listeners_[profile][event_name].erase(listener); | 1045 listeners_[profile][event_name].erase(listener); |
| 1042 | 1046 |
| 1043 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 1047 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 1044 base::Bind(&ClearCacheOnNavigationOnUI)); | 1048 base::Bind(&ClearCacheOnNavigationOnUI)); |
| 1045 } | 1049 } |
| 1046 | 1050 |
| 1047 void ExtensionWebRequestEventRouter::OnOTRProfileCreated( | 1051 void ExtensionWebRequestEventRouter::OnOTRProfileCreated( |
| 1048 void* original_profile, void* otr_profile) { | 1052 void* original_profile, void* otr_profile) { |
| 1049 cross_profile_map_[original_profile] = otr_profile; | 1053 permissions_.OnOTRProfileCreated(original_profile, otr_profile); |
| 1050 cross_profile_map_[otr_profile] = original_profile; | |
|
Matt Perry
2012/07/25 21:27:56
Why did you move this to the Permissions class? It
battre
2012/07/26 16:38:43
Good point. My original approach looked differentl
| |
| 1051 } | 1054 } |
| 1052 | 1055 |
| 1053 void ExtensionWebRequestEventRouter::OnOTRProfileDestroyed( | 1056 void ExtensionWebRequestEventRouter::OnOTRProfileDestroyed( |
| 1054 void* original_profile, void* otr_profile) { | 1057 void* original_profile, void* otr_profile) { |
| 1055 cross_profile_map_.erase(otr_profile); | 1058 permissions_.OnOTRProfileDestroyed(original_profile, otr_profile); |
| 1056 cross_profile_map_.erase(original_profile); | |
| 1057 } | 1059 } |
| 1058 | 1060 |
| 1059 void ExtensionWebRequestEventRouter::AddCallbackForPageLoad( | 1061 void ExtensionWebRequestEventRouter::AddCallbackForPageLoad( |
| 1060 const base::Closure& callback) { | 1062 const base::Closure& callback) { |
| 1061 callbacks_for_page_load_.push_back(callback); | 1063 callbacks_for_page_load_.push_back(callback); |
| 1062 } | 1064 } |
| 1063 | 1065 |
| 1064 bool ExtensionWebRequestEventRouter::IsPageLoad( | 1066 bool ExtensionWebRequestEventRouter::IsPageLoad( |
| 1065 net::URLRequest* request) const { | 1067 net::URLRequest* request) const { |
| 1066 bool is_main_frame = false; | 1068 bool is_main_frame = false; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1113 continue; | 1115 continue; |
| 1114 if (it->filter.tab_id != -1 && tab_id != it->filter.tab_id) | 1116 if (it->filter.tab_id != -1 && tab_id != it->filter.tab_id) |
| 1115 continue; | 1117 continue; |
| 1116 if (it->filter.window_id != -1 && window_id != it->filter.window_id) | 1118 if (it->filter.window_id != -1 && window_id != it->filter.window_id) |
| 1117 continue; | 1119 continue; |
| 1118 if (!it->filter.types.empty() && | 1120 if (!it->filter.types.empty() && |
| 1119 std::find(it->filter.types.begin(), it->filter.types.end(), | 1121 std::find(it->filter.types.begin(), it->filter.types.end(), |
| 1120 resource_type) == it->filter.types.end()) | 1122 resource_type) == it->filter.types.end()) |
| 1121 continue; | 1123 continue; |
| 1122 | 1124 |
| 1123 // extension_info_map can be NULL if this is a system-level request. | 1125 if (!permissions_.CanExtensionAccessURL( |
| 1124 if (extension_info_map) { | 1126 extension_info_map, it->extension_id, url, crosses_incognito, true)) |
| 1125 const Extension* extension = | 1127 continue; |
| 1126 extension_info_map->extensions().GetByID(it->extension_id); | |
| 1127 | 1128 |
| 1128 // Check if this event crosses incognito boundaries when it shouldn't. | 1129 bool blocking_listener = |
| 1129 if (!extension || | 1130 (it->extra_info_spec & |
| 1130 (crosses_incognito && | 1131 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) != 0; |
| 1131 !extension_info_map->CanCrossIncognito(extension))) | |
| 1132 continue; | |
| 1133 | 1132 |
| 1134 bool blocking_listener = | 1133 // We do not want to notify extensions about XHR requests that are |
| 1135 (it->extra_info_spec & | 1134 // triggered by themselves. This is a workaround to prevent deadlocks |
| 1136 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) != 0; | 1135 // in case of synchronous XHR requests that block the extension renderer |
| 1136 // and therefore prevent the extension from processing the request | |
| 1137 // handler. This is only a problem for blocking listeners. | |
| 1138 // http://crbug.com/105656 | |
| 1139 bool possibly_synchronous_xhr_from_extension = | |
| 1140 is_request_from_extension && resource_type == ResourceType::XHR; | |
| 1137 | 1141 |
| 1138 // We do not want to notify extensions about XHR requests that are | 1142 // Only send webRequest events for URLs the extension has access to. |
| 1139 // triggered by themselves. This is a workaround to prevent deadlocks | 1143 if (blocking_listener && possibly_synchronous_xhr_from_extension) |
| 1140 // in case of synchronous XHR requests that block the extension renderer | 1144 continue; |
| 1141 // and therefore prevent the extension from processing the request | |
| 1142 // handler. This is only a problem for blocking listeners. | |
| 1143 // http://crbug.com/105656 | |
| 1144 bool possibly_synchronous_xhr_from_extension = | |
| 1145 is_request_from_extension && resource_type == ResourceType::XHR; | |
| 1146 | |
| 1147 // Only send webRequest events for URLs the extension has access to. | |
| 1148 if (!helpers::CanExtensionAccessURL(extension, url) || | |
| 1149 (blocking_listener && possibly_synchronous_xhr_from_extension)) { | |
| 1150 continue; | |
| 1151 } | |
| 1152 } | |
| 1153 | 1145 |
| 1154 matching_listeners->push_back(&(*it)); | 1146 matching_listeners->push_back(&(*it)); |
| 1155 *extra_info_spec |= it->extra_info_spec; | 1147 *extra_info_spec |= it->extra_info_spec; |
| 1156 } | 1148 } |
| 1157 } | 1149 } |
| 1158 | 1150 |
| 1159 std::vector<const ExtensionWebRequestEventRouter::EventListener*> | 1151 std::vector<const ExtensionWebRequestEventRouter::EventListener*> |
| 1160 ExtensionWebRequestEventRouter::GetMatchingListeners( | 1152 ExtensionWebRequestEventRouter::GetMatchingListeners( |
| 1161 void* profile, | 1153 void* profile, |
| 1162 ExtensionInfoMap* extension_info_map, | 1154 ExtensionInfoMap* extension_info_map, |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1182 std::vector<const ExtensionWebRequestEventRouter::EventListener*> | 1174 std::vector<const ExtensionWebRequestEventRouter::EventListener*> |
| 1183 matching_listeners; | 1175 matching_listeners; |
| 1184 | 1176 |
| 1185 bool is_request_from_extension = | 1177 bool is_request_from_extension = |
| 1186 IsRequestFromExtension(request, extension_info_map); | 1178 IsRequestFromExtension(request, extension_info_map); |
| 1187 | 1179 |
| 1188 GetMatchingListenersImpl( | 1180 GetMatchingListenersImpl( |
| 1189 profile, extension_info_map, false, event_name, url, | 1181 profile, extension_info_map, false, event_name, url, |
| 1190 tab_id, window_id, resource_type, is_request_from_extension, | 1182 tab_id, window_id, resource_type, is_request_from_extension, |
| 1191 extra_info_spec, &matching_listeners); | 1183 extra_info_spec, &matching_listeners); |
| 1192 CrossProfileMap::const_iterator cross_profile = | 1184 void* cross_profile = permissions_.GetCrossProfile(profile); |
| 1193 cross_profile_map_.find(profile); | 1185 if (cross_profile) { |
| 1194 if (cross_profile != cross_profile_map_.end()) { | |
| 1195 GetMatchingListenersImpl( | 1186 GetMatchingListenersImpl( |
| 1196 cross_profile->second, extension_info_map, true, event_name, url, | 1187 cross_profile, extension_info_map, true, event_name, url, tab_id, |
| 1197 tab_id, window_id, resource_type, is_request_from_extension, | 1188 window_id, resource_type, is_request_from_extension, extra_info_spec, |
| 1198 extra_info_spec, &matching_listeners); | 1189 &matching_listeners); |
| 1199 } | 1190 } |
| 1200 | 1191 |
| 1201 return matching_listeners; | 1192 return matching_listeners; |
| 1202 } | 1193 } |
| 1203 | 1194 |
| 1204 namespace { | 1195 namespace { |
| 1205 | 1196 |
| 1206 helpers::EventResponseDelta* CalculateDelta( | 1197 helpers::EventResponseDelta* CalculateDelta( |
| 1207 ExtensionWebRequestEventRouter::BlockedRequest* blocked_request, | 1198 ExtensionWebRequestEventRouter::BlockedRequest* blocked_request, |
| 1208 ExtensionWebRequestEventRouter::EventResponse* response) { | 1199 ExtensionWebRequestEventRouter::EventResponse* response) { |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1387 net::NetworkDelegate::AuthCallback callback = blocked_request.auth_callback; | 1378 net::NetworkDelegate::AuthCallback callback = blocked_request.auth_callback; |
| 1388 blocked_requests_.erase(request_id); | 1379 blocked_requests_.erase(request_id); |
| 1389 if (call_callback) | 1380 if (call_callback) |
| 1390 callback.Run(response); | 1381 callback.Run(response); |
| 1391 } else { | 1382 } else { |
| 1392 blocked_requests_.erase(request_id); | 1383 blocked_requests_.erase(request_id); |
| 1393 } | 1384 } |
| 1394 return rv; | 1385 return rv; |
| 1395 } | 1386 } |
| 1396 | 1387 |
| 1388 namespace { | |
| 1389 struct RelevantRegistry { | |
|
Matt Perry
2012/07/25 21:27:56
I think you can define this within the function it
battre
2012/07/26 16:38:43
Ok, going for std::pair. I cannot define it in the
| |
| 1390 extensions::WebRequestRulesRegistry* registry; | |
| 1391 bool crosses_incognito; | |
| 1392 }; | |
| 1393 } // namespace | |
| 1394 | |
| 1397 bool ExtensionWebRequestEventRouter::ProcessDeclarativeRules( | 1395 bool ExtensionWebRequestEventRouter::ProcessDeclarativeRules( |
| 1398 void* profile, | 1396 void* profile, |
| 1399 ExtensionInfoMap* extension_info_map, | 1397 ExtensionInfoMap* extension_info_map, |
| 1400 const std::string& event_name, | 1398 const std::string& event_name, |
| 1401 net::URLRequest* request, | 1399 net::URLRequest* request, |
| 1402 extensions::RequestStages request_stage, | 1400 extensions::RequestStages request_stage, |
| 1403 net::HttpResponseHeaders* original_response_headers) { | 1401 net::HttpResponseHeaders* original_response_headers) { |
| 1404 if (!rules_registry_.get()) | 1402 // Rules of the current |profile| may apply but we need to check also whether |
| 1405 return false; | 1403 // there are applicable rules from mode spanning extensions. |
|
Matt Perry
2012/07/25 21:27:56
"mode spanning" -> "spanning mode" or "profile spa
battre
2012/07/26 16:38:43
WDYT of my proposal?
| |
| 1404 | |
| 1405 typedef std::vector<RelevantRegistry> RelevantRegistries; | |
| 1406 RelevantRegistries relevant_registries; | |
| 1407 | |
| 1408 if (rules_registries_.find(profile) != rules_registries_.end()) { | |
| 1409 RelevantRegistry registry = {rules_registries_[profile].get(), false}; | |
| 1410 relevant_registries.push_back(registry); | |
| 1411 } | |
| 1412 | |
| 1413 void* cross_profile = permissions_.GetCrossProfile(profile); | |
| 1414 if (cross_profile && | |
| 1415 rules_registries_.find(cross_profile) != rules_registries_.end()) { | |
| 1416 RelevantRegistry registry = {rules_registries_[cross_profile].get(), true}; | |
| 1417 relevant_registries.push_back(registry); | |
| 1418 } | |
| 1406 | 1419 |
| 1407 // TODO(mpcomplete): Eventually we'll want to turn this on, but for now, | 1420 // TODO(mpcomplete): Eventually we'll want to turn this on, but for now, |
| 1408 // we won't block startup for declarative webrequest. I want to measure | 1421 // we won't block startup for declarative webrequest. I want to measure |
| 1409 // its effect first. | 1422 // its effect first. |
| 1410 #if defined(BLOCK_STARTUP_ON_DECLARATIVE_RULES) | 1423 #if defined(BLOCK_STARTUP_ON_DECLARATIVE_RULES) |
| 1411 if (!rules_registry_->IsReady()) { | 1424 for (RelevantRegistries::iterator i = relevant_registries.begin(); |
| 1412 // The rules registry is still loading. Block this request until it | 1425 i != relevant_registries.end(); ++i) { |
| 1413 // finishes. | 1426 extensions::WebRequestRulesRegistry* rules_registry = i->registry; |
| 1414 rules_registry_->AddReadyCallback( | 1427 if (!rules_registry->IsReady()) { |
| 1415 base::Bind(&ExtensionWebRequestEventRouter::OnRulesRegistryReady, | 1428 // The rules registry is still loading. Block this request until it |
| 1416 AsWeakPtr(), profile, event_name, request->identifier(), | 1429 // finishes. |
| 1417 request_stage)); | 1430 rules_registry->AddReadyCallback( |
| 1418 blocked_requests_[request->identifier()].num_handlers_blocking++; | 1431 base::Bind(&ExtensionWebRequestEventRouter::OnRulesRegistryReady, |
| 1419 blocked_requests_[request->identifier()].request = request; | 1432 AsWeakPtr(), profile, event_name, request->identifier(), |
| 1420 blocked_requests_[request->identifier()].blocking_time = base::Time::Now(); | 1433 request_stage)); |
| 1421 blocked_requests_[request->identifier()].original_response_headers = | 1434 blocked_requests_[request->identifier()].num_handlers_blocking++; |
| 1422 original_response_headers; | 1435 blocked_requests_[request->identifier()].request = request; |
| 1423 blocked_requests_[request->identifier()].extension_info_map = | 1436 blocked_requests_[request->identifier()].blocking_time = |
| 1424 extension_info_map; | 1437 base::Time::Now(); |
| 1425 return true; | 1438 blocked_requests_[request->identifier()].original_response_headers = |
| 1439 original_response_headers; | |
| 1440 blocked_requests_[request->identifier()].extension_info_map = | |
| 1441 extension_info_map; | |
| 1442 return true; | |
| 1443 } | |
| 1426 } | 1444 } |
| 1427 #endif | 1445 #endif |
| 1428 | 1446 |
| 1429 base::Time start = base::Time::Now(); | 1447 base::Time start = base::Time::Now(); |
| 1430 | 1448 |
| 1431 extensions::WebRequestRule::OptionalRequestData optional_request_data; | 1449 bool deltas_created = false; |
| 1432 optional_request_data.original_response_headers = | 1450 for (RelevantRegistries::iterator i = relevant_registries.begin(); |
| 1433 original_response_headers; | 1451 i != relevant_registries.end(); ++i) { |
| 1434 helpers::EventResponseDeltas result = | 1452 extensions::WebRequestRulesRegistry* rules_registry = |
| 1435 rules_registry_->CreateDeltas(extension_info_map, request, | 1453 i->registry; |
| 1436 request_stage, optional_request_data); | 1454 extensions::WebRequestRule::OptionalRequestData optional_request_data; |
| 1455 optional_request_data.original_response_headers = | |
| 1456 original_response_headers; | |
| 1457 helpers::EventResponseDeltas result = | |
| 1458 rules_registry->CreateDeltas(&permissions_, extension_info_map, request, | |
| 1459 i->crosses_incognito, request_stage, optional_request_data); | |
| 1460 | |
| 1461 if (!result.empty()) { | |
| 1462 helpers::EventResponseDeltas& deltas = | |
| 1463 blocked_requests_[request->identifier()].response_deltas; | |
| 1464 deltas.insert(deltas.end(), result.begin(), result.end()); | |
| 1465 deltas_created = true; | |
| 1466 } | |
| 1467 } | |
| 1437 | 1468 |
| 1438 base::TimeDelta elapsed_time = start - base::Time::Now(); | 1469 base::TimeDelta elapsed_time = start - base::Time::Now(); |
| 1439 UMA_HISTOGRAM_TIMES("Extensions.DeclarativeWebRequestNetworkDelay", | 1470 UMA_HISTOGRAM_TIMES("Extensions.DeclarativeWebRequestNetworkDelay", |
| 1440 elapsed_time); | 1471 elapsed_time); |
| 1441 | 1472 |
| 1442 if (result.empty()) | 1473 return deltas_created; |
| 1443 return false; | |
| 1444 | |
| 1445 helpers::EventResponseDeltas& deltas = | |
| 1446 blocked_requests_[request->identifier()].response_deltas; | |
| 1447 deltas.insert(deltas.end(), result.begin(), result.end()); | |
| 1448 return true; | |
| 1449 } | 1474 } |
| 1450 | 1475 |
| 1451 void ExtensionWebRequestEventRouter::OnRulesRegistryReady( | 1476 void ExtensionWebRequestEventRouter::OnRulesRegistryReady( |
| 1452 void* profile, | 1477 void* profile, |
| 1453 const std::string& event_name, | 1478 const std::string& event_name, |
| 1454 uint64 request_id, | 1479 uint64 request_id, |
| 1455 extensions::RequestStages request_stage) { | 1480 extensions::RequestStages request_stage) { |
| 1456 // It's possible that this request was deleted, or cancelled by a previous | 1481 // It's possible that this request was deleted, or cancelled by a previous |
| 1457 // event handler. If so, ignore this response. | 1482 // event handler. If so, ignore this response. |
| 1458 if (blocked_requests_.find(request_id) == blocked_requests_.end()) | 1483 if (blocked_requests_.find(request_id) == blocked_requests_.end()) |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1787 } else if ((*it)->name().find("AdBlock") != std::string::npos) { | 1812 } else if ((*it)->name().find("AdBlock") != std::string::npos) { |
| 1788 adblock = true; | 1813 adblock = true; |
| 1789 } else { | 1814 } else { |
| 1790 other = true; | 1815 other = true; |
| 1791 } | 1816 } |
| 1792 } | 1817 } |
| 1793 } | 1818 } |
| 1794 | 1819 |
| 1795 host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other)); | 1820 host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other)); |
| 1796 } | 1821 } |
| OLD | NEW |