#include "content/browser/devtools/devtools_instrumentation.h"
#include "base/containers/adapters.h"
#include "base/feature_list.h"
#include "base/notreached.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/traced_value.h"
#include "components/download/public/common/download_create_info.h"
#include "components/download/public/common/download_item.h"
#include "components/download/public/common/download_url_parameters.h"
#include "content/browser/devtools/browser_devtools_agent_host.h"
#include "content/browser/devtools/dedicated_worker_devtools_agent_host.h"
#include "content/browser/devtools/devtools_issue_storage.h"
#include "content/browser/devtools/devtools_preload_storage.h"
#include "content/browser/devtools/protocol/audits.h"
#include "content/browser/devtools/protocol/audits_handler.h"
#include "content/browser/devtools/protocol/browser_handler.h"
#include "content/browser/devtools/protocol/device_access_handler.h"
#include "content/browser/devtools/protocol/emulation_handler.h"
#include "content/browser/devtools/protocol/fedcm_handler.h"
#include "content/browser/devtools/protocol/fetch_handler.h"
#include "content/browser/devtools/protocol/input_handler.h"
#include "content/browser/devtools/protocol/log_handler.h"
#include "content/browser/devtools/protocol/network.h"
#include "content/browser/devtools/protocol/network_handler.h"
#include "content/browser/devtools/protocol/page_handler.h"
#include "content/browser/devtools/protocol/preload_handler.h"
#include "content/browser/devtools/protocol/security_handler.h"
#include "content/browser/devtools/protocol/storage_handler.h"
#include "content/browser/devtools/protocol/target_handler.h"
#include "content/browser/devtools/protocol/tracing_handler.h"
#include "content/browser/devtools/render_frame_devtools_agent_host.h"
#include "content/browser/devtools/service_worker_devtools_agent_host.h"
#include "content/browser/devtools/web_contents_devtools_agent_host.h"
#include "content/browser/devtools/worker_devtools_manager.h"
#include "content/browser/preloading/prerender/prerender_final_status.h"
#include "content/browser/preloading/prerender/prerender_metrics.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/navigation_request.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/web_package/signed_exchange_envelope.h"
#include "content/public/browser/browser_context.h"
#include "devtools_agent_host_impl.h"
#include "devtools_instrumentation.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "net/base/features.h"
#include "net/base/load_flags.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_inclusion_status.h"
#include "net/http/http_request_headers.h"
#include "net/quic/web_transport_error.h"
#include "net/ssl/ssl_info.h"
#include "services/network/public/cpp/devtools_observer_util.h"
#include "services/network/public/cpp/url_loader_factory_builder.h"
#include "services/network/public/mojom/devtools_observer.mojom.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "third_party/blink/public/mojom/devtools/inspector_issue.mojom.h"
#include "third_party/blink/public/mojom/navigation/navigation_params.mojom.h"
namespace content {
namespace devtools_instrumentation {
namespace {
AttributionReportingIssueTypeEnum;
const char kPrivacySandboxExtensionsAPI[] = …;
template <typename Handler, typename... MethodArgs, typename... Args>
void DispatchToAgents(DevToolsAgentHostImpl* host,
void (Handler::*method)(MethodArgs...),
Args&&... args) { … }
template <typename Handler, typename... MethodArgs, typename... Args>
void DispatchToAgents(FrameTreeNode* frame_tree_node,
void (Handler::*method)(MethodArgs...),
Args&&... args) { … }
template <typename Handler, typename... MethodArgs, typename... Args>
void DispatchToAgents(int frame_tree_node_id,
void (Handler::*method)(MethodArgs...),
Args&&... args) { … }
template <typename Handler, typename... MethodArgs, typename... Args>
void DispatchToAgents(WebContents* web_contents,
void (Handler::*method)(MethodArgs...),
Args&&... args) { … }
std::unique_ptr<protocol::Audits::InspectorIssue> BuildHeavyAdIssue(
const blink::mojom::HeavyAdIssueDetailsPtr& issue_details) { … }
protocol::Audits::AttributionReportingIssueType
BuildAttributionReportingIssueViolationType(
blink::mojom::AttributionReportingIssueType type) { … }
std::unique_ptr<protocol::Audits::InspectorIssue>
BuildAttributionReportingIssue(
const blink::mojom::AttributionReportingIssueDetailsPtr& issue_details) { … }
protocol::Audits::FederatedAuthRequestIssueReason
FederatedAuthRequestResultToProtocol(
blink::mojom::FederatedAuthRequestResult result) { … }
std::unique_ptr<protocol::Audits::InspectorIssue>
BuildFederatedAuthRequestIssue(
const blink::mojom::FederatedAuthRequestIssueDetailsPtr& issue_details) { … }
protocol::Audits::FederatedAuthUserInfoRequestIssueReason
FederatedAuthUserInfoRequestResultToProtocol(
blink::mojom::FederatedAuthUserInfoRequestResult result) { … }
std::unique_ptr<protocol::Audits::InspectorIssue>
BuildFederatedAuthUserInfoRequestIssue(
const blink::mojom::FederatedAuthUserInfoRequestIssueDetailsPtr&
issue_details) { … }
const char* DeprecationIssueTypeToProtocol(
blink::mojom::DeprecationIssueType error_type) { … }
std::unique_ptr<protocol::Audits::InspectorIssue> BuildDeprecationIssue(
const blink::mojom::DeprecationIssueDetailsPtr& issue_details) { … }
std::unique_ptr<protocol::Audits::InspectorIssue> BuildBounceTrackingIssue(
const blink::mojom::BounceTrackingIssueDetailsPtr& issue_details) { … }
void UpdateChildFrameTrees(FrameTreeNode* ftn, bool update_target_info) { … }
}
void OnResetNavigationRequest(NavigationRequest* navigation_request) { … }
void OnNavigationResponseReceived(const NavigationRequest& nav_request,
const network::mojom::URLResponseHead& head) { … }
void OnFetchKeepAliveRequestWillBeSent(
FrameTreeNode* frame_tree_node,
const std::string& request_id,
const network::ResourceRequest& request,
std::optional<std::pair<const GURL&,
const network::mojom::URLResponseHeadDevToolsInfo&>>
redirect_info) { … }
void OnFetchKeepAliveResponseReceived(
FrameTreeNode* frame_tree_node,
const std::string& request_id,
const GURL& url,
const network::mojom::URLResponseHead& head) { … }
void OnFetchKeepAliveRequestComplete(
FrameTreeNode* frame_tree_node,
const std::string& request_id,
const network::URLLoaderCompletionStatus& status) { … }
void BackForwardCacheNotUsed(
const NavigationRequest* nav_request,
const BackForwardCacheCanStoreDocumentResult* result,
const BackForwardCacheCanStoreTreeResult* tree_result) { … }
void WillSwapFrameTreeNode(FrameTreeNode& old_node, FrameTreeNode& new_node) { … }
void OnFrameTreeNodeDestroyed(FrameTreeNode& frame_tree_node) { … }
bool IsPrerenderAllowed(FrameTree& frame_tree) { … }
void WillInitiatePrerender(FrameTree& frame_tree) { … }
void DidActivatePrerender(const NavigationRequest& nav_request,
const std::optional<base::UnguessableToken>&
initiator_devtools_navigation_token) { … }
void DidUpdatePolicyContainerHost(FrameTreeNode* ftn) { … }
void DidUpdatePrefetchStatus(
FrameTreeNode* ftn,
const base::UnguessableToken& initiator_devtools_navigation_token,
const GURL& prefetch_url,
PreloadingTriggeringOutcome status,
PrefetchStatus prefetch_status,
const std::string& request_id) { … }
void DidUpdatePrerenderStatus(
int initiator_frame_tree_node_id,
const base::UnguessableToken& initiator_devtools_navigation_token,
const GURL& prerender_url,
std::optional<blink::mojom::SpeculationTargetHint> target_hint,
PreloadingTriggeringOutcome status,
std::optional<PrerenderFinalStatus> prerender_status,
std::optional<std::string> disallowed_mojo_interface,
const std::vector<PrerenderMismatchedHeaders>* mismatched_headers) { … }
namespace {
protocol::String BuildBlockedByResponseReason(
network::mojom::BlockedByResponseReason reason) { … }
void ReportBlockedByResponseIssue(
const GURL& url,
std::string& requestId,
FrameTreeNode* ftn,
RenderFrameHostImpl* parent_frame,
const network::URLLoaderCompletionStatus& status) { … }
}
void OnNavigationRequestFailed(
const NavigationRequest& nav_request,
const network::URLLoaderCompletionStatus& status) { … }
bool ShouldBypassCSP(const NavigationRequest& nav_request) { … }
bool ShouldBypassCertificateErrors(DevToolsAgentHost* agent_host) { … }
bool ShouldBypassCertificateErrors() { … }
void ApplyNetworkOverridesForDownload(
RenderFrameHostImpl* rfh,
download::DownloadUrlParameters* parameters) { … }
void WillBeginDownload(download::DownloadCreateInfo* info,
download::DownloadItem* item) { … }
void OnSignedExchangeReceived(
FrameTreeNode* frame_tree_node,
std::optional<const base::UnguessableToken> devtools_navigation_token,
const GURL& outer_request_url,
const network::mojom::URLResponseHead& outer_response,
const std::optional<SignedExchangeEnvelope>& envelope,
const scoped_refptr<net::X509Certificate>& certificate,
const std::optional<net::SSLInfo>& ssl_info,
const std::vector<SignedExchangeError>& errors) { … }
namespace inspector_will_send_navigation_request_event {
std::unique_ptr<base::trace_event::TracedValue> Data(
const base::UnguessableToken& request_id) { … }
}
void OnSignedExchangeCertificateRequestSent(
FrameTreeNode* frame_tree_node,
const base::UnguessableToken& request_id,
const base::UnguessableToken& loader_id,
const network::ResourceRequest& request,
const GURL& signed_exchange_url) { … }
void OnSignedExchangeCertificateResponseReceived(
FrameTreeNode* frame_tree_node,
const base::UnguessableToken& request_id,
const base::UnguessableToken& loader_id,
const GURL& url,
const network::mojom::URLResponseHead& head) { … }
void OnSignedExchangeCertificateRequestCompleted(
FrameTreeNode* frame_tree_node,
const base::UnguessableToken& request_id,
const network::URLLoaderCompletionStatus& status) { … }
void ThrottleForServiceWorkerAgentHost(
ServiceWorkerDevToolsAgentHost* agent_host,
DevToolsAgentHostImpl* requesting_agent_host,
scoped_refptr<DevToolsThrottleHandle> throttle_handle) { … }
std::vector<std::unique_ptr<NavigationThrottle>> CreateNavigationThrottles(
NavigationHandle* navigation_handle) { … }
void ThrottleServiceWorkerMainScriptFetch(
ServiceWorkerContextWrapper* wrapper,
int64_t version_id,
const GlobalRenderFrameHostId& requesting_frame_id,
scoped_refptr<DevToolsThrottleHandle> throttle_handle) { … }
void ThrottleWorkerMainScriptFetch(
const base::UnguessableToken& devtools_worker_token,
const GlobalRenderFrameHostId& ancestor_render_frame_host_id,
scoped_refptr<DevToolsThrottleHandle> throttle_handle) { … }
bool ShouldWaitForDebuggerInWindowOpen() { … }
namespace {
DevToolsAgentHostImpl* GetDevToolsAgentHostForNetworkOverrides(
FrameTreeNode* frame_tree_node) { … }
void ApplyNetworkRequestOverrides(
DevToolsAgentHostImpl* agent_host,
net::HttpRequestHeaders* headers,
bool* disable_cache,
bool* network_instrumentation_enabled,
bool* skip_service_worker,
std::optional<std::vector<net::SourceStream::SourceType>>*
devtools_accepted_stream_types,
bool* devtools_user_agent_overridden,
bool* devtools_accept_language_overridden) { … }
}
void ApplyAuctionNetworkRequestOverrides(
FrameTreeNode* frame_tree_node,
network::ResourceRequest* request,
bool* network_instrumentation_enabled) { … }
void ApplyNetworkRequestOverrides(
FrameTreeNode* frame_tree_node,
blink::mojom::BeginNavigationParams* begin_params,
bool* report_raw_headers,
std::optional<std::vector<net::SourceStream::SourceType>>*
devtools_accepted_stream_types,
bool* devtools_user_agent_overridden,
bool* devtools_accept_language_overridden) { … }
bool ApplyUserAgentMetadataOverrides(
FrameTreeNode* frame_tree_node,
std::optional<blink::UserAgentMetadata>* override_out) { … }
namespace {
template <typename HandlerType>
bool MaybeCreateProxyForInterception(
DevToolsAgentHostImpl* agent_host,
int process_id,
StoragePartition* storage_partition,
const base::UnguessableToken& frame_token,
bool is_navigation,
bool is_download,
network::mojom::URLLoaderFactoryOverride* agent_override) { … }
}
bool WillCreateURLLoaderFactoryParams::Run(
bool is_navigation,
bool is_download,
network::URLLoaderFactoryBuilder& factory_builder,
network::mojom::URLLoaderFactoryOverridePtr* factory_override) { … }
WillCreateURLLoaderFactoryParams::WillCreateURLLoaderFactoryParams(
DevToolsAgentHostImpl* agent_host,
const base::UnguessableToken& devtools_token,
int process_id,
StoragePartition* storage_partition)
: … { … }
WillCreateURLLoaderFactoryParams WillCreateURLLoaderFactoryParams::ForFrame(
RenderFrameHostImpl* rfh) { … }
WillCreateURLLoaderFactoryParams
WillCreateURLLoaderFactoryParams::ForServiceWorker(RenderProcessHost& rph,
int routing_id) { … }
std::optional<WillCreateURLLoaderFactoryParams>
WillCreateURLLoaderFactoryParams::ForServiceWorkerMainScript(
const ServiceWorkerContextWrapper* context_wrapper,
std::optional<int64_t> version_id) { … }
std::optional<WillCreateURLLoaderFactoryParams>
WillCreateURLLoaderFactoryParams::ForSharedWorker(SharedWorkerHost* host) { … }
WillCreateURLLoaderFactoryParams
WillCreateURLLoaderFactoryParams::ForWorkerMainScript(
DevToolsAgentHostImpl* agent_host,
const base::UnguessableToken& worker_token,
RenderFrameHostImpl& ancestor_render_frame_host) { … }
void OnPrefetchRequestWillBeSent(
FrameTreeNode* frame_tree_node,
const std::string& request_id,
const GURL& initiator,
const network::ResourceRequest& request,
std::optional<std::pair<const GURL&,
const network::mojom::URLResponseHeadDevToolsInfo&>>
redirect_info) { … }
void OnPrefetchResponseReceived(FrameTreeNode* frame_tree_node,
const std::string& request_id,
const GURL& url,
const network::mojom::URLResponseHead& head) { … }
void OnPrefetchRequestComplete(
FrameTreeNode* frame_tree_node,
const std::string& request_id,
const network::URLLoaderCompletionStatus& status) { … }
void OnPrefetchBodyDataReceived(FrameTreeNode* frame_tree_node,
const std::string& request_id,
const std::string& body,
bool is_base64_encoded) { … }
void OnAuctionWorkletNetworkRequestWillBeSent(
int frame_tree_node_id,
const network::ResourceRequest& request,
base::TimeTicks timestamp) { … }
void OnAuctionWorkletNetworkResponseReceived(
int frame_tree_node_id,
const std::string& request_id,
const std::string& loader_id,
const GURL& request_url,
const network::mojom::URLResponseHead& headers) { … }
void OnAuctionWorkletNetworkRequestComplete(
int frame_tree_node_id,
const std::string& request_id,
const network::URLLoaderCompletionStatus& status) { … }
bool NeedInterestGroupAuctionEvents(int frame_tree_node_id) { … }
void OnInterestGroupAuctionEventOccurred(
int frame_tree_node_id,
base::Time event_time,
InterestGroupAuctionEventType type,
const std::string& unique_auction_id,
base::optional_ref<const std::string> parent_auction_id,
const base::Value::Dict& auction_config) { … }
void OnInterestGroupAuctionNetworkRequestCreated(
int frame_tree_node_id,
content::InterestGroupAuctionFetchType type,
const std::string& request_id,
const std::vector<std::string>& devtools_auction_ids) { … }
void OnNavigationRequestWillBeSent(
const NavigationRequest& navigation_request) { … }
bool NotifyCertificateError(DevToolsAgentHost* host,
int cert_error,
const GURL& request_url,
const CertErrorCallback& callback) { … }
bool HandleCertificateError(WebContents* web_contents,
int cert_error,
const GURL& request_url,
CertErrorCallback callback) { … }
void FencedFrameCreated(
base::SafeRef<RenderFrameHostImpl> owner_render_frame_host,
FencedFrame* fenced_frame) { … }
void WillStartDragging(FrameTreeNode* main_frame_tree_node,
const content::DropData& drop_data,
const blink::mojom::DragDataPtr drag_data,
blink::DragOperationsMask drag_operations_mask,
bool* intercepted) { … }
void DragEnded(FrameTreeNode& node) { … }
namespace {
std::unique_ptr<protocol::Array<protocol::String>> BuildExclusionReasons(
net::CookieInclusionStatus status) { … }
std::unique_ptr<protocol::Array<protocol::String>> BuildWarningReasons(
net::CookieInclusionStatus status) { … }
protocol::String BuildCookieOperation(blink::mojom::CookieOperation operation) { … }
std::unique_ptr<protocol::Audits::InspectorIssue>
BuildCookieDeprecationMetadataIssue(
const blink::mojom::CookieDeprecationMetadataIssueDetailsPtr&
issue_details) { … }
}
void ReportCookieIssue(
RenderFrameHostImpl* render_frame_host_impl,
const network::mojom::CookieOrLineWithAccessResultPtr& excluded_cookie,
const GURL& url,
const net::SiteForCookies& site_for_cookies,
blink::mojom::CookieOperation operation,
const std::optional<std::string>& devtools_request_id,
const std::optional<std::string>& devtools_issue_id) { … }
namespace {
void AddIssueToIssueStorage(
RenderFrameHost* rfh,
std::unique_ptr<protocol::Audits::InspectorIssue> issue) { … }
}
void ReportBrowserInitiatedIssue(RenderFrameHostImpl* frame,
protocol::Audits::InspectorIssue* issue) { … }
void BuildAndReportBrowserInitiatedIssue(
RenderFrameHostImpl* frame,
blink::mojom::InspectorIssueInfoPtr info) { … }
void OnWebTransportHandshakeFailed(
RenderFrameHostImpl* frame,
const GURL& url,
const std::optional<net::WebTransportError>& error) { … }
void OnServiceWorkerMainScriptFetchingFailed(
const GlobalRenderFrameHostId& requesting_frame_id,
const ServiceWorkerContextWrapper* context_wrapper,
int64_t version_id,
const std::string& error,
const network::URLLoaderCompletionStatus& status,
const network::mojom::URLResponseHead* response_head,
const GURL& url) { … }
namespace {
void MaybeAssignResourceRequestId(DevToolsAgentHostImpl* host,
const std::string& id,
network::ResourceRequest& request) { … }
}
void MaybeAssignResourceRequestId(FrameTreeNode* ftn,
const std::string& id,
network::ResourceRequest& request) { … }
void OnServiceWorkerMainScriptRequestWillBeSent(
const GlobalRenderFrameHostId& requesting_frame_id,
const ServiceWorkerContextWrapper* context_wrapper,
int64_t version_id,
network::ResourceRequest& request) { … }
void OnWorkerMainScriptLoadingFailed(
const GURL& url,
const base::UnguessableToken& worker_token,
FrameTreeNode* ftn,
RenderFrameHostImpl* ancestor_rfh,
const network::URLLoaderCompletionStatus& status) { … }
void OnWorkerMainScriptLoadingFinished(
FrameTreeNode* ftn,
const base::UnguessableToken& worker_token,
const network::URLLoaderCompletionStatus& status) { … }
void OnWorkerMainScriptRequestWillBeSent(
FrameTreeNode* ftn,
const base::UnguessableToken& worker_token,
network::ResourceRequest& request) { … }
void LogWorkletMessage(RenderFrameHostImpl& frame_host,
blink::mojom::ConsoleMessageLevel log_level,
const std::string& message) { … }
void ApplyNetworkContextParamsOverrides(
BrowserContext* browser_context,
network::mojom::NetworkContextParams* context_params) { … }
protocol::Audits::GenericIssueErrorType GenericIssueErrorTypeToProtocol(
blink::mojom::GenericIssueErrorType error_type) { … }
void UpdateDeviceRequestPrompt(RenderFrameHost* render_frame_host,
DevtoolsDeviceRequestPromptInfo* prompt_info) { … }
void CleanUpDeviceRequestPrompt(RenderFrameHost* render_frame_host,
DevtoolsDeviceRequestPromptInfo* prompt_info) { … }
void WillSendFedCmRequest(RenderFrameHost& render_frame_host,
bool* intercept,
bool* disable_delay) { … }
void WillShowFedCmDialog(RenderFrameHost& render_frame_host, bool* intercept) { … }
void DidShowFedCmDialog(RenderFrameHost& render_frame_host) { … }
void DidCloseFedCmDialog(RenderFrameHost& render_frame_host) { … }
void OnFencedFrameReportRequestSent(int initiator_frame_tree_node_id,
const std::string& devtools_request_id,
network::ResourceRequest& request,
const std::string& event_data) { … }
void OnFencedFrameReportResponseReceived(
int initiator_frame_tree_node_id,
const std::string& devtools_request_id,
const GURL& final_url,
scoped_refptr<net::HttpResponseHeaders> headers) { … }
void DidChangeFrameLoadingState(FrameTreeNode& ftn) { … }
}
}