chromium/extensions/browser/api/web_request/extension_web_request_event_router.cc

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#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;

// Describes the action taken by the Web Request API for a given stage of a web
// request.
// These values are written to logs.  New enum values can be added, but existing
// enum values must never be renumbered or deleted and reused.
enum RequestAction {};

constexpr char kEventMessage[] =;

constexpr char kWebRequestEventPrefix[] =;
constexpr char kWebViewEventPrefix[] =;

constexpr size_t kWebRequestEventPrefixLen =;
constexpr size_t kWebViewEventPrefixLen =;

// List of all the webRequest events. Note: this doesn't include
// "onActionIgnored" which is not related to a request's lifecycle and is
// handled as a normal event (as opposed to a WebRequestEvent at the bindings
// layer).
constexpr const char* kWebRequestEvents[] =;

events::HistogramValue GetEventHistogramValue(const std::string& event_name) {}

const char* GetRequestStageAsString(WebRequestEventRouter::EventTypes type) {}

void LogRequestAction(RequestAction action) {}

// Returns the corresponding EventTypes for the given |event_name|. If
// |event_name| is an invalid event, returns EventTypes::kInvalidEvent.
WebRequestEventRouter::EventTypes GetEventTypeFromEventName(
    std::string_view event_name) {}

bool IsWebRequestEvent(std::string_view event_name) {}

// Returns whether |request| has been triggered by an extension enabled in
// |context|.
bool IsRequestFromExtension(const WebRequestInfo& request,
                            content::BrowserContext* context) {}

// Sends an event to subscribers of chrome.declarativeWebRequest.onMessage or
// to subscribers of webview.onMessage if the action is being operated upon
// a <webview> guest renderer.
// |extension_id| identifies the extension that sends and receives the event.
// |is_web_view_guest| indicates whether the action is for a <webview>.
// |web_view_instance_id| is a valid if |is_web_view_guest| is true.
// |event_details| is passed to the event listener.
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) {}

// Helper to dispatch the "onActionIgnored" event.
void NotifyIgnoredActionsOnUI(
    content::BrowserContext* browser_context,
    uint64_t request_id,
    extension_web_request_api_helpers::IgnoredActions ignored_actions) {}

// We hide events from the system context as well as sensitive requests.
bool ShouldHideEvent(content::BrowserContext* browser_context,
                     const WebRequestInfo& request) {}

// Returns event details for a given request.
std::unique_ptr<WebRequestEventDetails> CreateEventDetails(
    const WebRequestInfo& request,
    int extra_info_spec) {}

// Mirrors the histogram enum of the same name. DO NOT REORDER THESE VALUES OR
// CHANGE THEIR MEANING.
enum class WebRequestEventListenerFlag {};

void LogEventListenerFlag(WebRequestEventListenerFlag flag) {}

void RecordAddEventListenerUMAs(int extra_info_spec) {}

// Helper to record a matched DNR action in RulesetManager's ActionTracker.
void OnDNRActionMatched(content::BrowserContext* browser_context,
                        const WebRequestInfo& request,
                        const DNRRequestAction& action) {}

// The `use_dynamic_url` feature for web accessible resources requires that the
// requested url be a dynamic url. A dynamic url is one where a session GUID is
// used for the host instead of the static extension id.
GURL GetNewUrl(const GURL& redirect_url,
               content::BrowserContext* browser_context) {}

CallbacksForPageLoad;

// TODO(crbug.com/40264286): We need to investigate why this is a global
// structure instead of a per-BrowserContext structure. It seems incorrect
// that a page load in one BrowserContext should interact with a page load
// in another one.
CallbacksForPageLoad& GetCallbacksForPageLoad() {}

ExtensionWebRequestTimeTracker& GetExtensionWebRequestTimeTracker() {}

class CrossContextData {};

void ClearCrossContextData(content::BrowserContext* browser_context) {}

}  // namespace

WebRequestEventRouter::WebRequestEventRouter(content::BrowserContext* context)
    :{}

WebRequestEventRouter::~WebRequestEventRouter() = default;

void WebRequestEventRouter::Shutdown() {}

// static
WebRequestEventRouter* WebRequestEventRouter::Get(
    content::BrowserContext* browser_context) {}

// static
std::vector<std::string> WebRequestEventRouter::GetEventNames() {}

// Represents a single unique listener to an event, along with whatever filter
// parameters and extra_info_spec were specified at the time the listener was
// added.
// NOTE(benjhayden) New APIs should not use this sub_event_name trick! It does
// not play well with event pages. See downloads.onDeterminingFilename and
// ExtensionDownloadsEventRouter for an alternative approach.
WebRequestEventRouter::EventListener::EventListener(ID id)
    :{}
WebRequestEventRouter::EventListener::~EventListener() = default;

// Contains info about requests that are blocked waiting for a response from
// an extension.
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) {}

// Convert a RequestCookieModifications/ResponseCookieModifications object to a
// base::Value::List which summarizes the changes made.  This is templated since
// the two types (request/response) are different but contain essentially the
// same fields.
template <typename CookieType>
base::Value::List SummarizeCookieModifications(
    const std::vector<CookieType>& modifications) {}

// Converts an EventResponseDelta object to a dictionary value suitable for the
// activity log.
base::Value::Dict SummarizeResponseDelta(
    const std::string& event_name,
    const helpers::EventResponseDelta& delta) {}

}  // namespace

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 {}

//
//  WebRequestEventRouter
//

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) {}

// static
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) {}

// static
void WebRequestEventRouter::OnOTRBrowserContextCreated(
    content::BrowserContext* original_browser_context,
    content::BrowserContext* otr_browser_context) {}

// static
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() {}

// static
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) {}

// static
bool WebRequestEventRouter::ListenerMatchesRequest(
    const EventListener& listener,
    const WebRequestInfo& request,
    content::BrowserContext& browser_context,
    bool is_request_from_extension,
    bool crosses_incognito) {}

// static
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) {}

}  // namespace extensions