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

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

Issue 2303113002: Fix semantics of ExtensionWebRequestEventRouter::EventListeners. (Closed)
Patch Set: Compile error on Linux. 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 ListenerIdentifiers 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 ListenerIdentifiers 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 ListenerIdentifiers 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 ListenerIdentifiers 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 ListenerIdentifiers 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 ListenerIdentifiers 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 ListenerIdentifiers 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 ListenerIdentifiers 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 ListenerIdentifiers 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 ListenerIdentifiers& 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 for (const EventListener::Identifier& id : listeners) {
1036 new std::vector<EventListener>()); 984 EventListener* listener = FindEventListener(id);
Devlin 2016/09/07 19:18:00 This makes me a bit sad, because it means we have
erikchen 2016/09/07 22:07:42 yup, done.
1037 listeners_to_dispatch->reserve(listeners.size());
1038 for (const EventListener* listener : listeners) {
1039 listeners_to_dispatch->push_back(*listener);
1040 if (listener->extra_info_spec & 985 if (listener->extra_info_spec &
1041 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) { 986 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) {
1042 listener->blocked_requests.insert(request->identifier()); 987 listener->blocked_requests.insert(request->identifier());
1043 // If this is the first delegate blocking the request, go ahead and log 988 // If this is the first delegate blocking the request, go ahead and log
1044 // it. 989 // it.
1045 if (num_handlers_blocking == 0) { 990 if (num_handlers_blocking == 0) {
1046 std::string delegate_info = l10n_util::GetStringFUTF8( 991 std::string delegate_info = l10n_util::GetStringFUTF8(
1047 IDS_LOAD_STATE_PARAMETER_EXTENSION, 992 IDS_LOAD_STATE_PARAMETER_EXTENSION,
1048 base::UTF8ToUTF16(listener->extension_name)); 993 base::UTF8ToUTF16(listener->extension_name));
1049 // LobAndReport allows extensions that block requests to be displayed in 994 // LobAndReport allows extensions that block requests to be displayed in
1050 // the load status bar. 995 // the load status bar.
1051 request->LogAndReportBlockedBy(delegate_info.c_str()); 996 request->LogAndReportBlockedBy(delegate_info.c_str());
1052 } 997 }
1053 ++num_handlers_blocking; 998 ++num_handlers_blocking;
1054 } 999 }
1055 } 1000 }
1056 1001
1057 event_details.release()->DetermineFrameDataOnIO(base::Bind( 1002 event_details.release()->DetermineFrameDataOnIO(
1058 &ExtensionWebRequestEventRouter::DispatchEventToListeners, AsWeakPtr(), 1003 base::Bind(&ExtensionWebRequestEventRouter::DispatchEventToListeners,
1059 browser_context, base::Passed(&listeners_to_dispatch))); 1004 AsWeakPtr(), browser_context, listeners));
Devlin 2016/09/07 19:18:00 Optimization: Shame about the copy this causes on
erikchen 2016/09/07 22:07:42 Done.
1060 1005
1061 if (num_handlers_blocking > 0) { 1006 if (num_handlers_blocking > 0) {
1062 BlockedRequest& blocked_request = blocked_requests_[request->identifier()]; 1007 BlockedRequest& blocked_request = blocked_requests_[request->identifier()];
1063 blocked_request.request = request; 1008 blocked_request.request = request;
1064 blocked_request.is_incognito |= IsIncognitoBrowserContext(browser_context); 1009 blocked_request.is_incognito |= IsIncognitoBrowserContext(browser_context);
1065 blocked_request.num_handlers_blocking += num_handlers_blocking; 1010 blocked_request.num_handlers_blocking += num_handlers_blocking;
1066 blocked_request.blocking_time = base::Time::Now(); 1011 blocked_request.blocking_time = base::Time::Now();
1067 return true; 1012 return true;
1068 } 1013 }
1069 1014
1070 return false; 1015 return false;
1071 } 1016 }
1072 1017
1073 void ExtensionWebRequestEventRouter::DispatchEventToListeners( 1018 void ExtensionWebRequestEventRouter::DispatchEventToListeners(
1074 void* browser_context, 1019 void* browser_context,
1075 std::unique_ptr<std::vector<EventListener>> listeners, 1020 const ListenerIdentifiers& listener_ids,
1076 std::unique_ptr<WebRequestEventDetails> event_details) { 1021 std::unique_ptr<WebRequestEventDetails> event_details) {
1077 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1022 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1078 DCHECK(listeners.get()); 1023 DCHECK_GT(listener_ids.size(), 0UL);
Devlin 2016/09/07 19:18:00 nit: DCHECK(!listener_ids.empty())
erikchen 2016/09/07 22:07:42 Done.
1079 DCHECK_GT(listeners->size(), 0UL);
1080 DCHECK(event_details.get()); 1024 DCHECK(event_details.get());
1081 1025
1082 std::string event_name = 1026 std::string event_name =
1083 EventRouter::GetBaseEventName((*listeners)[0].sub_event_name); 1027 EventRouter::GetBaseEventName(listener_ids[0].sub_event_name);
1084 DCHECK(IsWebRequestEvent(event_name)); 1028 DCHECK(IsWebRequestEvent(event_name));
1085 1029
1086 const std::set<EventListener>& event_listeners = 1030 const Listeners& event_listeners = listeners_[browser_context][event_name];
1087 listeners_[browser_context][event_name];
1088 void* cross_browser_context = GetCrossBrowserContext(browser_context); 1031 void* cross_browser_context = GetCrossBrowserContext(browser_context);
1089 const std::set<EventListener>* cross_event_listeners = 1032 const Listeners* cross_event_listeners =
1090 cross_browser_context ? &listeners_[cross_browser_context][event_name] 1033 cross_browser_context ? &listeners_[cross_browser_context][event_name]
1091 : nullptr; 1034 : nullptr;
1092 1035
1093 for (const EventListener& target : *listeners) { 1036 for (const EventListener::Identifier& id : listener_ids) {
1094 std::set<EventListener>::const_iterator listener = 1037 // It's possible that the listener is no longer present. Check to make sure
1095 event_listeners.find(target); 1038 // it's still there.
1096 // Ignore listener if it was removed between the thread hops. 1039 const EventListener* listener = nullptr;
1097 if (listener == event_listeners.end()) { 1040 for (const std::unique_ptr<EventListener>& event_listener :
Devlin 2016/09/07 19:18:00 Worth making a FindEventListenerInSet() helper fun
erikchen 2016/09/07 22:07:42 yes, done.
1098 if (!cross_event_listeners) 1041 event_listeners) {
1099 continue; 1042 if (event_listener->id == id) {
1100 listener = cross_event_listeners->find(target); 1043 listener = event_listener.get();
1101 if (listener == cross_event_listeners->end()) 1044 break;
1102 continue; 1045 }
1103 } 1046 }
1047 if (!listener) {
1048 for (const std::unique_ptr<EventListener>& event_listener :
1049 *cross_event_listeners) {
1050 if (event_listener->id == id) {
1051 listener = event_listener.get();
1052 break;
1053 }
1054 }
1055 }
1056 if (!listener)
1057 continue;
1104 1058
1105 if (!listener->ipc_sender.get()) 1059 if (!listener->ipc_sender.get())
1106 continue; 1060 continue;
1107 1061
1108 // Filter out the optional keys that this listener didn't request. 1062 // Filter out the optional keys that this listener didn't request.
1109 std::unique_ptr<base::ListValue> args_filtered(new base::ListValue); 1063 std::unique_ptr<base::ListValue> args_filtered(new base::ListValue);
1110 args_filtered->Append( 1064 args_filtered->Append(
1111 event_details->GetFilteredDict(listener->extra_info_spec)); 1065 event_details->GetFilteredDict(listener->extra_info_spec));
1112 1066
1113 EventRouter::DispatchEventToSender( 1067 EventRouter::DispatchEventToSender(
1114 listener->ipc_sender.get(), browser_context, listener->extension_id, 1068 listener->ipc_sender.get(), browser_context, listener->id.extension_id,
1115 listener->histogram_value, listener->sub_event_name, 1069 listener->histogram_value, listener->id.sub_event_name,
1116 std::move(args_filtered), EventRouter::USER_GESTURE_UNKNOWN, 1070 std::move(args_filtered), EventRouter::USER_GESTURE_UNKNOWN,
1117 EventFilteringInfo()); 1071 EventFilteringInfo());
1118 } 1072 }
1119 } 1073 }
1120 1074
1121 void ExtensionWebRequestEventRouter::OnEventHandled( 1075 void ExtensionWebRequestEventRouter::OnEventHandled(
1122 void* browser_context, 1076 void* browser_context,
1123 const std::string& extension_id, 1077 const std::string& extension_id,
1124 const std::string& event_name, 1078 const std::string& event_name,
1125 const std::string& sub_event_name, 1079 const std::string& sub_event_name,
1126 uint64_t request_id, 1080 uint64_t request_id,
1127 EventResponse* response) { 1081 EventResponse* response) {
1128 // TODO(robwu): Does this also work with webviews? operator< (used by find) 1082 // TODO(robwu): This ignores WebViews.
1129 // takes the webview ID into account, which is not set on |listener|. 1083 Listeners& listeners = listeners_[browser_context][event_name];
1130 EventListener listener; 1084 EventListener::Identifier id(browser_context, extension_id, sub_event_name, 0,
1131 listener.extension_id = extension_id; 1085 0);
1132 listener.sub_event_name = sub_event_name; 1086 for (auto it = listeners.begin(); it != listeners.end(); ++it) {
1133 1087 if ((*it)->id.LooselyMatches(id)) {
1134 // The listener may have been removed (e.g. due to the process going away) 1088 (*it)->blocked_requests.erase(request_id);
1135 // before we got here. 1089 }
1136 std::set<EventListener>::iterator found = 1090 }
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 1091
1141 DecrementBlockCount( 1092 DecrementBlockCount(
1142 browser_context, extension_id, event_name, request_id, response); 1093 browser_context, extension_id, event_name, request_id, response);
1143 } 1094 }
1144 1095
1145 bool ExtensionWebRequestEventRouter::AddEventListener( 1096 bool ExtensionWebRequestEventRouter::AddEventListener(
1146 void* browser_context, 1097 void* browser_context,
1147 const std::string& extension_id, 1098 const std::string& extension_id,
1148 const std::string& extension_name, 1099 const std::string& extension_name,
1149 events::HistogramValue histogram_value, 1100 events::HistogramValue histogram_value,
1150 const std::string& event_name, 1101 const std::string& event_name,
1151 const std::string& sub_event_name, 1102 const std::string& sub_event_name,
1152 const RequestFilter& filter, 1103 const RequestFilter& filter,
1153 int extra_info_spec, 1104 int extra_info_spec,
1154 int embedder_process_id, 1105 int embedder_process_id,
1155 int web_view_instance_id, 1106 int web_view_instance_id,
1156 base::WeakPtr<IPC::Sender> ipc_sender) { 1107 base::WeakPtr<IPC::Sender> ipc_sender) {
1157 if (!IsWebRequestEvent(event_name)) 1108 if (!IsWebRequestEvent(event_name))
1158 return false; 1109 return false;
1159 1110
1160 EventListener listener; 1111 if (event_name != EventRouter::GetBaseEventName(sub_event_name))
1161 listener.extension_id = extension_id; 1112 return false;
1162 listener.extension_name = extension_name; 1113
1163 listener.histogram_value = histogram_value; 1114 EventListener::Identifier id(browser_context, extension_id, sub_event_name,
1164 listener.sub_event_name = sub_event_name; 1115 embedder_process_id, web_view_instance_id);
1165 listener.filter = filter; 1116 std::unique_ptr<EventListener> listener(new EventListener(id));
1166 listener.extra_info_spec = extra_info_spec; 1117 listener->extension_name = extension_name;
1167 listener.ipc_sender = ipc_sender; 1118 listener->histogram_value = histogram_value;
1168 listener.embedder_process_id = embedder_process_id; 1119 listener->filter = filter;
1169 listener.web_view_instance_id = web_view_instance_id; 1120 listener->extra_info_spec = extra_info_spec;
1170 if (listener.web_view_instance_id) { 1121 listener->ipc_sender = ipc_sender;
1122 if (listener->id.web_view_instance_id) {
1171 content::RecordAction( 1123 content::RecordAction(
1172 base::UserMetricsAction("WebView.WebRequest.AddListener")); 1124 base::UserMetricsAction("WebView.WebRequest.AddListener"));
1173 } 1125 }
1174 1126
1175 if (base::ContainsKey(listeners_[browser_context][event_name], listener)) { 1127 if (FindEventListener(id) != nullptr) {
1176 // This is likely an abuse of the API by a malicious extension. 1128 // This is likely an abuse of the API by a malicious extension.
1177 return false; 1129 return false;
1178 } 1130 }
1179 listeners_[browser_context][event_name].insert(listener); 1131 listeners_[browser_context][event_name].push_back(std::move(listener));
1180 return true; 1132 return true;
1181 } 1133 }
1182 1134
1135 size_t ExtensionWebRequestEventRouter::GetListenerCountForTesting(
1136 void* browser_context,
1137 const std::string& event_name) {
1138 return listeners_[browser_context][event_name].size();
1139 }
1140
1141 ExtensionWebRequestEventRouter::EventListener*
1142 ExtensionWebRequestEventRouter::FindEventListener(
1143 const EventListener::Identifier& id) {
1144 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1145 std::string event_name = EventRouter::GetBaseEventName(id.sub_event_name);
1146 Listeners& listeners = listeners_[id.browser_context][event_name];
1147 for (auto it = listeners.begin(); it != listeners.end(); ++it) {
1148 if ((*it)->id == id) {
1149 return it->get();
1150 }
1151 }
1152 return nullptr;
1153 }
1154
1183 void ExtensionWebRequestEventRouter::RemoveEventListener( 1155 void ExtensionWebRequestEventRouter::RemoveEventListener(
1184 void* browser_context, 1156 const EventListener::Identifier& id) {
1185 const std::string& extension_id, 1157 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 1158
1192 EventListener listener; 1159 std::string event_name = EventRouter::GetBaseEventName(id.sub_event_name);
1193 listener.extension_id = extension_id; 1160 Listeners& listeners = listeners_[id.browser_context][event_name];
1194 listener.sub_event_name = sub_event_name; 1161 for (auto it = listeners.begin(); it != listeners.end(); ++it) {
1195 listener.embedder_process_id = embedder_process_id; 1162 std::unique_ptr<EventListener>& listener = *it;
1196 listener.web_view_instance_id = web_view_instance_id; 1163 if (listener->id.LooselyMatches(id)) {
1164 // Unblock any request that this event listener may have been blocking.
1165 for (uint64_t blocked_request_id : listener->blocked_requests)
1166 DecrementBlockCount(listener->id.browser_context,
1167 listener->id.extension_id, event_name,
1168 blocked_request_id, NULL);
1197 1169
1198 std::set<EventListener>& event_listeners = 1170 listeners.erase(it);
1199 listeners_[browser_context][event_name]; 1171 helpers::ClearCacheOnNavigation();
1200 // It's possible for AddEventListener to fail asynchronously. In that case, 1172 return;
1201 // the renderer believes the listener exists, while the browser does not. 1173 }
1202 // Ignore a RemoveEventListener in that case. 1174 }
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
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 } 1175 }
1228 1176
1229 void ExtensionWebRequestEventRouter::RemoveWebViewEventListeners( 1177 void ExtensionWebRequestEventRouter::RemoveWebViewEventListeners(
1230 void* browser_context, 1178 void* browser_context,
1231 int embedder_process_id, 1179 int embedder_process_id,
1232 int web_view_instance_id) { 1180 int web_view_instance_id) {
1233 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1181 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1234 1182
1235 // Iterate over all listeners of all WebRequest events to delete 1183 // Iterate over all listeners of all WebRequest events to delete
1236 // any listeners that belong to the provided <webview>. 1184 // any listeners that belong to the provided <webview>.
1237 ListenerMapForBrowserContext& map_for_browser_context = 1185 ListenerMapForBrowserContext& map_for_browser_context =
1238 listeners_[browser_context]; 1186 listeners_[browser_context];
1239 for (const auto& event_iter : map_for_browser_context) { 1187 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 1188 // Construct a listeners_to_delete vector so that we don't modify the set of
1241 // listeners as we iterate through it. 1189 // listeners as we iterate through it.
1242 std::vector<EventListener> listeners_to_delete; 1190 std::vector<EventListener::Identifier> listeners_to_delete;
1243 const std::set<EventListener>& listeners = event_iter.second; 1191 const Listeners& listeners = event_iter.second;
1244 for (const auto& listener : listeners) { 1192 for (const auto& listener : listeners) {
1245 if (listener.embedder_process_id == embedder_process_id && 1193 if (listener->id.embedder_process_id == embedder_process_id &&
1246 listener.web_view_instance_id == web_view_instance_id) { 1194 listener->id.web_view_instance_id == web_view_instance_id) {
1247 listeners_to_delete.push_back(listener); 1195 listeners_to_delete.push_back(listener->id);
1248 } 1196 }
1249 } 1197 }
1250 // Remove the listeners selected for deletion. 1198 // Remove the listeners selected for deletion.
1251 for (const auto& listener : listeners_to_delete) { 1199 for (const auto& listener_id : listeners_to_delete)
1252 RemoveEventListenerOnIOThread( 1200 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 } 1201 }
1260 } 1202 }
1261 1203
1262 void ExtensionWebRequestEventRouter::OnOTRBrowserContextCreated( 1204 void ExtensionWebRequestEventRouter::OnOTRBrowserContextCreated(
1263 void* original_browser_context, void* otr_browser_context) { 1205 void* original_browser_context, void* otr_browser_context) {
1264 cross_browser_context_map_[original_browser_context] = 1206 cross_browser_context_map_[original_browser_context] =
1265 std::make_pair(false, otr_browser_context); 1207 std::make_pair(false, otr_browser_context);
1266 cross_browser_context_map_[otr_browser_context] = 1208 cross_browser_context_map_[otr_browser_context] =
1267 std::make_pair(true, original_browser_context); 1209 std::make_pair(true, original_browser_context);
1268 } 1210 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1324 const InfoMap* extension_info_map, 1266 const InfoMap* extension_info_map,
1325 bool crosses_incognito, 1267 bool crosses_incognito,
1326 const std::string& event_name, 1268 const std::string& event_name,
1327 const GURL& url, 1269 const GURL& url,
1328 int render_process_host_id, 1270 int render_process_host_id,
1329 int routing_id, 1271 int routing_id,
1330 content::ResourceType resource_type, 1272 content::ResourceType resource_type,
1331 bool is_async_request, 1273 bool is_async_request,
1332 bool is_request_from_extension, 1274 bool is_request_from_extension,
1333 int* extra_info_spec, 1275 int* extra_info_spec,
1334 EventListeners* matching_listeners) { 1276 ListenerIdentifiers* matching_listeners) {
1335 std::string web_request_event_name(event_name); 1277 std::string web_request_event_name(event_name);
1336 WebViewRendererState::WebViewInfo web_view_info; 1278 WebViewRendererState::WebViewInfo web_view_info;
1337 bool is_web_view_guest = WebViewRendererState::GetInstance()->GetInfo( 1279 bool is_web_view_guest = WebViewRendererState::GetInstance()->GetInfo(
1338 render_process_host_id, routing_id, &web_view_info); 1280 render_process_host_id, routing_id, &web_view_info);
1339 if (is_web_view_guest) { 1281 if (is_web_view_guest) {
1340 web_request_event_name.replace( 1282 web_request_event_name.replace(
1341 0, sizeof(kWebRequestEventPrefix) - 1, webview::kWebViewEventPrefix); 1283 0, sizeof(kWebRequestEventPrefix) - 1, webview::kWebViewEventPrefix);
1342 } 1284 }
1343 1285
1344 std::set<EventListener>& listeners = 1286 Listeners& listeners = listeners_[browser_context][web_request_event_name];
1345 listeners_[browser_context][web_request_event_name]; 1287 for (const std::unique_ptr<EventListener>& listener : listeners) {
1346 for (const EventListener& listener : listeners) { 1288 if (!listener->ipc_sender.get()) {
1347 if (!listener.ipc_sender.get()) {
1348 // The IPC sender has been deleted. This listener will be removed soon 1289 // The IPC sender has been deleted. This listener will be removed soon
1349 // via a call to RemoveEventListener. For now, just skip it. 1290 // via a call to RemoveEventListener. For now, just skip it.
1350 continue; 1291 continue;
1351 } 1292 }
1352 1293
1353 if (is_web_view_guest && 1294 if (is_web_view_guest &&
1354 (listener.embedder_process_id != web_view_info.embedder_process_id || 1295 (listener->id.embedder_process_id !=
1355 listener.web_view_instance_id != web_view_info.instance_id)) { 1296 web_view_info.embedder_process_id ||
1297 listener->id.web_view_instance_id != web_view_info.instance_id)) {
1356 continue; 1298 continue;
1357 } 1299 }
1358 1300
1359 // Filter requests from other extensions / apps. This does not work for 1301 // Filter requests from other extensions / apps. This does not work for
1360 // content scripts, or extension pages in non-extension processes. 1302 // content scripts, or extension pages in non-extension processes.
1361 if (is_request_from_extension && 1303 if (is_request_from_extension &&
1362 listener.embedder_process_id != render_process_host_id) { 1304 listener->id.embedder_process_id != render_process_host_id) {
1363 continue; 1305 continue;
1364 } 1306 }
1365 1307
1366 if (!listener.filter.urls.is_empty() && 1308 if (!listener->filter.urls.is_empty() &&
1367 !listener.filter.urls.MatchesURL(url)) { 1309 !listener->filter.urls.MatchesURL(url)) {
1368 continue; 1310 continue;
1369 } 1311 }
1370 1312
1371 int render_process_id = -1; 1313 int render_process_id = -1;
1372 int render_frame_id = -1; 1314 int render_frame_id = -1;
1373 // TODO(devlin): Figure out when one/both of these can fail, and if we 1315 // TODO(devlin): Figure out when one/both of these can fail, and if we
1374 // need to address it. 1316 // need to address it.
1375 bool found_render_frame = 1317 bool found_render_frame =
1376 content::ResourceRequestInfo::GetRenderFrameForRequest( 1318 content::ResourceRequestInfo::GetRenderFrameForRequest(
1377 request, &render_process_id, &render_frame_id); 1319 request, &render_process_id, &render_frame_id);
1378 UMA_HISTOGRAM_BOOLEAN("Extensions.WebRequestEventFoundFrame", 1320 UMA_HISTOGRAM_BOOLEAN("Extensions.WebRequestEventFoundFrame",
1379 found_render_frame); 1321 found_render_frame);
1380 ExtensionApiFrameIdMap::FrameData frame_data; 1322 ExtensionApiFrameIdMap::FrameData frame_data;
1381 if (found_render_frame) { 1323 if (found_render_frame) {
1382 ExtensionApiFrameIdMap::Get()->GetCachedFrameDataOnIO( 1324 ExtensionApiFrameIdMap::Get()->GetCachedFrameDataOnIO(
1383 render_process_id, render_frame_id, &frame_data); 1325 render_process_id, render_frame_id, &frame_data);
1384 } 1326 }
1385 // Check if the tab id and window id match, if they were set in the 1327 // Check if the tab id and window id match, if they were set in the
1386 // listener params. 1328 // listener params.
1387 if ((listener.filter.tab_id != -1 && 1329 if ((listener->filter.tab_id != -1 &&
1388 frame_data.tab_id != listener.filter.tab_id) || 1330 frame_data.tab_id != listener->filter.tab_id) ||
1389 (listener.filter.window_id != -1 && 1331 (listener->filter.window_id != -1 &&
1390 frame_data.window_id != listener.filter.window_id)) { 1332 frame_data.window_id != listener->filter.window_id)) {
1391 continue; 1333 continue;
1392 } 1334 }
1393 1335
1394 const std::vector<content::ResourceType>& types = listener.filter.types; 1336 const std::vector<content::ResourceType>& types = listener->filter.types;
1395 if (!types.empty() && 1337 if (!types.empty() &&
1396 std::find(types.begin(), types.end(), resource_type) == types.end()) { 1338 std::find(types.begin(), types.end(), resource_type) == types.end()) {
1397 continue; 1339 continue;
1398 } 1340 }
1399 1341
1400 if (!is_web_view_guest) { 1342 if (!is_web_view_guest) {
1401 PermissionsData::AccessType access = 1343 PermissionsData::AccessType access =
1402 WebRequestPermissions::CanExtensionAccessURL( 1344 WebRequestPermissions::CanExtensionAccessURL(
1403 extension_info_map, listener.extension_id, url, frame_data.tab_id, 1345 extension_info_map, listener->id.extension_id, url,
1404 crosses_incognito, 1346 frame_data.tab_id, crosses_incognito,
1405 WebRequestPermissions::REQUIRE_HOST_PERMISSION); 1347 WebRequestPermissions::REQUIRE_HOST_PERMISSION);
1406 if (access != PermissionsData::ACCESS_ALLOWED) { 1348 if (access != PermissionsData::ACCESS_ALLOWED) {
1407 if (access == PermissionsData::ACCESS_WITHHELD && 1349 if (access == PermissionsData::ACCESS_WITHHELD &&
1408 web_request_event_router_delegate_) { 1350 web_request_event_router_delegate_) {
1409 web_request_event_router_delegate_->NotifyWebRequestWithheld( 1351 web_request_event_router_delegate_->NotifyWebRequestWithheld(
1410 render_process_id, render_frame_id, listener.extension_id); 1352 render_process_id, render_frame_id, listener->id.extension_id);
1411 } 1353 }
1412 continue; 1354 continue;
1413 } 1355 }
1414 } 1356 }
1415 1357
1416 bool blocking_listener = 1358 bool blocking_listener =
1417 (listener.extra_info_spec & 1359 (listener->extra_info_spec &
1418 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) != 0; 1360 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) != 0;
1419 1361
1420 // We do not want to notify extensions about XHR requests that are 1362 // We do not want to notify extensions about XHR requests that are
1421 // triggered by themselves. This is a workaround to prevent deadlocks 1363 // triggered by themselves. This is a workaround to prevent deadlocks
1422 // in case of synchronous XHR requests that block the extension renderer 1364 // in case of synchronous XHR requests that block the extension renderer
1423 // and therefore prevent the extension from processing the request 1365 // and therefore prevent the extension from processing the request
1424 // handler. This is only a problem for blocking listeners. 1366 // handler. This is only a problem for blocking listeners.
1425 // http://crbug.com/105656 1367 // http://crbug.com/105656
1426 bool synchronous_xhr_from_extension = 1368 bool synchronous_xhr_from_extension =
1427 !is_async_request && is_request_from_extension && 1369 !is_async_request && is_request_from_extension &&
1428 resource_type == content::RESOURCE_TYPE_XHR; 1370 resource_type == content::RESOURCE_TYPE_XHR;
1429 1371
1430 // Only send webRequest events for URLs the extension has access to. 1372 // Only send webRequest events for URLs the extension has access to.
1431 if (blocking_listener && synchronous_xhr_from_extension) 1373 if (blocking_listener && synchronous_xhr_from_extension)
1432 continue; 1374 continue;
1433 1375
1434 matching_listeners->push_back(&listener); 1376 matching_listeners->push_back(listener->id);
1435 *extra_info_spec |= listener.extra_info_spec; 1377 *extra_info_spec |= listener->extra_info_spec;
1436 } 1378 }
1437 } 1379 }
1438 1380
1439 ExtensionWebRequestEventRouter::EventListeners 1381 ExtensionWebRequestEventRouter::ListenerIdentifiers
1440 ExtensionWebRequestEventRouter::GetMatchingListeners( 1382 ExtensionWebRequestEventRouter::GetMatchingListeners(
1441 void* browser_context, 1383 void* browser_context,
1442 const InfoMap* extension_info_map, 1384 const InfoMap* extension_info_map,
1443 const std::string& event_name, 1385 const std::string& event_name,
1444 const net::URLRequest* request, 1386 const net::URLRequest* request,
1445 int* extra_info_spec) { 1387 int* extra_info_spec) {
1446 // TODO(mpcomplete): handle browser_context == NULL (should collect all 1388 // TODO(mpcomplete): handle browser_context == NULL (should collect all
1447 // listeners). 1389 // listeners).
1448 *extra_info_spec = 0; 1390 *extra_info_spec = 0;
1449 1391
1450 const GURL& url = request->url(); 1392 const GURL& url = request->url();
1451 int render_process_host_id = content::ChildProcessHost::kInvalidUniqueID; 1393 int render_process_host_id = content::ChildProcessHost::kInvalidUniqueID;
1452 int routing_id = MSG_ROUTING_NONE; 1394 int routing_id = MSG_ROUTING_NONE;
1453 content::ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE; 1395 content::ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE;
1454 // We are conservative here and assume requests are asynchronous in case 1396 // 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. 1397 // we don't have an info object. We don't want to risk a deadlock.
1456 bool is_async_request = false; 1398 bool is_async_request = false;
1457 bool is_request_from_extension = 1399 bool is_request_from_extension =
1458 IsRequestFromExtension(request, extension_info_map); 1400 IsRequestFromExtension(request, extension_info_map);
1459 1401
1460 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); 1402 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
1461 if (info) { 1403 if (info) {
1462 is_async_request = info->IsAsync(); 1404 is_async_request = info->IsAsync();
1463 if (helpers::IsRelevantResourceType(info->GetResourceType())) 1405 if (helpers::IsRelevantResourceType(info->GetResourceType()))
1464 resource_type = info->GetResourceType(); 1406 resource_type = info->GetResourceType();
1465 render_process_host_id = info->GetChildID(); 1407 render_process_host_id = info->GetChildID();
1466 routing_id = info->GetRouteID(); 1408 routing_id = info->GetRouteID();
1467 } 1409 }
1468 1410
1469 EventListeners matching_listeners; 1411 ListenerIdentifiers matching_listeners;
1470 GetMatchingListenersImpl( 1412 GetMatchingListenersImpl(
1471 browser_context, request, extension_info_map, false, event_name, 1413 browser_context, request, extension_info_map, false, event_name,
1472 url, render_process_host_id, routing_id, resource_type, 1414 url, render_process_host_id, routing_id, resource_type,
1473 is_async_request, is_request_from_extension, extra_info_spec, 1415 is_async_request, is_request_from_extension, extra_info_spec,
1474 &matching_listeners); 1416 &matching_listeners);
1475 void* cross_browser_context = GetCrossBrowserContext(browser_context); 1417 void* cross_browser_context = GetCrossBrowserContext(browser_context);
1476 if (cross_browser_context) { 1418 if (cross_browser_context) {
1477 GetMatchingListenersImpl( 1419 GetMatchingListenersImpl(
1478 cross_browser_context, request, extension_info_map, true, event_name, 1420 cross_browser_context, request, extension_info_map, true, event_name,
1479 url, render_process_host_id, routing_id, resource_type, 1421 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. 1620 // declarative rules to be read from disk.
1679 UMA_HISTOGRAM_TIMES("Extensions.NetworkDelayStartup", block_time); 1621 UMA_HISTOGRAM_TIMES("Extensions.NetworkDelayStartup", block_time);
1680 } 1622 }
1681 1623
1682 if (num_handlers_blocking == 0) { 1624 if (num_handlers_blocking == 0) {
1683 blocked_request.request->LogUnblocked(); 1625 blocked_request.request->LogUnblocked();
1684 ExecuteDeltas(browser_context, request_id, true); 1626 ExecuteDeltas(browser_context, request_id, true);
1685 } else { 1627 } else {
1686 // Update the URLRequest to make sure it's tagged with an extension that's 1628 // 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. 1629 // still blocking it. This may end up being the same extension as before.
1688 std::set<EventListener>& listeners = 1630 Listeners& listeners = listeners_[browser_context][event_name];
1689 listeners_[browser_context][event_name];
1690 1631
1691 for (const auto& listener : listeners) { 1632 for (const auto& listener : listeners) {
1692 if (!base::ContainsKey(listener.blocked_requests, request_id)) 1633 if (!base::ContainsKey(listener->blocked_requests, request_id))
1693 continue; 1634 continue;
1694 std::string delegate_info = 1635 std::string delegate_info = l10n_util::GetStringFUTF8(
1695 l10n_util::GetStringFUTF8(IDS_LOAD_STATE_PARAMETER_EXTENSION, 1636 IDS_LOAD_STATE_PARAMETER_EXTENSION,
1696 base::UTF8ToUTF16(listener.extension_name)); 1637 base::UTF8ToUTF16(listener->extension_name));
1697 blocked_request.request->LogAndReportBlockedBy(delegate_info.c_str()); 1638 blocked_request.request->LogAndReportBlockedBy(delegate_info.c_str());
1698 break; 1639 break;
1699 } 1640 }
1700 } 1641 }
1701 } 1642 }
1702 1643
1703 void ExtensionWebRequestEventRouter::SendMessages( 1644 void ExtensionWebRequestEventRouter::SendMessages(
1704 void* browser_context, 1645 void* browser_context,
1705 const BlockedRequest& blocked_request) { 1646 const BlockedRequest& blocked_request) {
1706 const helpers::EventResponseDeltas& deltas = blocked_request.response_deltas; 1647 const helpers::EventResponseDeltas& deltas = blocked_request.response_deltas;
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after
2285 RunWithValidation()->Execute(); 2226 RunWithValidation()->Execute();
2286 } 2227 }
2287 2228
2288 ExtensionFunction::ResponseAction 2229 ExtensionFunction::ResponseAction
2289 WebRequestHandlerBehaviorChangedFunction::Run() { 2230 WebRequestHandlerBehaviorChangedFunction::Run() {
2290 helpers::ClearCacheOnNavigation(); 2231 helpers::ClearCacheOnNavigation();
2291 return RespondNow(NoArguments()); 2232 return RespondNow(NoArguments());
2292 } 2233 }
2293 2234
2294 } // namespace extensions 2235 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698