| 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 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1080 | 1084 |
| 1081 void ExtensionWebRequestEventRouter::NotifyPageLoad() { | 1085 void ExtensionWebRequestEventRouter::NotifyPageLoad() { |
| 1082 for (CallbacksForPageLoad::const_iterator i = | 1086 for (CallbacksForPageLoad::const_iterator i = |
| 1083 callbacks_for_page_load_.begin(); | 1087 callbacks_for_page_load_.begin(); |
| 1084 i != callbacks_for_page_load_.end(); ++i) { | 1088 i != callbacks_for_page_load_.end(); ++i) { |
| 1085 i->Run(); | 1089 i->Run(); |
| 1086 } | 1090 } |
| 1087 callbacks_for_page_load_.clear(); | 1091 callbacks_for_page_load_.clear(); |
| 1088 } | 1092 } |
| 1089 | 1093 |
| 1094 void* ExtensionWebRequestEventRouter::GetCrossProfile(void* profile) const { |
| 1095 CrossProfileMap::const_iterator cross_profile = |
| 1096 cross_profile_map_.find(profile); |
| 1097 if (cross_profile == cross_profile_map_.end()) |
| 1098 return NULL; |
| 1099 return cross_profile->second; |
| 1100 } |
| 1101 |
| 1090 void ExtensionWebRequestEventRouter::GetMatchingListenersImpl( | 1102 void ExtensionWebRequestEventRouter::GetMatchingListenersImpl( |
| 1091 void* profile, | 1103 void* profile, |
| 1092 ExtensionInfoMap* extension_info_map, | 1104 ExtensionInfoMap* extension_info_map, |
| 1093 bool crosses_incognito, | 1105 bool crosses_incognito, |
| 1094 const std::string& event_name, | 1106 const std::string& event_name, |
| 1095 const GURL& url, | 1107 const GURL& url, |
| 1096 int tab_id, | 1108 int tab_id, |
| 1097 int window_id, | 1109 int window_id, |
| 1098 ResourceType::Type resource_type, | 1110 ResourceType::Type resource_type, |
| 1099 bool is_request_from_extension, | 1111 bool is_request_from_extension, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1113 continue; | 1125 continue; |
| 1114 if (it->filter.tab_id != -1 && tab_id != it->filter.tab_id) | 1126 if (it->filter.tab_id != -1 && tab_id != it->filter.tab_id) |
| 1115 continue; | 1127 continue; |
| 1116 if (it->filter.window_id != -1 && window_id != it->filter.window_id) | 1128 if (it->filter.window_id != -1 && window_id != it->filter.window_id) |
| 1117 continue; | 1129 continue; |
| 1118 if (!it->filter.types.empty() && | 1130 if (!it->filter.types.empty() && |
| 1119 std::find(it->filter.types.begin(), it->filter.types.end(), | 1131 std::find(it->filter.types.begin(), it->filter.types.end(), |
| 1120 resource_type) == it->filter.types.end()) | 1132 resource_type) == it->filter.types.end()) |
| 1121 continue; | 1133 continue; |
| 1122 | 1134 |
| 1123 // extension_info_map can be NULL if this is a system-level request. | 1135 if (!WebRequestPermissions::CanExtensionAccessURL( |
| 1124 if (extension_info_map) { | 1136 extension_info_map, it->extension_id, url, crosses_incognito, true)) |
| 1125 const Extension* extension = | 1137 continue; |
| 1126 extension_info_map->extensions().GetByID(it->extension_id); | |
| 1127 | 1138 |
| 1128 // Check if this event crosses incognito boundaries when it shouldn't. | 1139 bool blocking_listener = |
| 1129 if (!extension || | 1140 (it->extra_info_spec & |
| 1130 (crosses_incognito && | 1141 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) != 0; |
| 1131 !extension_info_map->CanCrossIncognito(extension))) | |
| 1132 continue; | |
| 1133 | 1142 |
| 1134 bool blocking_listener = | 1143 // We do not want to notify extensions about XHR requests that are |
| 1135 (it->extra_info_spec & | 1144 // triggered by themselves. This is a workaround to prevent deadlocks |
| 1136 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) != 0; | 1145 // in case of synchronous XHR requests that block the extension renderer |
| 1146 // and therefore prevent the extension from processing the request |
| 1147 // handler. This is only a problem for blocking listeners. |
| 1148 // http://crbug.com/105656 |
| 1149 bool possibly_synchronous_xhr_from_extension = |
| 1150 is_request_from_extension && resource_type == ResourceType::XHR; |
| 1137 | 1151 |
| 1138 // We do not want to notify extensions about XHR requests that are | 1152 // Only send webRequest events for URLs the extension has access to. |
| 1139 // triggered by themselves. This is a workaround to prevent deadlocks | 1153 if (blocking_listener && possibly_synchronous_xhr_from_extension) |
| 1140 // in case of synchronous XHR requests that block the extension renderer | 1154 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 | 1155 |
| 1154 matching_listeners->push_back(&(*it)); | 1156 matching_listeners->push_back(&(*it)); |
| 1155 *extra_info_spec |= it->extra_info_spec; | 1157 *extra_info_spec |= it->extra_info_spec; |
| 1156 } | 1158 } |
| 1157 } | 1159 } |
| 1158 | 1160 |
| 1159 std::vector<const ExtensionWebRequestEventRouter::EventListener*> | 1161 std::vector<const ExtensionWebRequestEventRouter::EventListener*> |
| 1160 ExtensionWebRequestEventRouter::GetMatchingListeners( | 1162 ExtensionWebRequestEventRouter::GetMatchingListeners( |
| 1161 void* profile, | 1163 void* profile, |
| 1162 ExtensionInfoMap* extension_info_map, | 1164 ExtensionInfoMap* extension_info_map, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1182 std::vector<const ExtensionWebRequestEventRouter::EventListener*> | 1184 std::vector<const ExtensionWebRequestEventRouter::EventListener*> |
| 1183 matching_listeners; | 1185 matching_listeners; |
| 1184 | 1186 |
| 1185 bool is_request_from_extension = | 1187 bool is_request_from_extension = |
| 1186 IsRequestFromExtension(request, extension_info_map); | 1188 IsRequestFromExtension(request, extension_info_map); |
| 1187 | 1189 |
| 1188 GetMatchingListenersImpl( | 1190 GetMatchingListenersImpl( |
| 1189 profile, extension_info_map, false, event_name, url, | 1191 profile, extension_info_map, false, event_name, url, |
| 1190 tab_id, window_id, resource_type, is_request_from_extension, | 1192 tab_id, window_id, resource_type, is_request_from_extension, |
| 1191 extra_info_spec, &matching_listeners); | 1193 extra_info_spec, &matching_listeners); |
| 1192 CrossProfileMap::const_iterator cross_profile = | 1194 void* cross_profile = GetCrossProfile(profile); |
| 1193 cross_profile_map_.find(profile); | 1195 if (cross_profile) { |
| 1194 if (cross_profile != cross_profile_map_.end()) { | |
| 1195 GetMatchingListenersImpl( | 1196 GetMatchingListenersImpl( |
| 1196 cross_profile->second, extension_info_map, true, event_name, url, | 1197 cross_profile, extension_info_map, true, event_name, url, tab_id, |
| 1197 tab_id, window_id, resource_type, is_request_from_extension, | 1198 window_id, resource_type, is_request_from_extension, extra_info_spec, |
| 1198 extra_info_spec, &matching_listeners); | 1199 &matching_listeners); |
| 1199 } | 1200 } |
| 1200 | 1201 |
| 1201 return matching_listeners; | 1202 return matching_listeners; |
| 1202 } | 1203 } |
| 1203 | 1204 |
| 1204 namespace { | 1205 namespace { |
| 1205 | 1206 |
| 1206 helpers::EventResponseDelta* CalculateDelta( | 1207 helpers::EventResponseDelta* CalculateDelta( |
| 1207 ExtensionWebRequestEventRouter::BlockedRequest* blocked_request, | 1208 ExtensionWebRequestEventRouter::BlockedRequest* blocked_request, |
| 1208 ExtensionWebRequestEventRouter::EventResponse* response) { | 1209 ExtensionWebRequestEventRouter::EventResponse* response) { |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1394 return rv; | 1395 return rv; |
| 1395 } | 1396 } |
| 1396 | 1397 |
| 1397 bool ExtensionWebRequestEventRouter::ProcessDeclarativeRules( | 1398 bool ExtensionWebRequestEventRouter::ProcessDeclarativeRules( |
| 1398 void* profile, | 1399 void* profile, |
| 1399 ExtensionInfoMap* extension_info_map, | 1400 ExtensionInfoMap* extension_info_map, |
| 1400 const std::string& event_name, | 1401 const std::string& event_name, |
| 1401 net::URLRequest* request, | 1402 net::URLRequest* request, |
| 1402 extensions::RequestStages request_stage, | 1403 extensions::RequestStages request_stage, |
| 1403 net::HttpResponseHeaders* original_response_headers) { | 1404 net::HttpResponseHeaders* original_response_headers) { |
| 1404 if (!rules_registry_.get()) | 1405 // Rules of the current |profile| may apply but we need to check also whether |
| 1405 return false; | 1406 // there are applicable rules from extensions whose background page |
| 1407 // spans from regular to incognito mode. |
| 1408 |
| 1409 // First parameter identifies the registry, the second indicates whether the |
| 1410 // registry belongs to the cross profile. |
| 1411 typedef std::pair<extensions::WebRequestRulesRegistry*, bool> |
| 1412 RelevantRegistry; |
| 1413 typedef std::vector<RelevantRegistry> RelevantRegistries; |
| 1414 RelevantRegistries relevant_registries; |
| 1415 |
| 1416 if (rules_registries_.find(profile) != rules_registries_.end()) { |
| 1417 relevant_registries.push_back( |
| 1418 std::make_pair(rules_registries_[profile].get(), false)); |
| 1419 } |
| 1420 |
| 1421 void* cross_profile = GetCrossProfile(profile); |
| 1422 if (cross_profile && |
| 1423 rules_registries_.find(cross_profile) != rules_registries_.end()) { |
| 1424 relevant_registries.push_back( |
| 1425 std::make_pair(rules_registries_[cross_profile].get(), true)); |
| 1426 } |
| 1406 | 1427 |
| 1407 // TODO(mpcomplete): Eventually we'll want to turn this on, but for now, | 1428 // 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 | 1429 // we won't block startup for declarative webrequest. I want to measure |
| 1409 // its effect first. | 1430 // its effect first. |
| 1410 #if defined(BLOCK_STARTUP_ON_DECLARATIVE_RULES) | 1431 #if defined(BLOCK_STARTUP_ON_DECLARATIVE_RULES) |
| 1411 if (!rules_registry_->IsReady()) { | 1432 for (RelevantRegistries::iterator i = relevant_registries.begin(); |
| 1412 // The rules registry is still loading. Block this request until it | 1433 i != relevant_registries.end(); ++i) { |
| 1413 // finishes. | 1434 extensions::WebRequestRulesRegistry* rules_registry = i->first; |
| 1414 rules_registry_->AddReadyCallback( | 1435 if (!rules_registry->IsReady()) { |
| 1415 base::Bind(&ExtensionWebRequestEventRouter::OnRulesRegistryReady, | 1436 // The rules registry is still loading. Block this request until it |
| 1416 AsWeakPtr(), profile, event_name, request->identifier(), | 1437 // finishes. |
| 1417 request_stage)); | 1438 rules_registry->AddReadyCallback( |
| 1418 blocked_requests_[request->identifier()].num_handlers_blocking++; | 1439 base::Bind(&ExtensionWebRequestEventRouter::OnRulesRegistryReady, |
| 1419 blocked_requests_[request->identifier()].request = request; | 1440 AsWeakPtr(), profile, event_name, request->identifier(), |
| 1420 blocked_requests_[request->identifier()].blocking_time = base::Time::Now(); | 1441 request_stage)); |
| 1421 blocked_requests_[request->identifier()].original_response_headers = | 1442 blocked_requests_[request->identifier()].num_handlers_blocking++; |
| 1422 original_response_headers; | 1443 blocked_requests_[request->identifier()].request = request; |
| 1423 blocked_requests_[request->identifier()].extension_info_map = | 1444 blocked_requests_[request->identifier()].blocking_time = |
| 1424 extension_info_map; | 1445 base::Time::Now(); |
| 1425 return true; | 1446 blocked_requests_[request->identifier()].original_response_headers = |
| 1447 original_response_headers; |
| 1448 blocked_requests_[request->identifier()].extension_info_map = |
| 1449 extension_info_map; |
| 1450 return true; |
| 1451 } |
| 1426 } | 1452 } |
| 1427 #endif | 1453 #endif |
| 1428 | 1454 |
| 1429 base::Time start = base::Time::Now(); | 1455 base::Time start = base::Time::Now(); |
| 1430 | 1456 |
| 1431 extensions::WebRequestRule::OptionalRequestData optional_request_data; | 1457 bool deltas_created = false; |
| 1432 optional_request_data.original_response_headers = | 1458 for (RelevantRegistries::iterator i = relevant_registries.begin(); |
| 1433 original_response_headers; | 1459 i != relevant_registries.end(); ++i) { |
| 1434 helpers::EventResponseDeltas result = | 1460 extensions::WebRequestRulesRegistry* rules_registry = |
| 1435 rules_registry_->CreateDeltas(extension_info_map, request, | 1461 i->first; |
| 1436 request_stage, optional_request_data); | 1462 extensions::WebRequestRule::OptionalRequestData optional_request_data; |
| 1463 optional_request_data.original_response_headers = |
| 1464 original_response_headers; |
| 1465 helpers::EventResponseDeltas result = |
| 1466 rules_registry->CreateDeltas(extension_info_map, request, |
| 1467 i->second, request_stage, optional_request_data); |
| 1468 |
| 1469 if (!result.empty()) { |
| 1470 helpers::EventResponseDeltas& deltas = |
| 1471 blocked_requests_[request->identifier()].response_deltas; |
| 1472 deltas.insert(deltas.end(), result.begin(), result.end()); |
| 1473 deltas_created = true; |
| 1474 } |
| 1475 } |
| 1437 | 1476 |
| 1438 base::TimeDelta elapsed_time = start - base::Time::Now(); | 1477 base::TimeDelta elapsed_time = start - base::Time::Now(); |
| 1439 UMA_HISTOGRAM_TIMES("Extensions.DeclarativeWebRequestNetworkDelay", | 1478 UMA_HISTOGRAM_TIMES("Extensions.DeclarativeWebRequestNetworkDelay", |
| 1440 elapsed_time); | 1479 elapsed_time); |
| 1441 | 1480 |
| 1442 if (result.empty()) | 1481 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 } | 1482 } |
| 1450 | 1483 |
| 1451 void ExtensionWebRequestEventRouter::OnRulesRegistryReady( | 1484 void ExtensionWebRequestEventRouter::OnRulesRegistryReady( |
| 1452 void* profile, | 1485 void* profile, |
| 1453 const std::string& event_name, | 1486 const std::string& event_name, |
| 1454 uint64 request_id, | 1487 uint64 request_id, |
| 1455 extensions::RequestStages request_stage) { | 1488 extensions::RequestStages request_stage) { |
| 1456 // It's possible that this request was deleted, or cancelled by a previous | 1489 // It's possible that this request was deleted, or cancelled by a previous |
| 1457 // event handler. If so, ignore this response. | 1490 // event handler. If so, ignore this response. |
| 1458 if (blocked_requests_.find(request_id) == blocked_requests_.end()) | 1491 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) { | 1820 } else if ((*it)->name().find("AdBlock") != std::string::npos) { |
| 1788 adblock = true; | 1821 adblock = true; |
| 1789 } else { | 1822 } else { |
| 1790 other = true; | 1823 other = true; |
| 1791 } | 1824 } |
| 1792 } | 1825 } |
| 1793 } | 1826 } |
| 1794 | 1827 |
| 1795 host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other)); | 1828 host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other)); |
| 1796 } | 1829 } |
| OLD | NEW |