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

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

Issue 2303113002: Fix semantics of ExtensionWebRequestEventRouter::EventListeners. (Closed)
Patch Set: Comments from rdevlin. 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
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::Identifier 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));
378 } 367 }
379 368
380 // Represents a single unique listener to an event, along with whatever filter 369 // 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 370 // parameters and extra_info_spec were specified at the time the listener was
382 // added. 371 // added.
383 // NOTE(benjhayden) New APIs should not use this sub_event_name trick! It does 372 // 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 373 // not play well with event pages. See downloads.onDeterminingFilename and
385 // ExtensionDownloadsEventRouter for an alternative approach. 374 // ExtensionDownloadsEventRouter for an alternative approach.
386 struct ExtensionWebRequestEventRouter::EventListener { 375 ExtensionWebRequestEventRouter::EventListener::EventListener(Identifier id)
387 std::string extension_id; 376 : id(id) {}
388 std::string extension_name; 377 ExtensionWebRequestEventRouter::EventListener::~EventListener() {}
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 ListenerPointers 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 ListenerPointers 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 ListenerPointers 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 ListenerPointers 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 ListenerPointers 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 ListenerPointers 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 int net_error) { 821 int net_error) {
874 DCHECK_NE(net::ERR_IO_PENDING, net_error); 822 DCHECK_NE(net::ERR_IO_PENDING, net_error);
875 823
876 if (ShouldHideEvent(browser_context, extension_info_map, request)) 824 if (ShouldHideEvent(browser_context, extension_info_map, request))
877 return; 825 return;
878 826
879 // OnResponseStarted is even triggered, when the request was cancelled. 827 // OnResponseStarted is even triggered, when the request was cancelled.
880 if (net_error != net::OK) 828 if (net_error != net::OK)
881 return; 829 return;
882 830
883 int extra_info_spec = 0; 831 int extra_info_spec = 0;
884 EventListeners listeners = GetMatchingListeners( 832 ListenerPointers listeners = GetMatchingListeners(
885 browser_context, extension_info_map, keys::kOnResponseStartedEvent, 833 browser_context, extension_info_map, keys::kOnResponseStartedEvent,
886 request, &extra_info_spec); 834 request, &extra_info_spec);
887 if (listeners.empty()) 835 if (listeners.empty())
888 return; 836 return;
889 837
890 std::unique_ptr<WebRequestEventDetails> event_details( 838 std::unique_ptr<WebRequestEventDetails> event_details(
891 CreateEventDetails(request, extra_info_spec)); 839 CreateEventDetails(request, extra_info_spec));
892 event_details->SetResponseHeaders(request, request->response_headers()); 840 event_details->SetResponseHeaders(request, request->response_headers());
893 event_details->SetResponseSource(request); 841 event_details->SetResponseSource(request);
894 842
(...skipping 28 matching lines...) Expand all
923 request_time_tracker_->LogRequestEndTime(request->identifier(), 871 request_time_tracker_->LogRequestEndTime(request->identifier(),
924 base::Time::Now()); 872 base::Time::Now());
925 873
926 DCHECK_EQ(net::OK, net_error); 874 DCHECK_EQ(net::OK, net_error);
927 875
928 DCHECK(!GetAndSetSignaled(request->identifier(), kOnCompleted)); 876 DCHECK(!GetAndSetSignaled(request->identifier(), kOnCompleted));
929 877
930 ClearPendingCallbacks(request); 878 ClearPendingCallbacks(request);
931 879
932 int extra_info_spec = 0; 880 int extra_info_spec = 0;
933 EventListeners listeners = 881 ListenerPointers listeners =
934 GetMatchingListeners(browser_context, extension_info_map, 882 GetMatchingListeners(browser_context, extension_info_map,
935 keys::kOnCompletedEvent, request, &extra_info_spec); 883 keys::kOnCompletedEvent, request, &extra_info_spec);
936 if (listeners.empty()) 884 if (listeners.empty())
937 return; 885 return;
938 886
939 std::unique_ptr<WebRequestEventDetails> event_details( 887 std::unique_ptr<WebRequestEventDetails> event_details(
940 CreateEventDetails(request, extra_info_spec)); 888 CreateEventDetails(request, extra_info_spec));
941 event_details->SetResponseHeaders(request, request->response_headers()); 889 event_details->SetResponseHeaders(request, request->response_headers());
942 event_details->SetResponseSource(request); 890 event_details->SetResponseSource(request);
943 891
(...skipping 30 matching lines...) Expand all
974 base::Time::Now()); 922 base::Time::Now());
975 923
976 DCHECK_NE(net::OK, net_error); 924 DCHECK_NE(net::OK, net_error);
977 DCHECK_NE(net::ERR_IO_PENDING, net_error); 925 DCHECK_NE(net::ERR_IO_PENDING, net_error);
978 926
979 DCHECK(!GetAndSetSignaled(request->identifier(), kOnErrorOccurred)); 927 DCHECK(!GetAndSetSignaled(request->identifier(), kOnErrorOccurred));
980 928
981 ClearPendingCallbacks(request); 929 ClearPendingCallbacks(request);
982 930
983 int extra_info_spec = 0; 931 int extra_info_spec = 0;
984 EventListeners listeners = GetMatchingListeners( 932 ListenerPointers listeners = GetMatchingListeners(
985 browser_context, extension_info_map, 933 browser_context, extension_info_map,
986 web_request::OnErrorOccurred::kEventName, request, &extra_info_spec); 934 web_request::OnErrorOccurred::kEventName, request, &extra_info_spec);
987 if (listeners.empty()) 935 if (listeners.empty())
988 return; 936 return;
989 937
990 std::unique_ptr<WebRequestEventDetails> event_details( 938 std::unique_ptr<WebRequestEventDetails> event_details(
991 CreateEventDetails(request, extra_info_spec)); 939 CreateEventDetails(request, extra_info_spec));
992 if (started) 940 if (started)
993 event_details->SetResponseSource(request); 941 event_details->SetResponseSource(request);
994 else 942 else
(...skipping 24 matching lines...) Expand all
1019 } 967 }
1020 968
1021 void ExtensionWebRequestEventRouter::ClearPendingCallbacks( 969 void ExtensionWebRequestEventRouter::ClearPendingCallbacks(
1022 const net::URLRequest* request) { 970 const net::URLRequest* request) {
1023 blocked_requests_.erase(request->identifier()); 971 blocked_requests_.erase(request->identifier());
1024 } 972 }
1025 973
1026 bool ExtensionWebRequestEventRouter::DispatchEvent( 974 bool ExtensionWebRequestEventRouter::DispatchEvent(
1027 void* browser_context, 975 void* browser_context,
1028 net::URLRequest* request, 976 net::URLRequest* request,
1029 const std::vector<const EventListener*>& listeners, 977 const ListenerPointers& listeners,
1030 std::unique_ptr<WebRequestEventDetails> event_details) { 978 std::unique_ptr<WebRequestEventDetails> event_details) {
1031 // TODO(mpcomplete): Consider consolidating common (extension_id,json_args) 979 // TODO(mpcomplete): Consider consolidating common (extension_id,json_args)
1032 // pairs into a single message sent to a list of sub_event_names. 980 // pairs into a single message sent to a list of sub_event_names.
1033 int num_handlers_blocking = 0; 981 int num_handlers_blocking = 0;
1034 982
1035 std::unique_ptr<std::vector<EventListener>> listeners_to_dispatch( 983 std::unique_ptr<ListenerIdentifiers> listeners_to_dispatch(
1036 new std::vector<EventListener>()); 984 new ListenerIdentifiers);
1037 listeners_to_dispatch->reserve(listeners.size()); 985 listeners_to_dispatch->reserve(listeners.size());
1038 for (const EventListener* listener : listeners) { 986 for (EventListener* listener : listeners) {
1039 listeners_to_dispatch->push_back(*listener); 987 listeners_to_dispatch->push_back(listener->id);
1040 if (listener->extra_info_spec & 988 if (listener->extra_info_spec &
1041 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) { 989 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) {
1042 listener->blocked_requests.insert(request->identifier()); 990 listener->blocked_requests.insert(request->identifier());
1043 // If this is the first delegate blocking the request, go ahead and log 991 // If this is the first delegate blocking the request, go ahead and log
1044 // it. 992 // it.
1045 if (num_handlers_blocking == 0) { 993 if (num_handlers_blocking == 0) {
1046 std::string delegate_info = l10n_util::GetStringFUTF8( 994 std::string delegate_info = l10n_util::GetStringFUTF8(
1047 IDS_LOAD_STATE_PARAMETER_EXTENSION, 995 IDS_LOAD_STATE_PARAMETER_EXTENSION,
1048 base::UTF8ToUTF16(listener->extension_name)); 996 base::UTF8ToUTF16(listener->extension_name));
1049 // LobAndReport allows extensions that block requests to be displayed in 997 // LobAndReport allows extensions that block requests to be displayed in
(...skipping 15 matching lines...) Expand all
1065 blocked_request.num_handlers_blocking += num_handlers_blocking; 1013 blocked_request.num_handlers_blocking += num_handlers_blocking;
1066 blocked_request.blocking_time = base::Time::Now(); 1014 blocked_request.blocking_time = base::Time::Now();
1067 return true; 1015 return true;
1068 } 1016 }
1069 1017
1070 return false; 1018 return false;
1071 } 1019 }
1072 1020
1073 void ExtensionWebRequestEventRouter::DispatchEventToListeners( 1021 void ExtensionWebRequestEventRouter::DispatchEventToListeners(
1074 void* browser_context, 1022 void* browser_context,
1075 std::unique_ptr<std::vector<EventListener>> listeners, 1023 std::unique_ptr<ListenerIdentifiers> listener_ids,
1076 std::unique_ptr<WebRequestEventDetails> event_details) { 1024 std::unique_ptr<WebRequestEventDetails> event_details) {
1077 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1025 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1078 DCHECK(listeners.get()); 1026 DCHECK(!listener_ids->empty());
1079 DCHECK_GT(listeners->size(), 0UL);
1080 DCHECK(event_details.get()); 1027 DCHECK(event_details.get());
1081 1028
1082 std::string event_name = 1029 std::string event_name =
1083 EventRouter::GetBaseEventName((*listeners)[0].sub_event_name); 1030 EventRouter::GetBaseEventName((*listener_ids)[0].sub_event_name);
1084 DCHECK(IsWebRequestEvent(event_name)); 1031 DCHECK(IsWebRequestEvent(event_name));
1085 1032
1086 const std::set<EventListener>& event_listeners = 1033 Listeners& event_listeners = listeners_[browser_context][event_name];
1087 listeners_[browser_context][event_name];
1088 void* cross_browser_context = GetCrossBrowserContext(browser_context); 1034 void* cross_browser_context = GetCrossBrowserContext(browser_context);
1089 const std::set<EventListener>* cross_event_listeners = 1035 Listeners* cross_event_listeners =
1090 cross_browser_context ? &listeners_[cross_browser_context][event_name] 1036 cross_browser_context ? &listeners_[cross_browser_context][event_name]
1091 : nullptr; 1037 : nullptr;
1092 1038
1093 for (const EventListener& target : *listeners) { 1039 for (const EventListener::Identifier& id : *listener_ids) {
1094 std::set<EventListener>::const_iterator listener = 1040 // It's possible that the listener is no longer present. Check to make sure
1095 event_listeners.find(target); 1041 // it's still there.
1096 // Ignore listener if it was removed between the thread hops. 1042 const EventListener* listener =
1097 if (listener == event_listeners.end()) { 1043 FindEventListenerInContainer(id, event_listeners);
1098 if (!cross_event_listeners) 1044 if (!listener && cross_event_listeners) {
1099 continue; 1045 listener = FindEventListenerInContainer(id, *cross_event_listeners);
1100 listener = cross_event_listeners->find(target);
1101 if (listener == cross_event_listeners->end())
1102 continue;
1103 } 1046 }
1047 if (!listener)
1048 continue;
1104 1049
1105 if (!listener->ipc_sender.get()) 1050 if (!listener->ipc_sender.get())
1106 continue; 1051 continue;
1107 1052
1108 // Filter out the optional keys that this listener didn't request. 1053 // Filter out the optional keys that this listener didn't request.
1109 std::unique_ptr<base::ListValue> args_filtered(new base::ListValue); 1054 std::unique_ptr<base::ListValue> args_filtered(new base::ListValue);
1110 args_filtered->Append( 1055 args_filtered->Append(
1111 event_details->GetFilteredDict(listener->extra_info_spec)); 1056 event_details->GetFilteredDict(listener->extra_info_spec));
1112 1057
1113 EventRouter::DispatchEventToSender( 1058 EventRouter::DispatchEventToSender(
1114 listener->ipc_sender.get(), browser_context, listener->extension_id, 1059 listener->ipc_sender.get(), browser_context, listener->id.extension_id,
1115 listener->histogram_value, listener->sub_event_name, 1060 listener->histogram_value, listener->id.sub_event_name,
1116 std::move(args_filtered), EventRouter::USER_GESTURE_UNKNOWN, 1061 std::move(args_filtered), EventRouter::USER_GESTURE_UNKNOWN,
1117 EventFilteringInfo()); 1062 EventFilteringInfo());
1118 } 1063 }
1119 } 1064 }
1120 1065
1121 void ExtensionWebRequestEventRouter::OnEventHandled( 1066 void ExtensionWebRequestEventRouter::OnEventHandled(
1122 void* browser_context, 1067 void* browser_context,
1123 const std::string& extension_id, 1068 const std::string& extension_id,
1124 const std::string& event_name, 1069 const std::string& event_name,
1125 const std::string& sub_event_name, 1070 const std::string& sub_event_name,
1126 uint64_t request_id, 1071 uint64_t request_id,
1127 EventResponse* response) { 1072 EventResponse* response) {
1128 // TODO(robwu): Does this also work with webviews? operator< (used by find) 1073 // TODO(robwu): This ignores WebViews.
1129 // takes the webview ID into account, which is not set on |listener|. 1074 Listeners& listeners = listeners_[browser_context][event_name];
1130 EventListener listener; 1075 EventListener::Identifier id(browser_context, extension_id, sub_event_name, 0,
1131 listener.extension_id = extension_id; 1076 0);
1132 listener.sub_event_name = sub_event_name; 1077 for (auto it = listeners.begin(); it != listeners.end(); ++it) {
1133 1078 if ((*it)->id.LooselyMatches(id)) {
1134 // The listener may have been removed (e.g. due to the process going away) 1079 (*it)->blocked_requests.erase(request_id);
1135 // before we got here. 1080 }
1136 std::set<EventListener>::iterator found = 1081 }
1137 listeners_[browser_context][event_name].find(listener);
1138 if (found != listeners_[browser_context][event_name].end())
1139 found->blocked_requests.erase(request_id);
1140 1082
1141 DecrementBlockCount( 1083 DecrementBlockCount(
1142 browser_context, extension_id, event_name, request_id, response); 1084 browser_context, extension_id, event_name, request_id, response);
1143 } 1085 }
1144 1086
1145 bool ExtensionWebRequestEventRouter::AddEventListener( 1087 bool ExtensionWebRequestEventRouter::AddEventListener(
1146 void* browser_context, 1088 void* browser_context,
1147 const std::string& extension_id, 1089 const std::string& extension_id,
1148 const std::string& extension_name, 1090 const std::string& extension_name,
1149 events::HistogramValue histogram_value, 1091 events::HistogramValue histogram_value,
1150 const std::string& event_name, 1092 const std::string& event_name,
1151 const std::string& sub_event_name, 1093 const std::string& sub_event_name,
1152 const RequestFilter& filter, 1094 const RequestFilter& filter,
1153 int extra_info_spec, 1095 int extra_info_spec,
1154 int embedder_process_id, 1096 int embedder_process_id,
1155 int web_view_instance_id, 1097 int web_view_instance_id,
1156 base::WeakPtr<IPC::Sender> ipc_sender) { 1098 base::WeakPtr<IPC::Sender> ipc_sender) {
1157 if (!IsWebRequestEvent(event_name)) 1099 if (!IsWebRequestEvent(event_name))
1158 return false; 1100 return false;
1159 1101
1160 EventListener listener; 1102 if (event_name != EventRouter::GetBaseEventName(sub_event_name))
1161 listener.extension_id = extension_id; 1103 return false;
1162 listener.extension_name = extension_name; 1104
1163 listener.histogram_value = histogram_value; 1105 EventListener::Identifier id(browser_context, extension_id, sub_event_name,
1164 listener.sub_event_name = sub_event_name; 1106 embedder_process_id, web_view_instance_id);
1165 listener.filter = filter; 1107 std::unique_ptr<EventListener> listener(new EventListener(id));
1166 listener.extra_info_spec = extra_info_spec; 1108 listener->extension_name = extension_name;
1167 listener.ipc_sender = ipc_sender; 1109 listener->histogram_value = histogram_value;
1168 listener.embedder_process_id = embedder_process_id; 1110 listener->filter = filter;
1169 listener.web_view_instance_id = web_view_instance_id; 1111 listener->extra_info_spec = extra_info_spec;
1170 if (listener.web_view_instance_id) { 1112 listener->ipc_sender = ipc_sender;
1113 if (listener->id.web_view_instance_id) {
Devlin 2016/09/08 17:33:12 nit: s/listener->id.web_view_instance_id/web_view_
erikchen 2016/09/08 18:34:42 Done.
1171 content::RecordAction( 1114 content::RecordAction(
1172 base::UserMetricsAction("WebView.WebRequest.AddListener")); 1115 base::UserMetricsAction("WebView.WebRequest.AddListener"));
1173 } 1116 }
1174 1117
1175 if (base::ContainsKey(listeners_[browser_context][event_name], listener)) { 1118 if (FindEventListener(id) != nullptr) {
Devlin 2016/09/08 17:33:12 Now that we search by id, we can move this before
erikchen 2016/09/08 18:34:42 Done.
1176 // This is likely an abuse of the API by a malicious extension. 1119 // This is likely an abuse of the API by a malicious extension.
1177 return false; 1120 return false;
1178 } 1121 }
1179 listeners_[browser_context][event_name].insert(listener); 1122 listeners_[browser_context][event_name].push_back(std::move(listener));
1180 return true; 1123 return true;
1181 } 1124 }
1182 1125
1126 size_t ExtensionWebRequestEventRouter::GetListenerCountForTesting(
1127 void* browser_context,
1128 const std::string& event_name) {
1129 return listeners_[browser_context][event_name].size();
1130 }
1131
1132 ExtensionWebRequestEventRouter::EventListener*
1133 ExtensionWebRequestEventRouter::FindEventListener(
1134 const EventListener::Identifier& id) {
1135 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1136 std::string event_name = EventRouter::GetBaseEventName(id.sub_event_name);
1137 Listeners& listeners = listeners_[id.browser_context][event_name];
1138 return FindEventListenerInContainer(id, listeners);
1139 }
1140
1141 ExtensionWebRequestEventRouter::EventListener*
1142 ExtensionWebRequestEventRouter::FindEventListenerInContainer(
Devlin 2016/09/08 17:33:12 nit: put this in the anonymous namespace instead?
erikchen 2016/09/08 18:34:42 Can't do that, as this uses private members of Ext
Devlin 2016/09/08 19:53:32 Oh, sneaky. Forgot that event listener id itself w
1143 const EventListener::Identifier& id,
1144 Listeners& listeners) {
1145 for (auto it = listeners.begin(); it != listeners.end(); ++it) {
1146 if ((*it)->id == id) {
1147 return it->get();
1148 }
1149 }
1150 return nullptr;
1151 }
1152
1183 void ExtensionWebRequestEventRouter::RemoveEventListener( 1153 void ExtensionWebRequestEventRouter::RemoveEventListener(
1184 void* browser_context, 1154 const EventListener::Identifier& id) {
1185 const std::string& extension_id, 1155 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1186 const std::string& sub_event_name,
1187 int embedder_process_id,
1188 int web_view_instance_id) {
1189 std::string event_name = EventRouter::GetBaseEventName(sub_event_name);
1190 DCHECK(IsWebRequestEvent(event_name));
1191 1156
1192 EventListener listener; 1157 std::string event_name = EventRouter::GetBaseEventName(id.sub_event_name);
1193 listener.extension_id = extension_id; 1158 Listeners& listeners = listeners_[id.browser_context][event_name];
1194 listener.sub_event_name = sub_event_name; 1159 for (auto it = listeners.begin(); it != listeners.end(); ++it) {
1195 listener.embedder_process_id = embedder_process_id; 1160 std::unique_ptr<EventListener>& listener = *it;
1196 listener.web_view_instance_id = web_view_instance_id; 1161 if (listener->id.LooselyMatches(id)) {
1162 // Unblock any request that this event listener may have been blocking.
1163 for (uint64_t blocked_request_id : listener->blocked_requests)
1164 DecrementBlockCount(listener->id.browser_context,
1165 listener->id.extension_id, event_name,
1166 blocked_request_id, NULL);
Devlin 2016/09/08 17:33:12 nit: nullptr
erikchen 2016/09/08 18:34:42 Done.
1197 1167
1198 std::set<EventListener>& event_listeners = 1168 listeners.erase(it);
1199 listeners_[browser_context][event_name]; 1169 helpers::ClearCacheOnNavigation();
1200 // It's possible for AddEventListener to fail asynchronously. In that case, 1170 return;
1201 // the renderer believes the listener exists, while the browser does not. 1171 }
1202 // Ignore a RemoveEventListener in that case. 1172 }
1203 std::set<EventListener>::const_iterator it = event_listeners.find(listener);
1204 if (it == event_listeners.end())
1205 return;
1206
1207 #if defined(OS_WIN)
1208 // Debugging https://crbug.com/589735
Devlin 2016/09/08 17:33:12 Hmm... so this does fix the bug of the release ass
erikchen 2016/09/08 18:34:42 No. My CL has the same behavior as the previous co
Devlin 2016/09/08 19:53:32 Right, that's what I was saying. This fixes the r
1209 // Please post crash reports at the following lines to the above issue.
1210 unsigned event_listener_count = event_listeners.count(listener);
1211 CHECK_GE(event_listener_count, 0u);
1212 CHECK_GE(event_listener_count, 1u);
1213 CHECK_LE(event_listener_count, 2u);
1214 CHECK_EQ(event_listener_count, 1u);
1215 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
1216 #endif // OS_WIN
1217 CHECK_EQ(event_listeners.count(listener), 1u) <<
1218 "extension=" << extension_id << " event=" << event_name;
1219
1220 // Unblock any request that this event listener may have been blocking.
1221 for (uint64_t id : it->blocked_requests)
1222 DecrementBlockCount(browser_context, extension_id, event_name, id, NULL);
1223
1224 event_listeners.erase(listener);
1225
1226 helpers::ClearCacheOnNavigation();
1227 } 1173 }
1228 1174
1229 void ExtensionWebRequestEventRouter::RemoveWebViewEventListeners( 1175 void ExtensionWebRequestEventRouter::RemoveWebViewEventListeners(
1230 void* browser_context, 1176 void* browser_context,
1231 int embedder_process_id, 1177 int embedder_process_id,
1232 int web_view_instance_id) { 1178 int web_view_instance_id) {
1233 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1179 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1234 1180
1235 // Iterate over all listeners of all WebRequest events to delete 1181 // Iterate over all listeners of all WebRequest events to delete
1236 // any listeners that belong to the provided <webview>. 1182 // any listeners that belong to the provided <webview>.
1237 ListenerMapForBrowserContext& map_for_browser_context = 1183 ListenerMapForBrowserContext& map_for_browser_context =
1238 listeners_[browser_context]; 1184 listeners_[browser_context];
1239 for (const auto& event_iter : map_for_browser_context) { 1185 for (const auto& event_iter : map_for_browser_context) {
1240 // Construct a listeners_to_delete vector so that we don't modify the set of 1186 // Construct a listeners_to_delete vector so that we don't modify the set of
1241 // listeners as we iterate through it. 1187 // listeners as we iterate through it.
1242 std::vector<EventListener> listeners_to_delete; 1188 std::vector<EventListener::Identifier> listeners_to_delete;
1243 const std::set<EventListener>& listeners = event_iter.second; 1189 const Listeners& listeners = event_iter.second;
1244 for (const auto& listener : listeners) { 1190 for (const auto& listener : listeners) {
1245 if (listener.embedder_process_id == embedder_process_id && 1191 if (listener->id.embedder_process_id == embedder_process_id &&
1246 listener.web_view_instance_id == web_view_instance_id) { 1192 listener->id.web_view_instance_id == web_view_instance_id) {
1247 listeners_to_delete.push_back(listener); 1193 listeners_to_delete.push_back(listener->id);
1248 } 1194 }
1249 } 1195 }
1250 // Remove the listeners selected for deletion. 1196 // Remove the listeners selected for deletion.
1251 for (const auto& listener : listeners_to_delete) { 1197 for (const auto& listener_id : listeners_to_delete)
1252 RemoveEventListenerOnIOThread( 1198 RemoveEventListener(listener_id);
1253 browser_context,
1254 listener.extension_id,
1255 listener.sub_event_name,
1256 listener.embedder_process_id,
1257 listener.web_view_instance_id);
1258 }
1259 } 1199 }
1260 } 1200 }
1261 1201
1262 void ExtensionWebRequestEventRouter::OnOTRBrowserContextCreated( 1202 void ExtensionWebRequestEventRouter::OnOTRBrowserContextCreated(
1263 void* original_browser_context, void* otr_browser_context) { 1203 void* original_browser_context, void* otr_browser_context) {
1264 cross_browser_context_map_[original_browser_context] = 1204 cross_browser_context_map_[original_browser_context] =
1265 std::make_pair(false, otr_browser_context); 1205 std::make_pair(false, otr_browser_context);
1266 cross_browser_context_map_[otr_browser_context] = 1206 cross_browser_context_map_[otr_browser_context] =
1267 std::make_pair(true, original_browser_context); 1207 std::make_pair(true, original_browser_context);
1268 } 1208 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1324 const InfoMap* extension_info_map, 1264 const InfoMap* extension_info_map,
1325 bool crosses_incognito, 1265 bool crosses_incognito,
1326 const std::string& event_name, 1266 const std::string& event_name,
1327 const GURL& url, 1267 const GURL& url,
1328 int render_process_host_id, 1268 int render_process_host_id,
1329 int routing_id, 1269 int routing_id,
1330 content::ResourceType resource_type, 1270 content::ResourceType resource_type,
1331 bool is_async_request, 1271 bool is_async_request,
1332 bool is_request_from_extension, 1272 bool is_request_from_extension,
1333 int* extra_info_spec, 1273 int* extra_info_spec,
1334 EventListeners* matching_listeners) { 1274 ListenerPointers* matching_listeners) {
1335 std::string web_request_event_name(event_name); 1275 std::string web_request_event_name(event_name);
1336 WebViewRendererState::WebViewInfo web_view_info; 1276 WebViewRendererState::WebViewInfo web_view_info;
1337 bool is_web_view_guest = WebViewRendererState::GetInstance()->GetInfo( 1277 bool is_web_view_guest = WebViewRendererState::GetInstance()->GetInfo(
1338 render_process_host_id, routing_id, &web_view_info); 1278 render_process_host_id, routing_id, &web_view_info);
1339 if (is_web_view_guest) { 1279 if (is_web_view_guest) {
1340 web_request_event_name.replace( 1280 web_request_event_name.replace(
1341 0, sizeof(kWebRequestEventPrefix) - 1, webview::kWebViewEventPrefix); 1281 0, sizeof(kWebRequestEventPrefix) - 1, webview::kWebViewEventPrefix);
1342 } 1282 }
1343 1283
1344 std::set<EventListener>& listeners = 1284 Listeners& listeners = listeners_[browser_context][web_request_event_name];
1345 listeners_[browser_context][web_request_event_name]; 1285 for (std::unique_ptr<EventListener>& listener : listeners) {
1346 for (const EventListener& listener : listeners) { 1286 if (!listener->ipc_sender.get()) {
1347 if (!listener.ipc_sender.get()) {
1348 // The IPC sender has been deleted. This listener will be removed soon 1287 // The IPC sender has been deleted. This listener will be removed soon
1349 // via a call to RemoveEventListener. For now, just skip it. 1288 // via a call to RemoveEventListener. For now, just skip it.
1350 continue; 1289 continue;
1351 } 1290 }
1352 1291
1353 if (is_web_view_guest && 1292 if (is_web_view_guest &&
1354 (listener.embedder_process_id != web_view_info.embedder_process_id || 1293 (listener->id.embedder_process_id !=
1355 listener.web_view_instance_id != web_view_info.instance_id)) { 1294 web_view_info.embedder_process_id ||
1295 listener->id.web_view_instance_id != web_view_info.instance_id)) {
1356 continue; 1296 continue;
1357 } 1297 }
1358 1298
1359 // Filter requests from other extensions / apps. This does not work for 1299 // Filter requests from other extensions / apps. This does not work for
1360 // content scripts, or extension pages in non-extension processes. 1300 // content scripts, or extension pages in non-extension processes.
1361 if (is_request_from_extension && 1301 if (is_request_from_extension &&
1362 listener.embedder_process_id != render_process_host_id) { 1302 listener->id.embedder_process_id != render_process_host_id) {
1363 continue; 1303 continue;
1364 } 1304 }
1365 1305
1366 if (!listener.filter.urls.is_empty() && 1306 if (!listener->filter.urls.is_empty() &&
1367 !listener.filter.urls.MatchesURL(url)) { 1307 !listener->filter.urls.MatchesURL(url)) {
1368 continue; 1308 continue;
1369 } 1309 }
1370 1310
1371 int render_process_id = -1; 1311 int render_process_id = -1;
1372 int render_frame_id = -1; 1312 int render_frame_id = -1;
1373 // TODO(devlin): Figure out when one/both of these can fail, and if we 1313 // TODO(devlin): Figure out when one/both of these can fail, and if we
1374 // need to address it. 1314 // need to address it.
1375 bool found_render_frame = 1315 bool found_render_frame =
1376 content::ResourceRequestInfo::GetRenderFrameForRequest( 1316 content::ResourceRequestInfo::GetRenderFrameForRequest(
1377 request, &render_process_id, &render_frame_id); 1317 request, &render_process_id, &render_frame_id);
1378 UMA_HISTOGRAM_BOOLEAN("Extensions.WebRequestEventFoundFrame", 1318 UMA_HISTOGRAM_BOOLEAN("Extensions.WebRequestEventFoundFrame",
1379 found_render_frame); 1319 found_render_frame);
1380 ExtensionApiFrameIdMap::FrameData frame_data; 1320 ExtensionApiFrameIdMap::FrameData frame_data;
1381 if (found_render_frame) { 1321 if (found_render_frame) {
1382 ExtensionApiFrameIdMap::Get()->GetCachedFrameDataOnIO( 1322 ExtensionApiFrameIdMap::Get()->GetCachedFrameDataOnIO(
1383 render_process_id, render_frame_id, &frame_data); 1323 render_process_id, render_frame_id, &frame_data);
1384 } 1324 }
1385 // Check if the tab id and window id match, if they were set in the 1325 // Check if the tab id and window id match, if they were set in the
1386 // listener params. 1326 // listener params.
1387 if ((listener.filter.tab_id != -1 && 1327 if ((listener->filter.tab_id != -1 &&
1388 frame_data.tab_id != listener.filter.tab_id) || 1328 frame_data.tab_id != listener->filter.tab_id) ||
1389 (listener.filter.window_id != -1 && 1329 (listener->filter.window_id != -1 &&
1390 frame_data.window_id != listener.filter.window_id)) { 1330 frame_data.window_id != listener->filter.window_id)) {
1391 continue; 1331 continue;
1392 } 1332 }
1393 1333
1394 const std::vector<content::ResourceType>& types = listener.filter.types; 1334 const std::vector<content::ResourceType>& types = listener->filter.types;
1395 if (!types.empty() && 1335 if (!types.empty() &&
1396 std::find(types.begin(), types.end(), resource_type) == types.end()) { 1336 std::find(types.begin(), types.end(), resource_type) == types.end()) {
1397 continue; 1337 continue;
1398 } 1338 }
1399 1339
1400 if (!is_web_view_guest) { 1340 if (!is_web_view_guest) {
1401 PermissionsData::AccessType access = 1341 PermissionsData::AccessType access =
1402 WebRequestPermissions::CanExtensionAccessURL( 1342 WebRequestPermissions::CanExtensionAccessURL(
1403 extension_info_map, listener.extension_id, url, frame_data.tab_id, 1343 extension_info_map, listener->id.extension_id, url,
1404 crosses_incognito, 1344 frame_data.tab_id, crosses_incognito,
1405 WebRequestPermissions::REQUIRE_HOST_PERMISSION); 1345 WebRequestPermissions::REQUIRE_HOST_PERMISSION);
1406 if (access != PermissionsData::ACCESS_ALLOWED) { 1346 if (access != PermissionsData::ACCESS_ALLOWED) {
1407 if (access == PermissionsData::ACCESS_WITHHELD && 1347 if (access == PermissionsData::ACCESS_WITHHELD &&
1408 web_request_event_router_delegate_) { 1348 web_request_event_router_delegate_) {
1409 web_request_event_router_delegate_->NotifyWebRequestWithheld( 1349 web_request_event_router_delegate_->NotifyWebRequestWithheld(
1410 render_process_id, render_frame_id, listener.extension_id); 1350 render_process_id, render_frame_id, listener->id.extension_id);
1411 } 1351 }
1412 continue; 1352 continue;
1413 } 1353 }
1414 } 1354 }
1415 1355
1416 bool blocking_listener = 1356 bool blocking_listener =
1417 (listener.extra_info_spec & 1357 (listener->extra_info_spec &
1418 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) != 0; 1358 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) != 0;
1419 1359
1420 // We do not want to notify extensions about XHR requests that are 1360 // We do not want to notify extensions about XHR requests that are
1421 // triggered by themselves. This is a workaround to prevent deadlocks 1361 // triggered by themselves. This is a workaround to prevent deadlocks
1422 // in case of synchronous XHR requests that block the extension renderer 1362 // in case of synchronous XHR requests that block the extension renderer
1423 // and therefore prevent the extension from processing the request 1363 // and therefore prevent the extension from processing the request
1424 // handler. This is only a problem for blocking listeners. 1364 // handler. This is only a problem for blocking listeners.
1425 // http://crbug.com/105656 1365 // http://crbug.com/105656
1426 bool synchronous_xhr_from_extension = 1366 bool synchronous_xhr_from_extension =
1427 !is_async_request && is_request_from_extension && 1367 !is_async_request && is_request_from_extension &&
1428 resource_type == content::RESOURCE_TYPE_XHR; 1368 resource_type == content::RESOURCE_TYPE_XHR;
1429 1369
1430 // Only send webRequest events for URLs the extension has access to. 1370 // Only send webRequest events for URLs the extension has access to.
1431 if (blocking_listener && synchronous_xhr_from_extension) 1371 if (blocking_listener && synchronous_xhr_from_extension)
1432 continue; 1372 continue;
1433 1373
1434 matching_listeners->push_back(&listener); 1374 matching_listeners->push_back(listener.get());
1435 *extra_info_spec |= listener.extra_info_spec; 1375 *extra_info_spec |= listener->extra_info_spec;
1436 } 1376 }
1437 } 1377 }
1438 1378
1439 ExtensionWebRequestEventRouter::EventListeners 1379 ExtensionWebRequestEventRouter::ListenerPointers
1440 ExtensionWebRequestEventRouter::GetMatchingListeners( 1380 ExtensionWebRequestEventRouter::GetMatchingListeners(
1441 void* browser_context, 1381 void* browser_context,
1442 const InfoMap* extension_info_map, 1382 const InfoMap* extension_info_map,
1443 const std::string& event_name, 1383 const std::string& event_name,
1444 const net::URLRequest* request, 1384 const net::URLRequest* request,
1445 int* extra_info_spec) { 1385 int* extra_info_spec) {
1446 // TODO(mpcomplete): handle browser_context == NULL (should collect all 1386 // TODO(mpcomplete): handle browser_context == NULL (should collect all
1447 // listeners). 1387 // listeners).
1448 *extra_info_spec = 0; 1388 *extra_info_spec = 0;
1449 1389
1450 const GURL& url = request->url(); 1390 const GURL& url = request->url();
1451 int render_process_host_id = content::ChildProcessHost::kInvalidUniqueID; 1391 int render_process_host_id = content::ChildProcessHost::kInvalidUniqueID;
1452 int routing_id = MSG_ROUTING_NONE; 1392 int routing_id = MSG_ROUTING_NONE;
1453 content::ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE; 1393 content::ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE;
1454 // We are conservative here and assume requests are asynchronous in case 1394 // We are conservative here and assume requests are asynchronous in case
1455 // we don't have an info object. We don't want to risk a deadlock. 1395 // we don't have an info object. We don't want to risk a deadlock.
1456 bool is_async_request = false; 1396 bool is_async_request = false;
1457 bool is_request_from_extension = 1397 bool is_request_from_extension =
1458 IsRequestFromExtension(request, extension_info_map); 1398 IsRequestFromExtension(request, extension_info_map);
1459 1399
1460 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); 1400 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
1461 if (info) { 1401 if (info) {
1462 is_async_request = info->IsAsync(); 1402 is_async_request = info->IsAsync();
1463 if (helpers::IsRelevantResourceType(info->GetResourceType())) 1403 if (helpers::IsRelevantResourceType(info->GetResourceType()))
1464 resource_type = info->GetResourceType(); 1404 resource_type = info->GetResourceType();
1465 render_process_host_id = info->GetChildID(); 1405 render_process_host_id = info->GetChildID();
1466 routing_id = info->GetRouteID(); 1406 routing_id = info->GetRouteID();
1467 } 1407 }
1468 1408
1469 EventListeners matching_listeners; 1409 ListenerPointers matching_listeners;
1470 GetMatchingListenersImpl( 1410 GetMatchingListenersImpl(
1471 browser_context, request, extension_info_map, false, event_name, 1411 browser_context, request, extension_info_map, false, event_name,
1472 url, render_process_host_id, routing_id, resource_type, 1412 url, render_process_host_id, routing_id, resource_type,
1473 is_async_request, is_request_from_extension, extra_info_spec, 1413 is_async_request, is_request_from_extension, extra_info_spec,
1474 &matching_listeners); 1414 &matching_listeners);
1475 void* cross_browser_context = GetCrossBrowserContext(browser_context); 1415 void* cross_browser_context = GetCrossBrowserContext(browser_context);
1476 if (cross_browser_context) { 1416 if (cross_browser_context) {
1477 GetMatchingListenersImpl( 1417 GetMatchingListenersImpl(
1478 cross_browser_context, request, extension_info_map, true, event_name, 1418 cross_browser_context, request, extension_info_map, true, event_name,
1479 url, render_process_host_id, routing_id, resource_type, 1419 url, render_process_host_id, routing_id, resource_type,
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1678 // declarative rules to be read from disk. 1618 // declarative rules to be read from disk.
1679 UMA_HISTOGRAM_TIMES("Extensions.NetworkDelayStartup", block_time); 1619 UMA_HISTOGRAM_TIMES("Extensions.NetworkDelayStartup", block_time);
1680 } 1620 }
1681 1621
1682 if (num_handlers_blocking == 0) { 1622 if (num_handlers_blocking == 0) {
1683 blocked_request.request->LogUnblocked(); 1623 blocked_request.request->LogUnblocked();
1684 ExecuteDeltas(browser_context, request_id, true); 1624 ExecuteDeltas(browser_context, request_id, true);
1685 } else { 1625 } else {
1686 // Update the URLRequest to make sure it's tagged with an extension that's 1626 // Update the URLRequest to make sure it's tagged with an extension that's
1687 // still blocking it. This may end up being the same extension as before. 1627 // still blocking it. This may end up being the same extension as before.
1688 std::set<EventListener>& listeners = 1628 Listeners& listeners = listeners_[browser_context][event_name];
1689 listeners_[browser_context][event_name];
1690 1629
1691 for (const auto& listener : listeners) { 1630 for (const auto& listener : listeners) {
1692 if (!base::ContainsKey(listener.blocked_requests, request_id)) 1631 if (!base::ContainsKey(listener->blocked_requests, request_id))
1693 continue; 1632 continue;
1694 std::string delegate_info = 1633 std::string delegate_info = l10n_util::GetStringFUTF8(
1695 l10n_util::GetStringFUTF8(IDS_LOAD_STATE_PARAMETER_EXTENSION, 1634 IDS_LOAD_STATE_PARAMETER_EXTENSION,
1696 base::UTF8ToUTF16(listener.extension_name)); 1635 base::UTF8ToUTF16(listener->extension_name));
1697 blocked_request.request->LogAndReportBlockedBy(delegate_info.c_str()); 1636 blocked_request.request->LogAndReportBlockedBy(delegate_info.c_str());
1698 break; 1637 break;
1699 } 1638 }
1700 } 1639 }
1701 } 1640 }
1702 1641
1703 void ExtensionWebRequestEventRouter::SendMessages( 1642 void ExtensionWebRequestEventRouter::SendMessages(
1704 void* browser_context, 1643 void* browser_context,
1705 const BlockedRequest& blocked_request) { 1644 const BlockedRequest& blocked_request) {
1706 const helpers::EventResponseDeltas& deltas = blocked_request.response_deltas; 1645 const helpers::EventResponseDeltas& deltas = blocked_request.response_deltas;
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
2284 // Continue gracefully. 2223 // Continue gracefully.
2285 RunWithValidation()->Execute(); 2224 RunWithValidation()->Execute();
2286 } 2225 }
2287 2226
2288 ExtensionFunction::ResponseAction 2227 ExtensionFunction::ResponseAction
2289 WebRequestHandlerBehaviorChangedFunction::Run() { 2228 WebRequestHandlerBehaviorChangedFunction::Run() {
2290 helpers::ClearCacheOnNavigation(); 2229 helpers::ClearCacheOnNavigation();
2291 return RespondNow(NoArguments()); 2230 return RespondNow(NoArguments());
2292 } 2231 }
2293 2232
2233 ExtensionWebRequestEventRouter::EventListener::Identifier::Identifier(
2234 void* browser_context,
2235 const std::string& extension_id,
2236 const std::string& sub_event_name,
2237 int embedder_process_id,
2238 int web_view_instance_id)
2239 : browser_context(browser_context),
2240 extension_id(extension_id),
2241 sub_event_name(sub_event_name),
2242 embedder_process_id(embedder_process_id),
2243 web_view_instance_id(web_view_instance_id) {}
2244
2245 bool ExtensionWebRequestEventRouter::EventListener::Identifier::LooselyMatches(
2246 const Identifier& that) const {
2247 if (web_view_instance_id == 0 && that.web_view_instance_id == 0) {
2248 // Since EventListeners are segmented by browser_context, check that
2249 // last, as it is exceedingly unlikely to be different.
2250 return extension_id == that.extension_id &&
2251 sub_event_name == that.sub_event_name &&
2252 browser_context == that.browser_context;
2253 }
2254
2255 return *this == that;
2256 }
2257
2258 bool ExtensionWebRequestEventRouter::EventListener::Identifier::operator==(
2259 const Identifier& that) const {
2260 // Since EventListeners are segmented by browser_context, check that
2261 // last, as it is exceedingly unlikely to be different.
2262 return extension_id == that.extension_id &&
2263 sub_event_name == that.sub_event_name &&
2264 web_view_instance_id == that.web_view_instance_id &&
2265 embedder_process_id == that.embedder_process_id &&
2266 browser_context == that.browser_context;
2267 }
2268
2294 } // namespace extensions 2269 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698