#include "extensions/browser/api/web_request/extension_web_request_event_router.h"
#include <algorithm>
#include <string_view>
#include <vector>
#include "base/containers/fixed_flat_map.h"
#include "base/feature_list.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/no_destructor.h"
#include "base/trace_event/trace_event.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "extensions/browser/api/declarative/rules_registry_service.h"
#include "extensions/browser/api/declarative_net_request/action_tracker.h"
#include "extensions/browser/api/declarative_net_request/constants.h"
#include "extensions/browser/api/declarative_net_request/request_action.h"
#include "extensions/browser/api/declarative_net_request/rules_monitor_service.h"
#include "extensions/browser/api/declarative_webrequest/request_stage.h"
#include "extensions/browser/api/declarative_webrequest/webrequest_constants.h"
#include "extensions/browser/api/declarative_webrequest/webrequest_rules_registry.h"
#include "extensions/browser/api/extensions_api_client.h"
#include "extensions/browser/api/web_accessible_resources/web_accessible_resources_router.h"
#include "extensions/browser/api/web_request/permission_helper.h"
#include "extensions/browser/api/web_request/web_request_api_constants.h"
#include "extensions/browser/api/web_request/web_request_api_helpers.h"
#include "extensions/browser/api/web_request/web_request_event_details.h"
#include "extensions/browser/api/web_request/web_request_event_router_factory.h"
#include "extensions/browser/api/web_request/web_request_info.h"
#include "extensions/browser/api/web_request/web_request_permissions.h"
#include "extensions/browser/api/web_request/web_request_time_tracker.h"
#include "extensions/browser/api_activity_monitor.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/process_map.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/api/web_request/web_request_activity_log_constants.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/mojom/event_dispatcher.mojom.h"
#if BUILDFLAG(ENABLE_GUEST_VIEW)
#include "extensions/browser/guest_view/guest_view_events.h"
#endif
BrowserThread;
ExtraInfoSpec;
DNRRequestAction;
namespace extensions {
namespace {
activity_log;
declarative_keys;
helpers;
keys;
web_request;
enum RequestAction { … };
constexpr char kEventMessage[] = …;
constexpr char kWebRequestEventPrefix[] = …;
constexpr char kWebViewEventPrefix[] = …;
constexpr size_t kWebRequestEventPrefixLen = …;
constexpr size_t kWebViewEventPrefixLen = …;
constexpr const char* kWebRequestEvents[] = …;
events::HistogramValue GetEventHistogramValue(const std::string& event_name) { … }
const char* GetRequestStageAsString(WebRequestEventRouter::EventTypes type) { … }
void LogRequestAction(RequestAction action) { … }
WebRequestEventRouter::EventTypes GetEventTypeFromEventName(
std::string_view event_name) { … }
bool IsWebRequestEvent(std::string_view event_name) { … }
bool IsRequestFromExtension(const WebRequestInfo& request,
content::BrowserContext* context) { … }
void SendOnMessageEventOnUI(
content::BrowserContext* browser_context,
const ExtensionId& extension_id,
bool is_web_view_guest,
int web_view_instance_id,
std::unique_ptr<WebRequestEventDetails> event_details) { … }
void NotifyIgnoredActionsOnUI(
content::BrowserContext* browser_context,
uint64_t request_id,
extension_web_request_api_helpers::IgnoredActions ignored_actions) { … }
bool ShouldHideEvent(content::BrowserContext* browser_context,
const WebRequestInfo& request) { … }
std::unique_ptr<WebRequestEventDetails> CreateEventDetails(
const WebRequestInfo& request,
int extra_info_spec) { … }
enum class WebRequestEventListenerFlag { … };
void LogEventListenerFlag(WebRequestEventListenerFlag flag) { … }
void RecordAddEventListenerUMAs(int extra_info_spec) { … }
void OnDNRActionMatched(content::BrowserContext* browser_context,
const WebRequestInfo& request,
const DNRRequestAction& action) { … }
GURL GetNewUrl(const GURL& redirect_url,
content::BrowserContext* browser_context) { … }
CallbacksForPageLoad;
CallbacksForPageLoad& GetCallbacksForPageLoad() { … }
ExtensionWebRequestTimeTracker& GetExtensionWebRequestTimeTracker() { … }
class CrossContextData { … };
void ClearCrossContextData(content::BrowserContext* browser_context) { … }
}
WebRequestEventRouter::WebRequestEventRouter(content::BrowserContext* context)
: … { … }
WebRequestEventRouter::~WebRequestEventRouter() = default;
void WebRequestEventRouter::Shutdown() { … }
WebRequestEventRouter* WebRequestEventRouter::Get(
content::BrowserContext* browser_context) { … }
std::vector<std::string> WebRequestEventRouter::GetEventNames() { … }
WebRequestEventRouter::EventListener::EventListener(ID id)
: … { … }
WebRequestEventRouter::EventListener::~EventListener() = default;
struct WebRequestEventRouter::BlockedRequest { … };
namespace {
helpers::EventResponseDelta CalculateDelta(
content::BrowserContext* browser_context,
WebRequestEventRouter::BlockedRequest* blocked_request,
WebRequestEventRouter::EventResponse* response,
int extra_info_spec) { … }
base::Value::List SerializeResponseHeaders(
const helpers::ResponseHeaders& headers) { … }
template <typename CookieType>
base::Value::List SummarizeCookieModifications(
const std::vector<CookieType>& modifications) { … }
base::Value::Dict SummarizeResponseDelta(
const std::string& event_name,
const helpers::EventResponseDelta& delta) { … }
}
bool WebRequestEventRouter::RequestFilter::InitFromValue(
const base::Value::Dict& value,
std::string* error) { … }
WebRequestEventRouter::EventResponse::EventResponse(
const ExtensionId& extension_id,
const base::Time& extension_install_time)
: … { … }
WebRequestEventRouter::EventResponse::~EventResponse() = default;
WebRequestEventRouter::RequestFilter::RequestFilter()
: … { … }
WebRequestEventRouter::RequestFilter::~RequestFilter() = default;
WebRequestEventRouter::RequestFilter::RequestFilter(RequestFilter&& other) =
default;
WebRequestEventRouter::RequestFilter&
WebRequestEventRouter::RequestFilter::operator=(RequestFilter&& other) =
default;
WebRequestEventRouter::SignaledRequestIDTracker::SignaledRequestIDTracker() =
default;
WebRequestEventRouter::SignaledRequestIDTracker::~SignaledRequestIDTracker() =
default;
WebRequestEventRouter::SignaledRequestIDTracker::SignaledRequestIDTracker(
SignaledRequestIDTracker&&) = default;
bool WebRequestEventRouter::SignaledRequestIDTracker::GetAndSet(
uint64_t request_id,
EventTypes event_type) { … }
void WebRequestEventRouter::SignaledRequestIDTracker::ClearEventType(
uint64_t request_id,
EventTypes event_type) { … }
WebRequestEventRouter::BrowserContextData::BrowserContextData() = default;
WebRequestEventRouter::BrowserContextData::BrowserContextData(
BrowserContextData&&) = default;
WebRequestEventRouter::BrowserContextData::~BrowserContextData() = default;
WebRequestEventRouter::EventListener::ID::ID(
content::BrowserContext* browser_context,
const ExtensionId& extension_id,
const std::string& sub_event_name,
int render_process_id,
int web_view_instance_id,
int worker_thread_id,
int64_t service_worker_version_id)
: … { … }
WebRequestEventRouter::EventListener::ID::ID(const ID& source) = default;
WebRequestEventRouter::EventListener::ID::ID(ID&& source) = default;
bool WebRequestEventRouter::EventListener::ID::operator==(
const ID& that) const { … }
void WebRequestEventRouter::RegisterRulesRegistry(
content::BrowserContext* browser_context,
int rules_registry_id,
scoped_refptr<WebRequestRulesRegistry> rules_registry) { … }
int WebRequestEventRouter::OnBeforeRequest(
content::BrowserContext* browser_context,
WebRequestInfo* request,
net::CompletionOnceCallback callback,
GURL* new_url,
bool* should_collapse_initiator) { … }
int WebRequestEventRouter::OnBeforeSendHeaders(
content::BrowserContext* browser_context,
const WebRequestInfo* request,
BeforeSendHeadersCallback callback,
net::HttpRequestHeaders* headers) { … }
void WebRequestEventRouter::OnSendHeaders(
content::BrowserContext* browser_context,
const WebRequestInfo* request,
const net::HttpRequestHeaders& headers) { … }
int WebRequestEventRouter::OnHeadersReceived(
content::BrowserContext* browser_context,
WebRequestInfo* request,
net::CompletionOnceCallback callback,
const net::HttpResponseHeaders* original_response_headers,
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
GURL* preserve_fragment_on_redirect_url,
bool* should_collapse_initiator) { … }
WebRequestEventRouter::AuthRequiredResponse
WebRequestEventRouter::OnAuthRequired(content::BrowserContext* browser_context,
const WebRequestInfo* request,
const net::AuthChallengeInfo& auth_info,
AuthCallback callback,
net::AuthCredentials* credentials) { … }
void WebRequestEventRouter::OnBeforeRedirect(
content::BrowserContext* browser_context,
const WebRequestInfo* request,
const GURL& new_location) { … }
void WebRequestEventRouter::OnResponseStarted(
content::BrowserContext* browser_context,
const WebRequestInfo* request,
int net_error) { … }
void WebRequestEventRouter::OnCompleted(
content::BrowserContext* browser_context,
const WebRequestInfo* request,
int net_error) { … }
void WebRequestEventRouter::OnErrorOccurred(
content::BrowserContext* browser_context,
const WebRequestInfo* request,
bool started,
int net_error) { … }
void WebRequestEventRouter::OnRequestWillBeDestroyed(
content::BrowserContext* browser_context,
const WebRequestInfo* request) { … }
void WebRequestEventRouter::ClearPendingCallbacks(
content::BrowserContext* browser_context,
const WebRequestInfo& request) { … }
bool WebRequestEventRouter::DispatchEvent(
content::BrowserContext* browser_context,
const WebRequestInfo* request,
const RawListeners& listeners,
std::unique_ptr<WebRequestEventDetails> event_details) { … }
void WebRequestEventRouter::DispatchEventToListeners(
content::BrowserContext* browser_context,
std::unique_ptr<ListenerIDs> listener_ids,
uint64_t request_id,
std::unique_ptr<WebRequestEventDetails> event_details) { … }
void WebRequestEventRouter::OnEventHandled(
content::BrowserContext* browser_context,
const ExtensionId& extension_id,
const std::string& event_name,
const std::string& sub_event_name,
uint64_t request_id,
int render_process_id,
int web_view_instance_id,
int worker_thread_id,
int64_t service_worker_version_id,
std::unique_ptr<EventResponse> response) { … }
bool WebRequestEventRouter::AddEventListener(
content::BrowserContext* browser_context,
const ExtensionId& extension_id,
const std::string& extension_name,
const std::string& event_name,
const std::string& sub_event_name,
RequestFilter filter,
int extra_info_spec,
int render_process_id,
int web_view_instance_id,
int worker_thread_id,
int64_t service_worker_version_id) { … }
WebRequestEventRouter::EventListener* WebRequestEventRouter::FindEventListener(
const EventListener::ID& id) { … }
WebRequestEventRouter::EventListener*
WebRequestEventRouter::FindEventListenerInContainer(
const EventListener::ID& id,
const Listeners& listeners) { … }
std::unique_ptr<WebRequestEventRouter::EventListener>
WebRequestEventRouter::RemoveMatchingListener(
Listeners& listeners,
const ExtensionId& extension_id,
const std::string& sub_event_name,
std::optional<int> worker_thread_id,
std::optional<int64_t> service_worker_version_id,
BrowserContextID browser_context_id) { … }
void WebRequestEventRouter::RemoveLazyListener(
content::BrowserContext* original_context,
const ExtensionId& extension_id,
const std::string& sub_event_name) { … }
void WebRequestEventRouter::UpdateActiveListener(
content::BrowserContext* browser_context,
ListenerUpdateType update_type,
const ExtensionId& extension_id,
const std::string& sub_event_name,
int worker_thread_id,
int64_t service_worker_version_id) { … }
void WebRequestEventRouter::CleanUpForListener(const EventListener& listener,
ListenerUpdateType update_type) { … }
void WebRequestEventRouter::RemoveWebViewEventListeners(
content::BrowserContext* browser_context,
int render_process_id,
int web_view_instance_id) { … }
void WebRequestEventRouter::OnOTRBrowserContextCreated(
content::BrowserContext* original_browser_context,
content::BrowserContext* otr_browser_context) { … }
void WebRequestEventRouter::OnOTRBrowserContextDestroyed(
content::BrowserContext* original_browser_context,
content::BrowserContext* otr_browser_context) { … }
void WebRequestEventRouter::AddCallbackForPageLoad(base::OnceClosure callback) { … }
bool WebRequestEventRouter::HasExtraHeadersListenerForRequest(
content::BrowserContext* browser_context,
const WebRequestInfo* request) { … }
bool WebRequestEventRouter::HasAnyExtraHeadersListener(
content::BrowserContext* browser_context) { … }
void WebRequestEventRouter::IncrementExtraHeadersListenerCount(
content::BrowserContext* browser_context) { … }
void WebRequestEventRouter::DecrementExtraHeadersListenerCount(
content::BrowserContext* browser_context) { … }
void WebRequestEventRouter::OnBrowserContextShutdown(
content::BrowserContext* browser_context) { … }
size_t WebRequestEventRouter::GetListenerCountForTesting(
content::BrowserContext* browser_context,
const std::string& event_name) { … }
size_t WebRequestEventRouter::GetInactiveListenerCountForTesting(
content::BrowserContext* browser_context,
const std::string& event_name) { … }
bool WebRequestEventRouter::HasAnyExtraHeadersListenerImpl(
content::BrowserContext* browser_context) { … }
WebRequestEventRouter::BlockedRequestMap&
WebRequestEventRouter::GetBlockedRequestMap(
content::BrowserContext* browser_context) { … }
void WebRequestEventRouter::ClearBlockedRequest(
content::BrowserContext* browser_context,
uint64_t id) { … }
WebRequestEventRouter::BlockedRequest&
WebRequestEventRouter::GetOrAddBlockedRequest(
content::BrowserContext* browser_context,
uint64_t id) { … }
WebRequestEventRouter::BlockedRequest* WebRequestEventRouter::GetBlockedRequest(
content::BrowserContext* browser_context,
uint64_t id) { … }
bool WebRequestEventRouter::IsPageLoad(const WebRequestInfo& request) const { … }
void WebRequestEventRouter::NotifyPageLoad() { … }
content::BrowserContext* WebRequestEventRouter::GetCrossBrowserContext(
content::BrowserContext* browser_context) { … }
bool WebRequestEventRouter::WasSignaled(
content::BrowserContext* browser_context,
uint64_t request_id) const { … }
WebRequestEventRouter::RawListeners WebRequestEventRouter::GetMatchingListeners(
content::BrowserContext* browser_context,
const std::string& event_name,
const WebRequestInfo* request,
int* extra_info_spec) { … }
bool WebRequestEventRouter::ListenerMatchesRequest(
const EventListener& listener,
const WebRequestInfo& request,
content::BrowserContext& browser_context,
bool is_request_from_extension,
bool crosses_incognito) { … }
void WebRequestEventRouter::GetMatchingListenersForRequest(
const Listeners& listeners,
const WebRequestInfo& request,
content::BrowserContext& browser_context,
bool is_request_from_extension,
bool crosses_incognito,
RawListeners* listeners_out,
int* extra_info_spec_out) { … }
void WebRequestEventRouter::DecrementBlockCount(
content::BrowserContext* browser_context,
const ExtensionId& extension_id,
const std::string& event_name,
uint64_t request_id,
std::unique_ptr<EventResponse> response,
int extra_info_spec) { … }
void WebRequestEventRouter::SendMessages(
content::BrowserContext* browser_context,
const BlockedRequest& blocked_request) { … }
int WebRequestEventRouter::ExecuteDeltas(
content::BrowserContext* browser_context,
const WebRequestInfo* request,
bool call_callback) { … }
bool WebRequestEventRouter::ProcessDeclarativeRules(
content::BrowserContext* browser_context,
const std::string& event_name,
const WebRequestInfo* request,
RequestStage request_stage,
const net::HttpResponseHeaders* original_response_headers) { … }
void WebRequestEventRouter::OnRulesRegistryReady(void* browser_context_id,
const std::string& event_name,
uint64_t request_id,
RequestStage request_stage) { … }
bool WebRequestEventRouter::GetAndSetSignaled(
content::BrowserContext* browser_context,
uint64_t request_id,
EventTypes event_type) { … }
void WebRequestEventRouter::ClearSignaled(
content::BrowserContext* browser_context,
uint64_t request_id,
EventTypes event_type) { … }
}