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

Side by Side Diff: extensions/browser/api/web_request/web_request_api.cc

Issue 2344993002: [Merge to 2840] Fix semantics of ExtensionWebRequestEventRouter::EventListeners. (Closed)
Patch Set: Created 4 years, 3 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
« no previous file with comments | « extensions/browser/api/web_request/web_request_api.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "extensions/browser/api/web_request/web_request_api.h" 5 #include "extensions/browser/api/web_request/web_request_api.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <memory> 10 #include <memory>
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 histogram_value = events::DECLARATIVE_WEB_REQUEST_ON_MESSAGE; 264 histogram_value = events::DECLARATIVE_WEB_REQUEST_ON_MESSAGE;
265 event_name = declarative_keys::kOnMessage; 265 event_name = declarative_keys::kOnMessage;
266 } 266 }
267 267
268 std::unique_ptr<Event> event(new Event( 268 std::unique_ptr<Event> event(new Event(
269 histogram_value, event_name, std::move(event_args), browser_context, 269 histogram_value, event_name, std::move(event_args), browser_context,
270 GURL(), EventRouter::USER_GESTURE_UNKNOWN, event_filtering_info)); 270 GURL(), EventRouter::USER_GESTURE_UNKNOWN, event_filtering_info));
271 event_router->DispatchEventToExtension(extension_id, std::move(event)); 271 event_router->DispatchEventToExtension(extension_id, std::move(event));
272 } 272 }
273 273
274 void RemoveEventListenerOnIOThread(
275 void* browser_context,
276 const std::string& extension_id,
277 const std::string& sub_event_name,
278 int embedder_process_id,
279 int web_view_instance_id) {
280 DCHECK_CURRENTLY_ON(BrowserThread::IO);
281 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener(
282 browser_context, extension_id, sub_event_name,
283 embedder_process_id, web_view_instance_id);
284 }
285
286 events::HistogramValue GetEventHistogramValue(const std::string& event_name) { 274 events::HistogramValue GetEventHistogramValue(const std::string& event_name) {
287 // Event names will either be webRequest events, or guest view (probably web 275 // Event names will either be webRequest events, or guest view (probably web
288 // view) events that map to webRequest events. Check webRequest first. 276 // view) events that map to webRequest events. Check webRequest first.
289 static struct ValueAndName { 277 static struct ValueAndName {
290 events::HistogramValue histogram_value; 278 events::HistogramValue histogram_value;
291 const char* const event_name; 279 const char* const event_name;
292 } values_and_names[] = { 280 } values_and_names[] = {
293 {events::WEB_REQUEST_ON_BEFORE_REDIRECT, keys::kOnBeforeRedirectEvent}, 281 {events::WEB_REQUEST_ON_BEFORE_REDIRECT, keys::kOnBeforeRedirectEvent},
294 {events::WEB_REQUEST_ON_BEFORE_REQUEST, 282 {events::WEB_REQUEST_ON_BEFORE_REQUEST,
295 web_request::OnBeforeRequest::kEventName}, 283 web_request::OnBeforeRequest::kEventName},
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 } 348 }
361 349
362 void WebRequestAPI::OnListenerRemoved(const EventListenerInfo& details) { 350 void WebRequestAPI::OnListenerRemoved(const EventListenerInfo& details) {
363 DCHECK_CURRENTLY_ON(BrowserThread::UI); 351 DCHECK_CURRENTLY_ON(BrowserThread::UI);
364 // Note that details.event_name includes the sub-event details (e.g. "/123"). 352 // Note that details.event_name includes the sub-event details (e.g. "/123").
365 // TODO(fsamuel): <webview> events will not be removed through this code path. 353 // TODO(fsamuel): <webview> events will not be removed through this code path.
366 // <webview> events will be removed in RemoveWebViewEventListeners. Ideally, 354 // <webview> events will be removed in RemoveWebViewEventListeners. Ideally,
367 // this code should be decoupled from extensions, we should use the host ID 355 // this code should be decoupled from extensions, we should use the host ID
368 // instead, and not have two different code paths. This is a huge undertaking 356 // instead, and not have two different code paths. This is a huge undertaking
369 // unfortunately, so we'll resort to two code paths for now. 357 // unfortunately, so we'll resort to two code paths for now.
370 BrowserThread::PostTask(BrowserThread::IO, 358 //
371 FROM_HERE, 359 // Note that details.event_name is actually the sub_event_name!
372 base::Bind(&RemoveEventListenerOnIOThread, 360 ExtensionWebRequestEventRouter::EventListener::ID id(
373 details.browser_context, 361 details.browser_context, details.extension_id, details.event_name, 0, 0);
374 details.extension_id, 362 BrowserThread::PostTask(
375 details.event_name, 363 BrowserThread::IO, FROM_HERE,
376 0 /* embedder_process_id (ignored) */, 364 base::Bind(
377 0 /* web_view_instance_id */)); 365 &ExtensionWebRequestEventRouter::RemoveEventListener,
366 base::Unretained(ExtensionWebRequestEventRouter::GetInstance()), id,
367 false /* not strict */));
378 } 368 }
379 369
380 // Represents a single unique listener to an event, along with whatever filter 370 // Represents a single unique listener to an event, along with whatever filter
381 // parameters and extra_info_spec were specified at the time the listener was 371 // parameters and extra_info_spec were specified at the time the listener was
382 // added. 372 // added.
383 // NOTE(benjhayden) New APIs should not use this sub_event_name trick! It does 373 // NOTE(benjhayden) New APIs should not use this sub_event_name trick! It does
384 // not play well with event pages. See downloads.onDeterminingFilename and 374 // not play well with event pages. See downloads.onDeterminingFilename and
385 // ExtensionDownloadsEventRouter for an alternative approach. 375 // ExtensionDownloadsEventRouter for an alternative approach.
386 struct ExtensionWebRequestEventRouter::EventListener { 376 ExtensionWebRequestEventRouter::EventListener::EventListener(ID id) : id(id) {}
387 std::string extension_id; 377 ExtensionWebRequestEventRouter::EventListener::~EventListener() {}
388 std::string extension_name;
389 events::HistogramValue histogram_value;
390 std::string sub_event_name;
391 RequestFilter filter;
392 int extra_info_spec;
393 int embedder_process_id;
394 int web_view_instance_id;
395 base::WeakPtr<IPC::Sender> ipc_sender;
396 mutable std::set<uint64_t> blocked_requests;
397
398 // Comparator to work with std::set.
399 bool operator<(const EventListener& that) const {
400 if (extension_id != that.extension_id)
401 return extension_id < that.extension_id;
402
403 if (sub_event_name != that.sub_event_name)
404 return sub_event_name < that.sub_event_name;
405
406 if (web_view_instance_id != that.web_view_instance_id)
407 return web_view_instance_id < that.web_view_instance_id;
408
409 if (web_view_instance_id == 0) {
410 // Do not filter by process ID for non-webviews, because this comparator
411 // is also used to find and remove an event listener when an extension is
412 // unloaded. At this point, the event listener cannot be mapped back to
413 // the original process, so 0 is used instead of the actual process ID.
414 if (embedder_process_id == 0 || that.embedder_process_id == 0)
415 return false;
416 }
417
418 if (embedder_process_id != that.embedder_process_id)
419 return embedder_process_id < that.embedder_process_id;
420
421 return false;
422 }
423
424 EventListener()
425 : histogram_value(events::UNKNOWN),
426 extra_info_spec(0),
427 embedder_process_id(0),
428 web_view_instance_id(0) {}
429 };
430 378
431 // Contains info about requests that are blocked waiting for a response from 379 // Contains info about requests that are blocked waiting for a response from
432 // an extension. 380 // an extension.
433 struct ExtensionWebRequestEventRouter::BlockedRequest { 381 struct ExtensionWebRequestEventRouter::BlockedRequest {
434 // The request that is being blocked. 382 // The request that is being blocked.
435 net::URLRequest* request; 383 net::URLRequest* request;
436 384
437 // Whether the request originates from an incognito tab. 385 // Whether the request originates from an incognito tab.
438 bool is_incognito; 386 bool is_incognito;
439 387
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 571
624 // Whether to initialized |blocked_requests_|. 572 // Whether to initialized |blocked_requests_|.
625 bool initialize_blocked_requests = false; 573 bool initialize_blocked_requests = false;
626 574
627 initialize_blocked_requests |= 575 initialize_blocked_requests |=
628 ProcessDeclarativeRules(browser_context, extension_info_map, 576 ProcessDeclarativeRules(browser_context, extension_info_map,
629 web_request::OnBeforeRequest::kEventName, request, 577 web_request::OnBeforeRequest::kEventName, request,
630 ON_BEFORE_REQUEST, NULL); 578 ON_BEFORE_REQUEST, NULL);
631 579
632 int extra_info_spec = 0; 580 int extra_info_spec = 0;
633 EventListeners listeners = GetMatchingListeners( 581 RawListeners listeners = GetMatchingListeners(
634 browser_context, extension_info_map, 582 browser_context, extension_info_map,
635 web_request::OnBeforeRequest::kEventName, request, &extra_info_spec); 583 web_request::OnBeforeRequest::kEventName, request, &extra_info_spec);
636 if (!listeners.empty() && 584 if (!listeners.empty() &&
637 !GetAndSetSignaled(request->identifier(), kOnBeforeRequest)) { 585 !GetAndSetSignaled(request->identifier(), kOnBeforeRequest)) {
638 std::unique_ptr<WebRequestEventDetails> event_details( 586 std::unique_ptr<WebRequestEventDetails> event_details(
639 CreateEventDetails(request, extra_info_spec)); 587 CreateEventDetails(request, extra_info_spec));
640 event_details->SetRequestBody(request); 588 event_details->SetRequestBody(request);
641 589
642 initialize_blocked_requests |= DispatchEvent( 590 initialize_blocked_requests |= DispatchEvent(
643 browser_context, request, listeners, std::move(event_details)); 591 browser_context, request, listeners, std::move(event_details));
(...skipping 28 matching lines...) Expand all
672 if (ShouldHideEvent(browser_context, extension_info_map, request)) 620 if (ShouldHideEvent(browser_context, extension_info_map, request))
673 return net::OK; 621 return net::OK;
674 622
675 bool initialize_blocked_requests = false; 623 bool initialize_blocked_requests = false;
676 624
677 initialize_blocked_requests |= ProcessDeclarativeRules( 625 initialize_blocked_requests |= ProcessDeclarativeRules(
678 browser_context, extension_info_map, keys::kOnBeforeSendHeadersEvent, 626 browser_context, extension_info_map, keys::kOnBeforeSendHeadersEvent,
679 request, ON_BEFORE_SEND_HEADERS, NULL); 627 request, ON_BEFORE_SEND_HEADERS, NULL);
680 628
681 int extra_info_spec = 0; 629 int extra_info_spec = 0;
682 EventListeners listeners = GetMatchingListeners( 630 RawListeners listeners = GetMatchingListeners(
683 browser_context, extension_info_map, keys::kOnBeforeSendHeadersEvent, 631 browser_context, extension_info_map, keys::kOnBeforeSendHeadersEvent,
684 request, &extra_info_spec); 632 request, &extra_info_spec);
685 if (!listeners.empty() && 633 if (!listeners.empty() &&
686 !GetAndSetSignaled(request->identifier(), kOnBeforeSendHeaders)) { 634 !GetAndSetSignaled(request->identifier(), kOnBeforeSendHeaders)) {
687 std::unique_ptr<WebRequestEventDetails> event_details( 635 std::unique_ptr<WebRequestEventDetails> event_details(
688 CreateEventDetails(request, extra_info_spec)); 636 CreateEventDetails(request, extra_info_spec));
689 event_details->SetRequestHeaders(*headers); 637 event_details->SetRequestHeaders(*headers);
690 638
691 initialize_blocked_requests |= DispatchEvent( 639 initialize_blocked_requests |= DispatchEvent(
692 browser_context, request, listeners, std::move(event_details)); 640 browser_context, request, listeners, std::move(event_details));
(...skipping 26 matching lines...) Expand all
719 const net::HttpRequestHeaders& headers) { 667 const net::HttpRequestHeaders& headers) {
720 if (ShouldHideEvent(browser_context, extension_info_map, request)) 668 if (ShouldHideEvent(browser_context, extension_info_map, request))
721 return; 669 return;
722 670
723 if (GetAndSetSignaled(request->identifier(), kOnSendHeaders)) 671 if (GetAndSetSignaled(request->identifier(), kOnSendHeaders))
724 return; 672 return;
725 673
726 ClearSignaled(request->identifier(), kOnBeforeRedirect); 674 ClearSignaled(request->identifier(), kOnBeforeRedirect);
727 675
728 int extra_info_spec = 0; 676 int extra_info_spec = 0;
729 EventListeners listeners = GetMatchingListeners( 677 RawListeners listeners = GetMatchingListeners(
730 browser_context, extension_info_map, keys::kOnSendHeadersEvent, request, 678 browser_context, extension_info_map, keys::kOnSendHeadersEvent, request,
731 &extra_info_spec); 679 &extra_info_spec);
732 if (listeners.empty()) 680 if (listeners.empty())
733 return; 681 return;
734 682
735 std::unique_ptr<WebRequestEventDetails> event_details( 683 std::unique_ptr<WebRequestEventDetails> event_details(
736 CreateEventDetails(request, extra_info_spec)); 684 CreateEventDetails(request, extra_info_spec));
737 event_details->SetRequestHeaders(headers); 685 event_details->SetRequestHeaders(headers);
738 686
739 DispatchEvent(browser_context, request, listeners, std::move(event_details)); 687 DispatchEvent(browser_context, request, listeners, std::move(event_details));
(...skipping 10 matching lines...) Expand all
750 if (ShouldHideEvent(browser_context, extension_info_map, request)) 698 if (ShouldHideEvent(browser_context, extension_info_map, request))
751 return net::OK; 699 return net::OK;
752 700
753 bool initialize_blocked_requests = false; 701 bool initialize_blocked_requests = false;
754 702
755 initialize_blocked_requests |= ProcessDeclarativeRules( 703 initialize_blocked_requests |= ProcessDeclarativeRules(
756 browser_context, extension_info_map, keys::kOnHeadersReceivedEvent, 704 browser_context, extension_info_map, keys::kOnHeadersReceivedEvent,
757 request, ON_HEADERS_RECEIVED, original_response_headers); 705 request, ON_HEADERS_RECEIVED, original_response_headers);
758 706
759 int extra_info_spec = 0; 707 int extra_info_spec = 0;
760 EventListeners listeners = GetMatchingListeners( 708 RawListeners listeners = GetMatchingListeners(
761 browser_context, extension_info_map, keys::kOnHeadersReceivedEvent, 709 browser_context, extension_info_map, keys::kOnHeadersReceivedEvent,
762 request, &extra_info_spec); 710 request, &extra_info_spec);
763 711
764 if (!listeners.empty() && 712 if (!listeners.empty() &&
765 !GetAndSetSignaled(request->identifier(), kOnHeadersReceived)) { 713 !GetAndSetSignaled(request->identifier(), kOnHeadersReceived)) {
766 std::unique_ptr<WebRequestEventDetails> event_details( 714 std::unique_ptr<WebRequestEventDetails> event_details(
767 CreateEventDetails(request, extra_info_spec)); 715 CreateEventDetails(request, extra_info_spec));
768 event_details->SetResponseHeaders(request, original_response_headers); 716 event_details->SetResponseHeaders(request, original_response_headers);
769 717
770 initialize_blocked_requests |= DispatchEvent( 718 initialize_blocked_requests |= DispatchEvent(
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 const net::NetworkDelegate::AuthCallback& callback, 750 const net::NetworkDelegate::AuthCallback& callback,
803 net::AuthCredentials* credentials) { 751 net::AuthCredentials* credentials) {
804 // No browser_context means that this is for authentication challenges in the 752 // No browser_context means that this is for authentication challenges in the
805 // system context. Skip in that case. Also skip sensitive requests. 753 // system context. Skip in that case. Also skip sensitive requests.
806 if (!browser_context || 754 if (!browser_context ||
807 WebRequestPermissions::HideRequest(extension_info_map, request)) { 755 WebRequestPermissions::HideRequest(extension_info_map, request)) {
808 return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; 756 return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION;
809 } 757 }
810 758
811 int extra_info_spec = 0; 759 int extra_info_spec = 0;
812 EventListeners listeners = GetMatchingListeners( 760 RawListeners listeners = GetMatchingListeners(
813 browser_context, extension_info_map, keys::kOnAuthRequiredEvent, request, 761 browser_context, extension_info_map, keys::kOnAuthRequiredEvent, request,
814 &extra_info_spec); 762 &extra_info_spec);
815 if (listeners.empty()) 763 if (listeners.empty())
816 return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; 764 return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION;
817 765
818 std::unique_ptr<WebRequestEventDetails> event_details( 766 std::unique_ptr<WebRequestEventDetails> event_details(
819 CreateEventDetails(request, extra_info_spec)); 767 CreateEventDetails(request, extra_info_spec));
820 event_details->SetResponseHeaders(request, request->response_headers()); 768 event_details->SetResponseHeaders(request, request->response_headers());
821 event_details->SetAuthInfo(auth_info); 769 event_details->SetAuthInfo(auth_info);
822 770
(...skipping 21 matching lines...) Expand all
844 792
845 if (GetAndSetSignaled(request->identifier(), kOnBeforeRedirect)) 793 if (GetAndSetSignaled(request->identifier(), kOnBeforeRedirect))
846 return; 794 return;
847 795
848 ClearSignaled(request->identifier(), kOnBeforeRequest); 796 ClearSignaled(request->identifier(), kOnBeforeRequest);
849 ClearSignaled(request->identifier(), kOnBeforeSendHeaders); 797 ClearSignaled(request->identifier(), kOnBeforeSendHeaders);
850 ClearSignaled(request->identifier(), kOnSendHeaders); 798 ClearSignaled(request->identifier(), kOnSendHeaders);
851 ClearSignaled(request->identifier(), kOnHeadersReceived); 799 ClearSignaled(request->identifier(), kOnHeadersReceived);
852 800
853 int extra_info_spec = 0; 801 int extra_info_spec = 0;
854 EventListeners listeners = GetMatchingListeners( 802 RawListeners listeners = GetMatchingListeners(
855 browser_context, extension_info_map, keys::kOnBeforeRedirectEvent, 803 browser_context, extension_info_map, keys::kOnBeforeRedirectEvent,
856 request, &extra_info_spec); 804 request, &extra_info_spec);
857 if (listeners.empty()) 805 if (listeners.empty())
858 return; 806 return;
859 807
860 std::unique_ptr<WebRequestEventDetails> event_details( 808 std::unique_ptr<WebRequestEventDetails> event_details(
861 CreateEventDetails(request, extra_info_spec)); 809 CreateEventDetails(request, extra_info_spec));
862 event_details->SetResponseHeaders(request, request->response_headers()); 810 event_details->SetResponseHeaders(request, request->response_headers());
863 event_details->SetResponseSource(request); 811 event_details->SetResponseSource(request);
864 event_details->SetString(keys::kRedirectUrlKey, new_location.spec()); 812 event_details->SetString(keys::kRedirectUrlKey, new_location.spec());
865 813
866 DispatchEvent(browser_context, request, listeners, std::move(event_details)); 814 DispatchEvent(browser_context, request, listeners, std::move(event_details));
867 } 815 }
868 816
869 void ExtensionWebRequestEventRouter::OnResponseStarted( 817 void ExtensionWebRequestEventRouter::OnResponseStarted(
870 void* browser_context, 818 void* browser_context,
871 const InfoMap* extension_info_map, 819 const InfoMap* extension_info_map,
872 net::URLRequest* request) { 820 net::URLRequest* request) {
873 if (ShouldHideEvent(browser_context, extension_info_map, request)) 821 if (ShouldHideEvent(browser_context, extension_info_map, request))
874 return; 822 return;
875 823
876 // OnResponseStarted is even triggered, when the request was cancelled. 824 // OnResponseStarted is even triggered, when the request was cancelled.
877 if (request->status().status() != net::URLRequestStatus::SUCCESS) 825 if (request->status().status() != net::URLRequestStatus::SUCCESS)
878 return; 826 return;
879 827
880 int extra_info_spec = 0; 828 int extra_info_spec = 0;
881 EventListeners listeners = GetMatchingListeners( 829 RawListeners listeners = GetMatchingListeners(
882 browser_context, extension_info_map, keys::kOnResponseStartedEvent, 830 browser_context, extension_info_map, keys::kOnResponseStartedEvent,
883 request, &extra_info_spec); 831 request, &extra_info_spec);
884 if (listeners.empty()) 832 if (listeners.empty())
885 return; 833 return;
886 834
887 std::unique_ptr<WebRequestEventDetails> event_details( 835 std::unique_ptr<WebRequestEventDetails> event_details(
888 CreateEventDetails(request, extra_info_spec)); 836 CreateEventDetails(request, extra_info_spec));
889 event_details->SetResponseHeaders(request, request->response_headers()); 837 event_details->SetResponseHeaders(request, request->response_headers());
890 event_details->SetResponseSource(request); 838 event_details->SetResponseSource(request);
891 839
(...skipping 17 matching lines...) Expand all
909 request_time_tracker_->LogRequestEndTime(request->identifier(), 857 request_time_tracker_->LogRequestEndTime(request->identifier(),
910 base::Time::Now()); 858 base::Time::Now());
911 859
912 DCHECK(request->status().status() == net::URLRequestStatus::SUCCESS); 860 DCHECK(request->status().status() == net::URLRequestStatus::SUCCESS);
913 861
914 DCHECK(!GetAndSetSignaled(request->identifier(), kOnCompleted)); 862 DCHECK(!GetAndSetSignaled(request->identifier(), kOnCompleted));
915 863
916 ClearPendingCallbacks(request); 864 ClearPendingCallbacks(request);
917 865
918 int extra_info_spec = 0; 866 int extra_info_spec = 0;
919 EventListeners listeners = 867 RawListeners listeners =
920 GetMatchingListeners(browser_context, extension_info_map, 868 GetMatchingListeners(browser_context, extension_info_map,
921 keys::kOnCompletedEvent, request, &extra_info_spec); 869 keys::kOnCompletedEvent, request, &extra_info_spec);
922 if (listeners.empty()) 870 if (listeners.empty())
923 return; 871 return;
924 872
925 std::unique_ptr<WebRequestEventDetails> event_details( 873 std::unique_ptr<WebRequestEventDetails> event_details(
926 CreateEventDetails(request, extra_info_spec)); 874 CreateEventDetails(request, extra_info_spec));
927 event_details->SetResponseHeaders(request, request->response_headers()); 875 event_details->SetResponseHeaders(request, request->response_headers());
928 event_details->SetResponseSource(request); 876 event_details->SetResponseSource(request);
929 877
(...skipping 19 matching lines...) Expand all
949 base::Time::Now()); 897 base::Time::Now());
950 898
951 DCHECK(request->status().status() == net::URLRequestStatus::FAILED || 899 DCHECK(request->status().status() == net::URLRequestStatus::FAILED ||
952 request->status().status() == net::URLRequestStatus::CANCELED); 900 request->status().status() == net::URLRequestStatus::CANCELED);
953 901
954 DCHECK(!GetAndSetSignaled(request->identifier(), kOnErrorOccurred)); 902 DCHECK(!GetAndSetSignaled(request->identifier(), kOnErrorOccurred));
955 903
956 ClearPendingCallbacks(request); 904 ClearPendingCallbacks(request);
957 905
958 int extra_info_spec = 0; 906 int extra_info_spec = 0;
959 EventListeners listeners = GetMatchingListeners( 907 RawListeners listeners = GetMatchingListeners(
960 browser_context, extension_info_map, 908 browser_context, extension_info_map,
961 web_request::OnErrorOccurred::kEventName, request, &extra_info_spec); 909 web_request::OnErrorOccurred::kEventName, request, &extra_info_spec);
962 if (listeners.empty()) 910 if (listeners.empty())
963 return; 911 return;
964 912
965 std::unique_ptr<WebRequestEventDetails> event_details( 913 std::unique_ptr<WebRequestEventDetails> event_details(
966 CreateEventDetails(request, extra_info_spec)); 914 CreateEventDetails(request, extra_info_spec));
967 if (started) 915 if (started)
968 event_details->SetResponseSource(request); 916 event_details->SetResponseSource(request);
969 else 917 else
(...skipping 16 matching lines...) Expand all
986 } 934 }
987 935
988 void ExtensionWebRequestEventRouter::ClearPendingCallbacks( 936 void ExtensionWebRequestEventRouter::ClearPendingCallbacks(
989 const net::URLRequest* request) { 937 const net::URLRequest* request) {
990 blocked_requests_.erase(request->identifier()); 938 blocked_requests_.erase(request->identifier());
991 } 939 }
992 940
993 bool ExtensionWebRequestEventRouter::DispatchEvent( 941 bool ExtensionWebRequestEventRouter::DispatchEvent(
994 void* browser_context, 942 void* browser_context,
995 net::URLRequest* request, 943 net::URLRequest* request,
996 const std::vector<const EventListener*>& listeners, 944 const RawListeners& listeners,
997 std::unique_ptr<WebRequestEventDetails> event_details) { 945 std::unique_ptr<WebRequestEventDetails> event_details) {
998 // TODO(mpcomplete): Consider consolidating common (extension_id,json_args) 946 // TODO(mpcomplete): Consider consolidating common (extension_id,json_args)
999 // pairs into a single message sent to a list of sub_event_names. 947 // pairs into a single message sent to a list of sub_event_names.
1000 int num_handlers_blocking = 0; 948 int num_handlers_blocking = 0;
1001 949
1002 std::unique_ptr<std::vector<EventListener>> listeners_to_dispatch( 950 std::unique_ptr<ListenerIDs> listeners_to_dispatch(new ListenerIDs);
1003 new std::vector<EventListener>());
1004 listeners_to_dispatch->reserve(listeners.size()); 951 listeners_to_dispatch->reserve(listeners.size());
1005 for (const EventListener* listener : listeners) { 952 for (EventListener* listener : listeners) {
1006 listeners_to_dispatch->push_back(*listener); 953 listeners_to_dispatch->push_back(listener->id);
1007 if (listener->extra_info_spec & 954 if (listener->extra_info_spec &
1008 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) { 955 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) {
1009 listener->blocked_requests.insert(request->identifier()); 956 listener->blocked_requests.insert(request->identifier());
1010 // If this is the first delegate blocking the request, go ahead and log 957 // If this is the first delegate blocking the request, go ahead and log
1011 // it. 958 // it.
1012 if (num_handlers_blocking == 0) { 959 if (num_handlers_blocking == 0) {
1013 std::string delegate_info = l10n_util::GetStringFUTF8( 960 std::string delegate_info = l10n_util::GetStringFUTF8(
1014 IDS_LOAD_STATE_PARAMETER_EXTENSION, 961 IDS_LOAD_STATE_PARAMETER_EXTENSION,
1015 base::UTF8ToUTF16(listener->extension_name)); 962 base::UTF8ToUTF16(listener->extension_name));
1016 // LobAndReport allows extensions that block requests to be displayed in 963 // LobAndReport allows extensions that block requests to be displayed in
(...skipping 15 matching lines...) Expand all
1032 blocked_request.num_handlers_blocking += num_handlers_blocking; 979 blocked_request.num_handlers_blocking += num_handlers_blocking;
1033 blocked_request.blocking_time = base::Time::Now(); 980 blocked_request.blocking_time = base::Time::Now();
1034 return true; 981 return true;
1035 } 982 }
1036 983
1037 return false; 984 return false;
1038 } 985 }
1039 986
1040 void ExtensionWebRequestEventRouter::DispatchEventToListeners( 987 void ExtensionWebRequestEventRouter::DispatchEventToListeners(
1041 void* browser_context, 988 void* browser_context,
1042 std::unique_ptr<std::vector<EventListener>> listeners, 989 std::unique_ptr<ListenerIDs> listener_ids,
1043 std::unique_ptr<WebRequestEventDetails> event_details) { 990 std::unique_ptr<WebRequestEventDetails> event_details) {
1044 DCHECK_CURRENTLY_ON(BrowserThread::IO); 991 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1045 DCHECK(listeners.get()); 992 DCHECK(!listener_ids->empty());
1046 DCHECK_GT(listeners->size(), 0UL);
1047 DCHECK(event_details.get()); 993 DCHECK(event_details.get());
1048 994
1049 std::string event_name = 995 std::string event_name =
1050 EventRouter::GetBaseEventName((*listeners)[0].sub_event_name); 996 EventRouter::GetBaseEventName((*listener_ids)[0].sub_event_name);
1051 DCHECK(IsWebRequestEvent(event_name)); 997 DCHECK(IsWebRequestEvent(event_name));
1052 998
1053 const std::set<EventListener>& event_listeners = 999 Listeners& event_listeners = listeners_[browser_context][event_name];
1054 listeners_[browser_context][event_name];
1055 void* cross_browser_context = GetCrossBrowserContext(browser_context); 1000 void* cross_browser_context = GetCrossBrowserContext(browser_context);
1056 const std::set<EventListener>* cross_event_listeners = 1001 Listeners* cross_event_listeners =
1057 cross_browser_context ? &listeners_[cross_browser_context][event_name] 1002 cross_browser_context ? &listeners_[cross_browser_context][event_name]
1058 : nullptr; 1003 : nullptr;
1059 1004
1060 for (const EventListener& target : *listeners) { 1005 for (const EventListener::ID& id : *listener_ids) {
1061 std::set<EventListener>::const_iterator listener = 1006 // It's possible that the listener is no longer present. Check to make sure
1062 event_listeners.find(target); 1007 // it's still there.
1063 // Ignore listener if it was removed between the thread hops. 1008 const EventListener* listener =
1064 if (listener == event_listeners.end()) { 1009 FindEventListenerInContainer(id, event_listeners);
1065 if (!cross_event_listeners) 1010 if (!listener && cross_event_listeners) {
1066 continue; 1011 listener = FindEventListenerInContainer(id, *cross_event_listeners);
1067 listener = cross_event_listeners->find(target);
1068 if (listener == cross_event_listeners->end())
1069 continue;
1070 } 1012 }
1013 if (!listener)
1014 continue;
1071 1015
1072 if (!listener->ipc_sender.get()) 1016 if (!listener->ipc_sender.get())
1073 continue; 1017 continue;
1074 1018
1075 // Filter out the optional keys that this listener didn't request. 1019 // Filter out the optional keys that this listener didn't request.
1076 std::unique_ptr<base::ListValue> args_filtered(new base::ListValue); 1020 std::unique_ptr<base::ListValue> args_filtered(new base::ListValue);
1077 args_filtered->Append( 1021 args_filtered->Append(
1078 event_details->GetFilteredDict(listener->extra_info_spec)); 1022 event_details->GetFilteredDict(listener->extra_info_spec));
1079 1023
1080 EventRouter::DispatchEventToSender( 1024 EventRouter::DispatchEventToSender(
1081 listener->ipc_sender.get(), browser_context, listener->extension_id, 1025 listener->ipc_sender.get(), browser_context, listener->id.extension_id,
1082 listener->histogram_value, listener->sub_event_name, 1026 listener->histogram_value, listener->id.sub_event_name,
1083 std::move(args_filtered), EventRouter::USER_GESTURE_UNKNOWN, 1027 std::move(args_filtered), EventRouter::USER_GESTURE_UNKNOWN,
1084 EventFilteringInfo()); 1028 EventFilteringInfo());
1085 } 1029 }
1086 } 1030 }
1087 1031
1088 void ExtensionWebRequestEventRouter::OnEventHandled( 1032 void ExtensionWebRequestEventRouter::OnEventHandled(
1089 void* browser_context, 1033 void* browser_context,
1090 const std::string& extension_id, 1034 const std::string& extension_id,
1091 const std::string& event_name, 1035 const std::string& event_name,
1092 const std::string& sub_event_name, 1036 const std::string& sub_event_name,
1093 uint64_t request_id, 1037 uint64_t request_id,
1094 EventResponse* response) { 1038 EventResponse* response) {
1095 // TODO(robwu): Does this also work with webviews? operator< (used by find) 1039 // TODO(robwu): This ignores WebViews.
1096 // takes the webview ID into account, which is not set on |listener|. 1040 Listeners& listeners = listeners_[browser_context][event_name];
1097 EventListener listener; 1041 EventListener::ID id(browser_context, extension_id, sub_event_name, 0, 0);
1098 listener.extension_id = extension_id; 1042 for (auto it = listeners.begin(); it != listeners.end(); ++it) {
1099 listener.sub_event_name = sub_event_name; 1043 if ((*it)->id.LooselyMatches(id)) {
1100 1044 (*it)->blocked_requests.erase(request_id);
1101 // The listener may have been removed (e.g. due to the process going away) 1045 }
1102 // before we got here. 1046 }
1103 std::set<EventListener>::iterator found =
1104 listeners_[browser_context][event_name].find(listener);
1105 if (found != listeners_[browser_context][event_name].end())
1106 found->blocked_requests.erase(request_id);
1107 1047
1108 DecrementBlockCount( 1048 DecrementBlockCount(
1109 browser_context, extension_id, event_name, request_id, response); 1049 browser_context, extension_id, event_name, request_id, response);
1110 } 1050 }
1111 1051
1112 bool ExtensionWebRequestEventRouter::AddEventListener( 1052 bool ExtensionWebRequestEventRouter::AddEventListener(
1113 void* browser_context, 1053 void* browser_context,
1114 const std::string& extension_id, 1054 const std::string& extension_id,
1115 const std::string& extension_name, 1055 const std::string& extension_name,
1116 events::HistogramValue histogram_value, 1056 events::HistogramValue histogram_value,
1117 const std::string& event_name, 1057 const std::string& event_name,
1118 const std::string& sub_event_name, 1058 const std::string& sub_event_name,
1119 const RequestFilter& filter, 1059 const RequestFilter& filter,
1120 int extra_info_spec, 1060 int extra_info_spec,
1121 int embedder_process_id, 1061 int embedder_process_id,
1122 int web_view_instance_id, 1062 int web_view_instance_id,
1123 base::WeakPtr<IPC::Sender> ipc_sender) { 1063 base::WeakPtr<IPC::Sender> ipc_sender) {
1124 if (!IsWebRequestEvent(event_name)) 1064 if (!IsWebRequestEvent(event_name))
1125 return false; 1065 return false;
1126 1066
1127 EventListener listener; 1067 if (event_name != EventRouter::GetBaseEventName(sub_event_name))
1128 listener.extension_id = extension_id; 1068 return false;
1129 listener.extension_name = extension_name; 1069
1130 listener.histogram_value = histogram_value; 1070 EventListener::ID id(browser_context, extension_id, sub_event_name,
1131 listener.sub_event_name = sub_event_name; 1071 embedder_process_id, web_view_instance_id);
1132 listener.filter = filter; 1072 if (FindEventListener(id) != nullptr) {
1133 listener.extra_info_spec = extra_info_spec; 1073 // This is likely an abuse of the API by a malicious extension.
1134 listener.ipc_sender = ipc_sender; 1074 return false;
1135 listener.embedder_process_id = embedder_process_id; 1075 }
1136 listener.web_view_instance_id = web_view_instance_id; 1076
1137 if (listener.web_view_instance_id) { 1077 std::unique_ptr<EventListener> listener(new EventListener(id));
1078 listener->extension_name = extension_name;
1079 listener->histogram_value = histogram_value;
1080 listener->filter = filter;
1081 listener->extra_info_spec = extra_info_spec;
1082 listener->ipc_sender = ipc_sender;
1083 if (web_view_instance_id) {
1138 content::RecordAction( 1084 content::RecordAction(
1139 base::UserMetricsAction("WebView.WebRequest.AddListener")); 1085 base::UserMetricsAction("WebView.WebRequest.AddListener"));
1140 } 1086 }
1141 1087
1142 if (base::ContainsKey(listeners_[browser_context][event_name], listener)) { 1088 listeners_[browser_context][event_name].push_back(std::move(listener));
1143 // This is likely an abuse of the API by a malicious extension.
1144 return false;
1145 }
1146 listeners_[browser_context][event_name].insert(listener);
1147 return true; 1089 return true;
1148 } 1090 }
1149 1091
1092 size_t ExtensionWebRequestEventRouter::GetListenerCountForTesting(
1093 void* browser_context,
1094 const std::string& event_name) {
1095 return listeners_[browser_context][event_name].size();
1096 }
1097
1098 ExtensionWebRequestEventRouter::EventListener*
1099 ExtensionWebRequestEventRouter::FindEventListener(const EventListener::ID& id) {
1100 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1101 std::string event_name = EventRouter::GetBaseEventName(id.sub_event_name);
1102 Listeners& listeners = listeners_[id.browser_context][event_name];
1103 return FindEventListenerInContainer(id, listeners);
1104 }
1105
1106 ExtensionWebRequestEventRouter::EventListener*
1107 ExtensionWebRequestEventRouter::FindEventListenerInContainer(
1108 const EventListener::ID& id,
1109 Listeners& listeners) {
1110 for (auto it = listeners.begin(); it != listeners.end(); ++it) {
1111 if ((*it)->id == id) {
1112 return it->get();
1113 }
1114 }
1115 return nullptr;
1116 }
1117
1150 void ExtensionWebRequestEventRouter::RemoveEventListener( 1118 void ExtensionWebRequestEventRouter::RemoveEventListener(
1151 void* browser_context, 1119 const EventListener::ID& id,
1152 const std::string& extension_id, 1120 bool strict) {
1153 const std::string& sub_event_name, 1121 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1154 int embedder_process_id,
1155 int web_view_instance_id) {
1156 std::string event_name = EventRouter::GetBaseEventName(sub_event_name);
1157 DCHECK(IsWebRequestEvent(event_name));
1158 1122
1159 EventListener listener; 1123 std::string event_name = EventRouter::GetBaseEventName(id.sub_event_name);
1160 listener.extension_id = extension_id; 1124 Listeners& listeners = listeners_[id.browser_context][event_name];
1161 listener.sub_event_name = sub_event_name; 1125 for (auto it = listeners.begin(); it != listeners.end(); ++it) {
1162 listener.embedder_process_id = embedder_process_id; 1126 std::unique_ptr<EventListener>& listener = *it;
1163 listener.web_view_instance_id = web_view_instance_id;
1164 1127
1165 std::set<EventListener>& event_listeners = 1128 // There are two places that call this method: RemoveWebViewEventListeners
1166 listeners_[browser_context][event_name]; 1129 // and OnListenerRemoved. The latter can't use operator== because it doesn't
1167 // It's possible for AddEventListener to fail asynchronously. In that case, 1130 // have the embedder_process_id. This shouldn't be a problem, because
1168 // the renderer believes the listener exists, while the browser does not. 1131 // OnListenerRemoved is only called for web_view_instance_id == 0.
1169 // Ignore a RemoveEventListener in that case. 1132 bool matches =
1170 std::set<EventListener>::const_iterator it = event_listeners.find(listener); 1133 strict ? listener->id == id : listener->id.LooselyMatches(id);
1171 if (it == event_listeners.end()) 1134 if (matches) {
1172 return; 1135 // Unblock any request that this event listener may have been blocking.
1136 for (uint64_t blocked_request_id : listener->blocked_requests)
1137 DecrementBlockCount(listener->id.browser_context,
1138 listener->id.extension_id, event_name,
1139 blocked_request_id, nullptr);
1173 1140
1174 #if defined(OS_WIN) 1141 listeners.erase(it);
1175 // Debugging https://crbug.com/589735 1142 helpers::ClearCacheOnNavigation();
1176 // Please post crash reports at the following lines to the above issue. 1143 return;
1177 unsigned event_listener_count = event_listeners.count(listener); 1144 }
1178 CHECK_GE(event_listener_count, 0u); 1145 }
1179 CHECK_GE(event_listener_count, 1u);
1180 CHECK_LE(event_listener_count, 2u);
1181 CHECK_EQ(event_listener_count, 1u);
1182 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
1183 #endif // OS_WIN
1184 CHECK_EQ(event_listeners.count(listener), 1u) <<
1185 "extension=" << extension_id << " event=" << event_name;
1186
1187 // Unblock any request that this event listener may have been blocking.
1188 for (uint64_t id : it->blocked_requests)
1189 DecrementBlockCount(browser_context, extension_id, event_name, id, NULL);
1190
1191 event_listeners.erase(listener);
1192
1193 helpers::ClearCacheOnNavigation();
1194 } 1146 }
1195 1147
1196 void ExtensionWebRequestEventRouter::RemoveWebViewEventListeners( 1148 void ExtensionWebRequestEventRouter::RemoveWebViewEventListeners(
1197 void* browser_context, 1149 void* browser_context,
1198 int embedder_process_id, 1150 int embedder_process_id,
1199 int web_view_instance_id) { 1151 int web_view_instance_id) {
1200 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1152 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1201 1153
1202 // Iterate over all listeners of all WebRequest events to delete 1154 // Iterate over all listeners of all WebRequest events to delete
1203 // any listeners that belong to the provided <webview>. 1155 // any listeners that belong to the provided <webview>.
1204 ListenerMapForBrowserContext& map_for_browser_context = 1156 ListenerMapForBrowserContext& map_for_browser_context =
1205 listeners_[browser_context]; 1157 listeners_[browser_context];
1206 for (const auto& event_iter : map_for_browser_context) { 1158 for (const auto& event_iter : map_for_browser_context) {
1207 // Construct a listeners_to_delete vector so that we don't modify the set of 1159 // Construct a listeners_to_delete vector so that we don't modify the set of
1208 // listeners as we iterate through it. 1160 // listeners as we iterate through it.
1209 std::vector<EventListener> listeners_to_delete; 1161 std::vector<EventListener::ID> listeners_to_delete;
1210 const std::set<EventListener>& listeners = event_iter.second; 1162 const Listeners& listeners = event_iter.second;
1211 for (const auto& listener : listeners) { 1163 for (const auto& listener : listeners) {
1212 if (listener.embedder_process_id == embedder_process_id && 1164 if (listener->id.embedder_process_id == embedder_process_id &&
1213 listener.web_view_instance_id == web_view_instance_id) { 1165 listener->id.web_view_instance_id == web_view_instance_id) {
1214 listeners_to_delete.push_back(listener); 1166 listeners_to_delete.push_back(listener->id);
1215 } 1167 }
1216 } 1168 }
1217 // Remove the listeners selected for deletion. 1169 // Remove the listeners selected for deletion.
1218 for (const auto& listener : listeners_to_delete) { 1170 for (const auto& listener_id : listeners_to_delete)
1219 RemoveEventListenerOnIOThread( 1171 RemoveEventListener(listener_id, true /* strict */);
1220 browser_context,
1221 listener.extension_id,
1222 listener.sub_event_name,
1223 listener.embedder_process_id,
1224 listener.web_view_instance_id);
1225 }
1226 } 1172 }
1227 } 1173 }
1228 1174
1229 void ExtensionWebRequestEventRouter::OnOTRBrowserContextCreated( 1175 void ExtensionWebRequestEventRouter::OnOTRBrowserContextCreated(
1230 void* original_browser_context, void* otr_browser_context) { 1176 void* original_browser_context, void* otr_browser_context) {
1231 cross_browser_context_map_[original_browser_context] = 1177 cross_browser_context_map_[original_browser_context] =
1232 std::make_pair(false, otr_browser_context); 1178 std::make_pair(false, otr_browser_context);
1233 cross_browser_context_map_[otr_browser_context] = 1179 cross_browser_context_map_[otr_browser_context] =
1234 std::make_pair(true, original_browser_context); 1180 std::make_pair(true, original_browser_context);
1235 } 1181 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1291 const InfoMap* extension_info_map, 1237 const InfoMap* extension_info_map,
1292 bool crosses_incognito, 1238 bool crosses_incognito,
1293 const std::string& event_name, 1239 const std::string& event_name,
1294 const GURL& url, 1240 const GURL& url,
1295 int render_process_host_id, 1241 int render_process_host_id,
1296 int routing_id, 1242 int routing_id,
1297 content::ResourceType resource_type, 1243 content::ResourceType resource_type,
1298 bool is_async_request, 1244 bool is_async_request,
1299 bool is_request_from_extension, 1245 bool is_request_from_extension,
1300 int* extra_info_spec, 1246 int* extra_info_spec,
1301 EventListeners* matching_listeners) { 1247 RawListeners* matching_listeners) {
1302 std::string web_request_event_name(event_name); 1248 std::string web_request_event_name(event_name);
1303 WebViewRendererState::WebViewInfo web_view_info; 1249 WebViewRendererState::WebViewInfo web_view_info;
1304 bool is_web_view_guest = WebViewRendererState::GetInstance()->GetInfo( 1250 bool is_web_view_guest = WebViewRendererState::GetInstance()->GetInfo(
1305 render_process_host_id, routing_id, &web_view_info); 1251 render_process_host_id, routing_id, &web_view_info);
1306 if (is_web_view_guest) { 1252 if (is_web_view_guest) {
1307 web_request_event_name.replace( 1253 web_request_event_name.replace(
1308 0, sizeof(kWebRequestEventPrefix) - 1, webview::kWebViewEventPrefix); 1254 0, sizeof(kWebRequestEventPrefix) - 1, webview::kWebViewEventPrefix);
1309 } 1255 }
1310 1256
1311 std::set<EventListener>& listeners = 1257 Listeners& listeners = listeners_[browser_context][web_request_event_name];
1312 listeners_[browser_context][web_request_event_name]; 1258 for (std::unique_ptr<EventListener>& listener : listeners) {
1313 for (const EventListener& listener : listeners) { 1259 if (!listener->ipc_sender.get()) {
1314 if (!listener.ipc_sender.get()) {
1315 // The IPC sender has been deleted. This listener will be removed soon 1260 // The IPC sender has been deleted. This listener will be removed soon
1316 // via a call to RemoveEventListener. For now, just skip it. 1261 // via a call to RemoveEventListener. For now, just skip it.
1317 continue; 1262 continue;
1318 } 1263 }
1319 1264
1320 if (is_web_view_guest && 1265 if (is_web_view_guest &&
1321 (listener.embedder_process_id != web_view_info.embedder_process_id || 1266 (listener->id.embedder_process_id !=
1322 listener.web_view_instance_id != web_view_info.instance_id)) { 1267 web_view_info.embedder_process_id ||
1268 listener->id.web_view_instance_id != web_view_info.instance_id)) {
1323 continue; 1269 continue;
1324 } 1270 }
1325 1271
1326 // Filter requests from other extensions / apps. This does not work for 1272 // Filter requests from other extensions / apps. This does not work for
1327 // content scripts, or extension pages in non-extension processes. 1273 // content scripts, or extension pages in non-extension processes.
1328 if (is_request_from_extension && 1274 if (is_request_from_extension &&
1329 listener.embedder_process_id != render_process_host_id) { 1275 listener->id.embedder_process_id != render_process_host_id) {
1330 continue; 1276 continue;
1331 } 1277 }
1332 1278
1333 if (!listener.filter.urls.is_empty() && 1279 if (!listener->filter.urls.is_empty() &&
1334 !listener.filter.urls.MatchesURL(url)) { 1280 !listener->filter.urls.MatchesURL(url)) {
1335 continue; 1281 continue;
1336 } 1282 }
1337 1283
1338 int render_process_id = -1; 1284 int render_process_id = -1;
1339 int render_frame_id = -1; 1285 int render_frame_id = -1;
1340 // TODO(devlin): Figure out when one/both of these can fail, and if we 1286 // TODO(devlin): Figure out when one/both of these can fail, and if we
1341 // need to address it. 1287 // need to address it.
1342 bool found_render_frame = 1288 bool found_render_frame =
1343 content::ResourceRequestInfo::GetRenderFrameForRequest( 1289 content::ResourceRequestInfo::GetRenderFrameForRequest(
1344 request, &render_process_id, &render_frame_id); 1290 request, &render_process_id, &render_frame_id);
1345 UMA_HISTOGRAM_BOOLEAN("Extensions.WebRequestEventFoundFrame", 1291 UMA_HISTOGRAM_BOOLEAN("Extensions.WebRequestEventFoundFrame",
1346 found_render_frame); 1292 found_render_frame);
1347 ExtensionApiFrameIdMap::FrameData frame_data; 1293 ExtensionApiFrameIdMap::FrameData frame_data;
1348 if (found_render_frame) { 1294 if (found_render_frame) {
1349 ExtensionApiFrameIdMap::Get()->GetCachedFrameDataOnIO( 1295 ExtensionApiFrameIdMap::Get()->GetCachedFrameDataOnIO(
1350 render_process_id, render_frame_id, &frame_data); 1296 render_process_id, render_frame_id, &frame_data);
1351 } 1297 }
1352 // Check if the tab id and window id match, if they were set in the 1298 // Check if the tab id and window id match, if they were set in the
1353 // listener params. 1299 // listener params.
1354 if ((listener.filter.tab_id != -1 && 1300 if ((listener->filter.tab_id != -1 &&
1355 frame_data.tab_id != listener.filter.tab_id) || 1301 frame_data.tab_id != listener->filter.tab_id) ||
1356 (listener.filter.window_id != -1 && 1302 (listener->filter.window_id != -1 &&
1357 frame_data.window_id != listener.filter.window_id)) { 1303 frame_data.window_id != listener->filter.window_id)) {
1358 continue; 1304 continue;
1359 } 1305 }
1360 1306
1361 const std::vector<content::ResourceType>& types = listener.filter.types; 1307 const std::vector<content::ResourceType>& types = listener->filter.types;
1362 if (!types.empty() && 1308 if (!types.empty() &&
1363 std::find(types.begin(), types.end(), resource_type) == types.end()) { 1309 std::find(types.begin(), types.end(), resource_type) == types.end()) {
1364 continue; 1310 continue;
1365 } 1311 }
1366 1312
1367 if (!is_web_view_guest) { 1313 if (!is_web_view_guest) {
1368 PermissionsData::AccessType access = 1314 PermissionsData::AccessType access =
1369 WebRequestPermissions::CanExtensionAccessURL( 1315 WebRequestPermissions::CanExtensionAccessURL(
1370 extension_info_map, listener.extension_id, url, frame_data.tab_id, 1316 extension_info_map, listener->id.extension_id, url,
1371 crosses_incognito, 1317 frame_data.tab_id, crosses_incognito,
1372 WebRequestPermissions::REQUIRE_HOST_PERMISSION); 1318 WebRequestPermissions::REQUIRE_HOST_PERMISSION);
1373 if (access != PermissionsData::ACCESS_ALLOWED) { 1319 if (access != PermissionsData::ACCESS_ALLOWED) {
1374 if (access == PermissionsData::ACCESS_WITHHELD && 1320 if (access == PermissionsData::ACCESS_WITHHELD &&
1375 web_request_event_router_delegate_) { 1321 web_request_event_router_delegate_) {
1376 web_request_event_router_delegate_->NotifyWebRequestWithheld( 1322 web_request_event_router_delegate_->NotifyWebRequestWithheld(
1377 render_process_id, render_frame_id, listener.extension_id); 1323 render_process_id, render_frame_id, listener->id.extension_id);
1378 } 1324 }
1379 continue; 1325 continue;
1380 } 1326 }
1381 } 1327 }
1382 1328
1383 bool blocking_listener = 1329 bool blocking_listener =
1384 (listener.extra_info_spec & 1330 (listener->extra_info_spec &
1385 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) != 0; 1331 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) != 0;
1386 1332
1387 // We do not want to notify extensions about XHR requests that are 1333 // We do not want to notify extensions about XHR requests that are
1388 // triggered by themselves. This is a workaround to prevent deadlocks 1334 // triggered by themselves. This is a workaround to prevent deadlocks
1389 // in case of synchronous XHR requests that block the extension renderer 1335 // in case of synchronous XHR requests that block the extension renderer
1390 // and therefore prevent the extension from processing the request 1336 // and therefore prevent the extension from processing the request
1391 // handler. This is only a problem for blocking listeners. 1337 // handler. This is only a problem for blocking listeners.
1392 // http://crbug.com/105656 1338 // http://crbug.com/105656
1393 bool synchronous_xhr_from_extension = 1339 bool synchronous_xhr_from_extension =
1394 !is_async_request && is_request_from_extension && 1340 !is_async_request && is_request_from_extension &&
1395 resource_type == content::RESOURCE_TYPE_XHR; 1341 resource_type == content::RESOURCE_TYPE_XHR;
1396 1342
1397 // Only send webRequest events for URLs the extension has access to. 1343 // Only send webRequest events for URLs the extension has access to.
1398 if (blocking_listener && synchronous_xhr_from_extension) 1344 if (blocking_listener && synchronous_xhr_from_extension)
1399 continue; 1345 continue;
1400 1346
1401 matching_listeners->push_back(&listener); 1347 matching_listeners->push_back(listener.get());
1402 *extra_info_spec |= listener.extra_info_spec; 1348 *extra_info_spec |= listener->extra_info_spec;
1403 } 1349 }
1404 } 1350 }
1405 1351
1406 ExtensionWebRequestEventRouter::EventListeners 1352 ExtensionWebRequestEventRouter::RawListeners
1407 ExtensionWebRequestEventRouter::GetMatchingListeners( 1353 ExtensionWebRequestEventRouter::GetMatchingListeners(
1408 void* browser_context, 1354 void* browser_context,
1409 const InfoMap* extension_info_map, 1355 const InfoMap* extension_info_map,
1410 const std::string& event_name, 1356 const std::string& event_name,
1411 const net::URLRequest* request, 1357 const net::URLRequest* request,
1412 int* extra_info_spec) { 1358 int* extra_info_spec) {
1413 // TODO(mpcomplete): handle browser_context == NULL (should collect all 1359 // TODO(mpcomplete): handle browser_context == NULL (should collect all
1414 // listeners). 1360 // listeners).
1415 *extra_info_spec = 0; 1361 *extra_info_spec = 0;
1416 1362
1417 const GURL& url = request->url(); 1363 const GURL& url = request->url();
1418 int render_process_host_id = content::ChildProcessHost::kInvalidUniqueID; 1364 int render_process_host_id = content::ChildProcessHost::kInvalidUniqueID;
1419 int routing_id = MSG_ROUTING_NONE; 1365 int routing_id = MSG_ROUTING_NONE;
1420 content::ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE; 1366 content::ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE;
1421 // We are conservative here and assume requests are asynchronous in case 1367 // We are conservative here and assume requests are asynchronous in case
1422 // we don't have an info object. We don't want to risk a deadlock. 1368 // we don't have an info object. We don't want to risk a deadlock.
1423 bool is_async_request = false; 1369 bool is_async_request = false;
1424 bool is_request_from_extension = 1370 bool is_request_from_extension =
1425 IsRequestFromExtension(request, extension_info_map); 1371 IsRequestFromExtension(request, extension_info_map);
1426 1372
1427 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); 1373 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
1428 if (info) { 1374 if (info) {
1429 is_async_request = info->IsAsync(); 1375 is_async_request = info->IsAsync();
1430 if (helpers::IsRelevantResourceType(info->GetResourceType())) 1376 if (helpers::IsRelevantResourceType(info->GetResourceType()))
1431 resource_type = info->GetResourceType(); 1377 resource_type = info->GetResourceType();
1432 render_process_host_id = info->GetChildID(); 1378 render_process_host_id = info->GetChildID();
1433 routing_id = info->GetRouteID(); 1379 routing_id = info->GetRouteID();
1434 } 1380 }
1435 1381
1436 EventListeners matching_listeners; 1382 RawListeners matching_listeners;
1437 GetMatchingListenersImpl( 1383 GetMatchingListenersImpl(
1438 browser_context, request, extension_info_map, false, event_name, 1384 browser_context, request, extension_info_map, false, event_name,
1439 url, render_process_host_id, routing_id, resource_type, 1385 url, render_process_host_id, routing_id, resource_type,
1440 is_async_request, is_request_from_extension, extra_info_spec, 1386 is_async_request, is_request_from_extension, extra_info_spec,
1441 &matching_listeners); 1387 &matching_listeners);
1442 void* cross_browser_context = GetCrossBrowserContext(browser_context); 1388 void* cross_browser_context = GetCrossBrowserContext(browser_context);
1443 if (cross_browser_context) { 1389 if (cross_browser_context) {
1444 GetMatchingListenersImpl( 1390 GetMatchingListenersImpl(
1445 cross_browser_context, request, extension_info_map, true, event_name, 1391 cross_browser_context, request, extension_info_map, true, event_name,
1446 url, render_process_host_id, routing_id, resource_type, 1392 url, render_process_host_id, routing_id, resource_type,
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1645 // declarative rules to be read from disk. 1591 // declarative rules to be read from disk.
1646 UMA_HISTOGRAM_TIMES("Extensions.NetworkDelayStartup", block_time); 1592 UMA_HISTOGRAM_TIMES("Extensions.NetworkDelayStartup", block_time);
1647 } 1593 }
1648 1594
1649 if (num_handlers_blocking == 0) { 1595 if (num_handlers_blocking == 0) {
1650 blocked_request.request->LogUnblocked(); 1596 blocked_request.request->LogUnblocked();
1651 ExecuteDeltas(browser_context, request_id, true); 1597 ExecuteDeltas(browser_context, request_id, true);
1652 } else { 1598 } else {
1653 // Update the URLRequest to make sure it's tagged with an extension that's 1599 // Update the URLRequest to make sure it's tagged with an extension that's
1654 // still blocking it. This may end up being the same extension as before. 1600 // still blocking it. This may end up being the same extension as before.
1655 std::set<EventListener>& listeners = 1601 Listeners& listeners = listeners_[browser_context][event_name];
1656 listeners_[browser_context][event_name];
1657 1602
1658 for (const auto& listener : listeners) { 1603 for (const auto& listener : listeners) {
1659 if (!base::ContainsKey(listener.blocked_requests, request_id)) 1604 if (!base::ContainsKey(listener->blocked_requests, request_id))
1660 continue; 1605 continue;
1661 std::string delegate_info = 1606 std::string delegate_info = l10n_util::GetStringFUTF8(
1662 l10n_util::GetStringFUTF8(IDS_LOAD_STATE_PARAMETER_EXTENSION, 1607 IDS_LOAD_STATE_PARAMETER_EXTENSION,
1663 base::UTF8ToUTF16(listener.extension_name)); 1608 base::UTF8ToUTF16(listener->extension_name));
1664 blocked_request.request->LogAndReportBlockedBy(delegate_info.c_str()); 1609 blocked_request.request->LogAndReportBlockedBy(delegate_info.c_str());
1665 break; 1610 break;
1666 } 1611 }
1667 } 1612 }
1668 } 1613 }
1669 1614
1670 void ExtensionWebRequestEventRouter::SendMessages( 1615 void ExtensionWebRequestEventRouter::SendMessages(
1671 void* browser_context, 1616 void* browser_context,
1672 const BlockedRequest& blocked_request) { 1617 const BlockedRequest& blocked_request) {
1673 const helpers::EventResponseDeltas& deltas = blocked_request.response_deltas; 1618 const helpers::EventResponseDeltas& deltas = blocked_request.response_deltas;
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
2251 // Continue gracefully. 2196 // Continue gracefully.
2252 RunWithValidation()->Execute(); 2197 RunWithValidation()->Execute();
2253 } 2198 }
2254 2199
2255 ExtensionFunction::ResponseAction 2200 ExtensionFunction::ResponseAction
2256 WebRequestHandlerBehaviorChangedFunction::Run() { 2201 WebRequestHandlerBehaviorChangedFunction::Run() {
2257 helpers::ClearCacheOnNavigation(); 2202 helpers::ClearCacheOnNavigation();
2258 return RespondNow(NoArguments()); 2203 return RespondNow(NoArguments());
2259 } 2204 }
2260 2205
2206 ExtensionWebRequestEventRouter::EventListener::ID::ID(
2207 void* browser_context,
2208 const std::string& extension_id,
2209 const std::string& sub_event_name,
2210 int embedder_process_id,
2211 int web_view_instance_id)
2212 : browser_context(browser_context),
2213 extension_id(extension_id),
2214 sub_event_name(sub_event_name),
2215 embedder_process_id(embedder_process_id),
2216 web_view_instance_id(web_view_instance_id) {}
2217
2218 bool ExtensionWebRequestEventRouter::EventListener::ID::LooselyMatches(
2219 const ID& that) const {
2220 if (web_view_instance_id == 0 && that.web_view_instance_id == 0) {
2221 // Since EventListeners are segmented by browser_context, check that
2222 // last, as it is exceedingly unlikely to be different.
2223 return extension_id == that.extension_id &&
2224 sub_event_name == that.sub_event_name &&
2225 browser_context == that.browser_context;
2226 }
2227
2228 return *this == that;
2229 }
2230
2231 bool ExtensionWebRequestEventRouter::EventListener::ID::operator==(
2232 const ID& that) const {
2233 // Since EventListeners are segmented by browser_context, check that
2234 // last, as it is exceedingly unlikely to be different.
2235 return extension_id == that.extension_id &&
2236 sub_event_name == that.sub_event_name &&
2237 web_view_instance_id == that.web_view_instance_id &&
2238 embedder_process_id == that.embedder_process_id &&
2239 browser_context == that.browser_context;
2240 }
2241
2261 } // namespace extensions 2242 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/api/web_request/web_request_api.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698