| // Copyright 2021 The Chromium Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "content/browser/devtools/network_service_devtools_observer.h" | |
| #include "base/feature_list.h" | |
| #include "content/browser/devtools/devtools_agent_host_impl.h" | |
| #include "content/browser/devtools/devtools_instrumentation.h" | |
| #include "content/browser/devtools/protocol/audits_handler.h" | |
| #include "content/browser/devtools/protocol/network_handler.h" | |
| #include "content/browser/devtools/render_frame_devtools_agent_host.h" | |
| #include "content/browser/renderer_host/frame_tree_node.h" | |
| #include "content/public/common/content_client.h" | |
| #include "mojo/public/cpp/bindings/self_owned_receiver.h" | |
| #include "services/network/public/cpp/features.h" | |
| #include "services/network/public/mojom/http_raw_headers.mojom.h" | |
| #include "services/network/public/mojom/shared_dictionary_error.mojom.h" | |
| #include "services/network/public/mojom/sri_message_signature.mojom.h" | |
| #include "services/network/public/mojom/unencoded_digest.mojom.h" | |
| #include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom.h" | |
| namespace content { | |
| namespace { | |
| template <typename Handler, typename... MethodArgs, typename... Args> | |
| void DispatchToAgents(DevToolsAgentHostImpl* agent_host, | |
| void (Handler::*method)(MethodArgs...), | |
| Args&&... args) { | |
| for (auto* h : Handler::ForAgentHost(agent_host)) | |
| (h->*method)(std::forward<Args>(args)...); | |
| } | |
| RenderFrameHostImpl* GetRenderFrameHostImplFrom( | |
| FrameTreeNodeId frame_tree_node_id) { | |
| auto* ftn = FrameTreeNode::GloballyFindByID(frame_tree_node_id); | |
| if (!ftn) { | |
| return nullptr; | |
| } | |
| RenderFrameHostImpl* rfhi = ftn->current_frame_host(); | |
| return rfhi; | |
| } | |
| } // namespace | |
| NetworkServiceDevToolsObserver::NetworkServiceDevToolsObserver( | |
| base::PassKey<NetworkServiceDevToolsObserver> pass_key, | |
| const std::string& id, | |
| FrameTreeNodeId frame_tree_node_id) | |
| : devtools_agent_id_(id), frame_tree_node_id_(frame_tree_node_id) {} | |
| NetworkServiceDevToolsObserver::~NetworkServiceDevToolsObserver() = default; | |
| DevToolsAgentHostImpl* NetworkServiceDevToolsObserver::GetDevToolsAgentHost() { | |
| if (frame_tree_node_id_) { | |
| auto* frame_tree_node = | |
| FrameTreeNode::GloballyFindByID(frame_tree_node_id_); | |
| if (!frame_tree_node) | |
| return nullptr; | |
| return RenderFrameDevToolsAgentHost::GetForWithAncestorFallback( | |
| frame_tree_node); | |
| } | |
| auto host = DevToolsAgentHostImpl::GetForId(devtools_agent_id_); | |
| if (!host) | |
| return nullptr; | |
| return host.get(); | |
| } | |
| void NetworkServiceDevToolsObserver::OnRawRequest( | |
| const std::string& devtools_request_id, | |
| const net::CookieAccessResultList& request_cookie_list, | |
| std::vector<network::mojom::HttpRawHeaderPairPtr> request_headers, | |
| base::TimeTicks timestamp, | |
| std::vector<network::mojom::DeviceBoundSessionWithUsagePtr> | |
| device_bound_session_usages, | |
| network::mojom::ClientSecurityStatePtr security_state, | |
| network::mojom::OtherPartitionInfoPtr other_partition_info, | |
| const std::optional<base::UnguessableToken>& | |
| applied_network_conditions_id) { | |
| auto* host = GetDevToolsAgentHost(); | |
| if (!host) | |
| return; | |
| DispatchToAgents(host, | |
| &protocol::NetworkHandler::OnRequestWillBeSentExtraInfo, | |
| devtools_request_id, request_cookie_list, request_headers, | |
| timestamp, device_bound_session_usages, security_state, | |
| other_partition_info, applied_network_conditions_id); | |
| } | |
| void NetworkServiceDevToolsObserver::OnRawResponse( | |
| const std::string& devtools_request_id, | |
| const net::CookieAndLineAccessResultList& response_cookie_list, | |
| std::vector<network::mojom::HttpRawHeaderPairPtr> response_headers, | |
| const std::optional<std::string>& response_headers_text, | |
| network::mojom::IPAddressSpace resource_address_space, | |
| int32_t http_status_code, | |
| const std::optional<net::CookiePartitionKey>& cookie_partition_key) { | |
| auto* host = GetDevToolsAgentHost(); | |
| if (!host) | |
| return; | |
| DispatchToAgents(host, &protocol::NetworkHandler::OnResponseReceivedExtraInfo, | |
| devtools_request_id, response_cookie_list, response_headers, | |
| response_headers_text, resource_address_space, | |
| http_status_code, cookie_partition_key); | |
| } | |
| void NetworkServiceDevToolsObserver::OnEarlyHintsResponse( | |
| const std::string& devtools_request_id, | |
| std::vector<network::mojom::HttpRawHeaderPairPtr> headers) { | |
| auto* host = GetDevToolsAgentHost(); | |
| if (!host) { | |
| return; | |
| } | |
| DispatchToAgents(host, | |
| &protocol::NetworkHandler::OnResponseReceivedEarlyHints, | |
| devtools_request_id, headers); | |
| } | |
| void NetworkServiceDevToolsObserver::OnTrustTokenOperationDone( | |
| const std::string& devtools_request_id, | |
| network::mojom::TrustTokenOperationResultPtr result) { | |
| auto* host = GetDevToolsAgentHost(); | |
| if (!host) | |
| return; | |
| DispatchToAgents(host, &protocol::NetworkHandler::OnTrustTokenOperationDone, | |
| devtools_request_id, *result); | |
| } | |
| void NetworkServiceDevToolsObserver::OnLocalNetworkRequest( | |
| const std::optional<std::string>& devtools_request_id, | |
| const GURL& url, | |
| bool is_warning, | |
| network::mojom::IPAddressSpace resource_address_space, | |
| network::mojom::ClientSecurityStatePtr client_security_state) { | |
| if (frame_tree_node_id_.is_null()) { | |
| return; | |
| } | |
| auto* ftn = FrameTreeNode::GloballyFindByID(frame_tree_node_id_); | |
| if (!ftn) | |
| return; | |
| auto cors_error_status = | |
| protocol::Network::CorsErrorStatus::Create() | |
| .SetCorsError( | |
| base::FeatureList::IsEnabled( | |
| network::features::kLocalNetworkAccessChecks) | |
| ? protocol::Network::CorsErrorEnum:: | |
| LocalNetworkAccessPermissionDenied | |
| : protocol::Network::CorsErrorEnum::InsecureLocalNetwork) | |
| .SetFailedParameter("") | |
| .Build(); | |
| std::unique_ptr<protocol::Audits::AffectedRequest> affected_request = | |
| protocol::Audits::AffectedRequest::Create() | |
| .SetRequestId(devtools_request_id.value_or("")) | |
| .SetUrl(url.spec()) | |
| .Build(); | |
| auto cors_issue_details = | |
| protocol::Audits::CorsIssueDetails::Create() | |
| .SetIsWarning(is_warning) | |
| .SetResourceIPAddressSpace( | |
| protocol::NetworkHandler::BuildIpAddressSpace( | |
| resource_address_space)) | |
| .SetRequest(std::move(affected_request)) | |
| .SetCorsErrorStatus(std::move(cors_error_status)) | |
| .Build(); | |
| if (auto maybe_protocol_security_state = | |
| protocol::NetworkHandler::MaybeBuildClientSecurityState( | |
| client_security_state)) { | |
| cors_issue_details->SetClientSecurityState( | |
| std::move(maybe_protocol_security_state)); | |
| } | |
| auto details = protocol::Audits::InspectorIssueDetails::Create() | |
| .SetCorsIssueDetails(std::move(cors_issue_details)) | |
| .Build(); | |
| auto issue = protocol::Audits::InspectorIssue::Create() | |
| .SetCode(protocol::Audits::InspectorIssueCodeEnum::CorsIssue) | |
| .SetDetails(std::move(details)) | |
| .Build(); | |
| devtools_instrumentation::ReportBrowserInitiatedIssue( | |
| ftn->current_frame_host(), std::move(issue)); | |
| } | |
| void NetworkServiceDevToolsObserver::OnCorsPreflightRequest( | |
| const base::UnguessableToken& devtools_request_id, | |
| const net::HttpRequestHeaders& request_headers, | |
| network::mojom::URLRequestDevToolsInfoPtr request_info, | |
| const GURL& initiator_url, | |
| const std::string& initiator_devtools_request_id) { | |
| auto* host = GetDevToolsAgentHost(); | |
| if (!host) | |
| return; | |
| auto timestamp = base::TimeTicks::Now(); | |
| auto id = devtools_request_id.ToString(); | |
| DispatchToAgents(host, &protocol::NetworkHandler::RequestSent, id, | |
| /* loader_id=*/"", request_headers, *request_info, | |
| protocol::Network::Initiator::TypeEnum::Preflight, | |
| initiator_url, initiator_devtools_request_id, | |
| /*frame_token=*/std::nullopt, timestamp); | |
| } | |
| void NetworkServiceDevToolsObserver::OnCorsPreflightResponse( | |
| const base::UnguessableToken& devtools_request_id, | |
| const GURL& url, | |
| network::mojom::URLResponseHeadDevToolsInfoPtr head) { | |
| auto* host = GetDevToolsAgentHost(); | |
| if (!host) | |
| return; | |
| auto id = devtools_request_id.ToString(); | |
| DispatchToAgents(host, &protocol::NetworkHandler::ResponseReceived, id, | |
| /* loader_id=*/"", url, | |
| protocol::Network::ResourceTypeEnum::Preflight, *head, | |
| std::nullopt); | |
| } | |
| void NetworkServiceDevToolsObserver::OnCorsPreflightRequestCompleted( | |
| const base::UnguessableToken& devtools_request_id, | |
| const network::URLLoaderCompletionStatus& status) { | |
| auto* host = GetDevToolsAgentHost(); | |
| if (!host) | |
| return; | |
| auto id = devtools_request_id.ToString(); | |
| DispatchToAgents(host, &protocol::NetworkHandler::LoadingComplete, id, | |
| protocol::Network::ResourceTypeEnum::Preflight, status); | |
| } | |
| void NetworkServiceDevToolsObserver::OnCorsError( | |
| const std::optional<std::string>& devtools_request_id, | |
| const std::optional<::url::Origin>& initiator_origin, | |
| network::mojom::ClientSecurityStatePtr client_security_state, | |
| const GURL& url, | |
| const network::CorsErrorStatus& cors_error_status, | |
| bool is_warning) { | |
| RenderFrameHostImpl* rfhi = GetRenderFrameHostImplFrom(frame_tree_node_id_); | |
| if (!rfhi) | |
| return; | |
| std::unique_ptr<protocol::Audits::AffectedRequest> affected_request = | |
| protocol::Audits::AffectedRequest::Create() | |
| .SetRequestId(devtools_request_id ? *devtools_request_id : "") | |
| .SetUrl(url.spec()) | |
| .Build(); | |
| auto cors_issue_details = | |
| protocol::Audits::CorsIssueDetails::Create() | |
| .SetIsWarning(is_warning) | |
| .SetRequest(std::move(affected_request)) | |
| .SetCorsErrorStatus( | |
| protocol::NetworkHandler::BuildCorsErrorStatus(cors_error_status)) | |
| .Build(); | |
| if (initiator_origin) { | |
| cors_issue_details->SetInitiatorOrigin(initiator_origin->GetURL().spec()); | |
| } | |
| if (auto maybe_protocol_security_state = | |
| protocol::NetworkHandler::MaybeBuildClientSecurityState( | |
| client_security_state)) { | |
| cors_issue_details->SetClientSecurityState( | |
| std::move(maybe_protocol_security_state)); | |
| } | |
| auto details = protocol::Audits::InspectorIssueDetails::Create() | |
| .SetCorsIssueDetails(std::move(cors_issue_details)) | |
| .Build(); | |
| auto issue = protocol::Audits::InspectorIssue::Create() | |
| .SetCode(protocol::Audits::InspectorIssueCodeEnum::CorsIssue) | |
| .SetDetails(std::move(details)) | |
| .SetIssueId(cors_error_status.issue_id.ToString()) | |
| .Build(); | |
| devtools_instrumentation::ReportBrowserInitiatedIssue(rfhi, std::move(issue)); | |
| } | |
| void NetworkServiceDevToolsObserver::OnOrbError( | |
| const std::optional<std::string>& devtools_request_id, | |
| const GURL& url) { | |
| RenderFrameHostImpl* rfhi = GetRenderFrameHostImplFrom(frame_tree_node_id_); | |
| if (!rfhi) { | |
| return; | |
| } | |
| std::unique_ptr<protocol::Audits::AffectedRequest> affected_request = | |
| protocol::Audits::AffectedRequest::Create() | |
| .SetRequestId(devtools_request_id.value_or("")) | |
| .SetUrl(url.spec()) | |
| .Build(); | |
| auto generic_details = | |
| protocol::Audits::GenericIssueDetails::Create() | |
| .SetErrorType(protocol::Audits::GenericIssueErrorTypeEnum:: | |
| ResponseWasBlockedByORB) | |
| .SetRequest(std::move(affected_request)) | |
| .Build(); | |
| auto details = protocol::Audits::InspectorIssueDetails::Create() | |
| .SetGenericIssueDetails(std::move(generic_details)) | |
| .Build(); | |
| auto issue = | |
| protocol::Audits::InspectorIssue::Create() | |
| .SetCode(protocol::Audits::InspectorIssueCodeEnum::GenericIssue) | |
| .SetDetails(std::move(details)) | |
| .Build(); | |
| devtools_instrumentation::ReportBrowserInitiatedIssue(rfhi, std::move(issue)); | |
| } | |
| namespace { | |
| protocol::String BuildSharedDictionaryError( | |
| network::mojom::SharedDictionaryError write_error) { | |
| using network::mojom::SharedDictionaryError; | |
| namespace SharedDictionaryErrorEnum = | |
| protocol::Audits::SharedDictionaryErrorEnum; | |
| switch (write_error) { | |
| case SharedDictionaryError::kUseErrorDictionaryLoadFailure: | |
| return SharedDictionaryErrorEnum::UseErrorDictionaryLoadFailure; | |
| case SharedDictionaryError::kUseErrorMatchingDictionaryNotUsed: | |
| return SharedDictionaryErrorEnum::UseErrorMatchingDictionaryNotUsed; | |
| case SharedDictionaryError::kUseErrorUnexpectedContentDictionaryHeader: | |
| return SharedDictionaryErrorEnum:: | |
| UseErrorUnexpectedContentDictionaryHeader; | |
| case SharedDictionaryError::kWriteErrorAlreadyRegistered: | |
| NOTREACHED(); | |
| case SharedDictionaryError::kWriteErrorCossOriginNoCorsRequest: | |
| return SharedDictionaryErrorEnum::WriteErrorCossOriginNoCorsRequest; | |
| case SharedDictionaryError::kWriteErrorDisallowedBySettings: | |
| return SharedDictionaryErrorEnum::WriteErrorDisallowedBySettings; | |
| case SharedDictionaryError::kWriteErrorExpiredResponse: | |
| return SharedDictionaryErrorEnum::WriteErrorExpiredResponse; | |
| case SharedDictionaryError::kWriteErrorFeatureDisabled: | |
| return SharedDictionaryErrorEnum::WriteErrorFeatureDisabled; | |
| case SharedDictionaryError::kWriteErrorInsufficientResources: | |
| return SharedDictionaryErrorEnum::WriteErrorInsufficientResources; | |
| case SharedDictionaryError::kWriteErrorInvalidMatchField: | |
| return SharedDictionaryErrorEnum::WriteErrorInvalidMatchField; | |
| case SharedDictionaryError::kWriteErrorInvalidStructuredHeader: | |
| return SharedDictionaryErrorEnum::WriteErrorInvalidStructuredHeader; | |
| case SharedDictionaryError::kWriteErrorInvalidTTLField: | |
| return SharedDictionaryErrorEnum::WriteErrorInvalidTTLField; | |
| case SharedDictionaryError::kWriteErrorNavigationRequest: | |
| return SharedDictionaryErrorEnum::WriteErrorNavigationRequest; | |
| case SharedDictionaryError::kWriteErrorNoMatchField: | |
| return SharedDictionaryErrorEnum::WriteErrorNoMatchField; | |
| case SharedDictionaryError::kWriteErrorNonListMatchDestField: | |
| return SharedDictionaryErrorEnum::WriteErrorNonListMatchDestField; | |
| case SharedDictionaryError::kWriteErrorNonSecureContext: | |
| return SharedDictionaryErrorEnum::WriteErrorNonSecureContext; | |
| case SharedDictionaryError::kWriteErrorNonStringIdField: | |
| return SharedDictionaryErrorEnum::WriteErrorNonStringIdField; | |
| case SharedDictionaryError::kWriteErrorNonStringInMatchDestList: | |
| return SharedDictionaryErrorEnum::WriteErrorNonStringInMatchDestList; | |
| case SharedDictionaryError::kWriteErrorInvalidMatchDestList: | |
| return SharedDictionaryErrorEnum::WriteErrorInvalidMatchDestList; | |
| case SharedDictionaryError::kWriteErrorNonStringMatchField: | |
| return SharedDictionaryErrorEnum::WriteErrorNonStringMatchField; | |
| case SharedDictionaryError::kWriteErrorNonTokenTypeField: | |
| return SharedDictionaryErrorEnum::WriteErrorNonTokenTypeField; | |
| case SharedDictionaryError::kWriteErrorRequestAborted: | |
| return SharedDictionaryErrorEnum::WriteErrorRequestAborted; | |
| case SharedDictionaryError::kWriteErrorShuttingDown: | |
| return SharedDictionaryErrorEnum::WriteErrorShuttingDown; | |
| case SharedDictionaryError::kWriteErrorTooLongIdField: | |
| return SharedDictionaryErrorEnum::WriteErrorTooLongIdField; | |
| case SharedDictionaryError::kWriteErrorUnsupportedType: | |
| return SharedDictionaryErrorEnum::WriteErrorUnsupportedType; | |
| case SharedDictionaryError::kWriteErrorNonIntegerTTLField: | |
| return SharedDictionaryErrorEnum::WriteErrorNonIntegerTTLField; | |
| } | |
| } | |
| protocol::String ConvertToDevtoolsEnum( | |
| network::mojom::SRIMessageSignatureError error) { | |
| using network::mojom::SRIMessageSignatureError; | |
| namespace SRIMessageSignatureErrorEnum = | |
| protocol::Audits::SRIMessageSignatureErrorEnum; | |
| switch (error) { | |
| case SRIMessageSignatureError::kMissingSignatureHeader: | |
| return SRIMessageSignatureErrorEnum::MissingSignatureHeader; | |
| case SRIMessageSignatureError::kMissingSignatureInputHeader: | |
| return SRIMessageSignatureErrorEnum::MissingSignatureInputHeader; | |
| case SRIMessageSignatureError::kInvalidSignatureHeader: | |
| return SRIMessageSignatureErrorEnum::InvalidSignatureHeader; | |
| case SRIMessageSignatureError::kInvalidSignatureInputHeader: | |
| return SRIMessageSignatureErrorEnum::InvalidSignatureInputHeader; | |
| case SRIMessageSignatureError::kSignatureHeaderValueIsNotByteSequence: | |
| return SRIMessageSignatureErrorEnum:: | |
| SignatureHeaderValueIsNotByteSequence; | |
| case SRIMessageSignatureError::kSignatureHeaderValueIsParameterized: | |
| return SRIMessageSignatureErrorEnum::SignatureHeaderValueIsParameterized; | |
| case SRIMessageSignatureError::kSignatureHeaderValueIsIncorrectLength: | |
| return SRIMessageSignatureErrorEnum:: | |
| SignatureHeaderValueIsIncorrectLength; | |
| case SRIMessageSignatureError::kSignatureInputHeaderMissingLabel: | |
| return SRIMessageSignatureErrorEnum::SignatureInputHeaderMissingLabel; | |
| case SRIMessageSignatureError::kSignatureInputHeaderValueNotInnerList: | |
| return SRIMessageSignatureErrorEnum:: | |
| SignatureInputHeaderValueNotInnerList; | |
| case SRIMessageSignatureError::kSignatureInputHeaderValueMissingComponents: | |
| return SRIMessageSignatureErrorEnum:: | |
| SignatureInputHeaderValueMissingComponents; | |
| case SRIMessageSignatureError::kSignatureInputHeaderInvalidComponentType: | |
| return SRIMessageSignatureErrorEnum:: | |
| SignatureInputHeaderInvalidComponentType; | |
| case SRIMessageSignatureError::kSignatureInputHeaderInvalidComponentName: | |
| return SRIMessageSignatureErrorEnum:: | |
| SignatureInputHeaderInvalidComponentName; | |
| case SRIMessageSignatureError:: | |
| kSignatureInputHeaderInvalidHeaderComponentParameter: | |
| return SRIMessageSignatureErrorEnum:: | |
| SignatureInputHeaderInvalidHeaderComponentParameter; | |
| case SRIMessageSignatureError:: | |
| kSignatureInputHeaderInvalidDerivedComponentParameter: | |
| return SRIMessageSignatureErrorEnum:: | |
| SignatureInputHeaderInvalidDerivedComponentParameter; | |
| case SRIMessageSignatureError::kSignatureInputHeaderKeyIdLength: | |
| return SRIMessageSignatureErrorEnum::SignatureInputHeaderKeyIdLength; | |
| case SRIMessageSignatureError::kSignatureInputHeaderInvalidParameter: | |
| return SRIMessageSignatureErrorEnum::SignatureInputHeaderInvalidParameter; | |
| case SRIMessageSignatureError:: | |
| kSignatureInputHeaderMissingRequiredParameters: | |
| return SRIMessageSignatureErrorEnum:: | |
| SignatureInputHeaderMissingRequiredParameters; | |
| case SRIMessageSignatureError::kValidationFailedSignatureExpired: | |
| return SRIMessageSignatureErrorEnum::ValidationFailedSignatureExpired; | |
| case SRIMessageSignatureError::kValidationFailedSignatureMismatch: | |
| return SRIMessageSignatureErrorEnum::ValidationFailedSignatureMismatch; | |
| case SRIMessageSignatureError::kValidationFailedInvalidLength: | |
| return SRIMessageSignatureErrorEnum::ValidationFailedInvalidLength; | |
| case SRIMessageSignatureError::kValidationFailedIntegrityMismatch: | |
| return SRIMessageSignatureErrorEnum::ValidationFailedIntegrityMismatch; | |
| case SRIMessageSignatureError::kSignatureBaseUnknownDerivedComponent: | |
| return SRIMessageSignatureErrorEnum::SignatureBaseUnknownDerivedComponent; | |
| case SRIMessageSignatureError::kSignatureBaseMissingHeader: | |
| return SRIMessageSignatureErrorEnum::SignatureBaseMissingHeader; | |
| case SRIMessageSignatureError::kSignatureBaseInvalidUnencodedDigest: | |
| return SRIMessageSignatureErrorEnum::SignatureBaseInvalidUnencodedDigest; | |
| case SRIMessageSignatureError::kSignatureBaseUnsupportedComponent: | |
| return SRIMessageSignatureErrorEnum::SignatureBaseUnsupportedComponent; | |
| } | |
| } | |
| protocol::String ConvertToDevtoolsEnum( | |
| network::mojom::UnencodedDigestIssue error) { | |
| using network::mojom::UnencodedDigestIssue; | |
| namespace UnencodedDigestErrorEnum = | |
| protocol::Audits::UnencodedDigestErrorEnum; | |
| switch (error) { | |
| case UnencodedDigestIssue::kMalformedDictionary: | |
| return UnencodedDigestErrorEnum::MalformedDictionary; | |
| case UnencodedDigestIssue::kUnknownAlgorithm: | |
| return UnencodedDigestErrorEnum::UnknownAlgorithm; | |
| case UnencodedDigestIssue::kIncorrectDigestType: | |
| return UnencodedDigestErrorEnum::IncorrectDigestType; | |
| case UnencodedDigestIssue::kIncorrectDigestLength: | |
| return UnencodedDigestErrorEnum::IncorrectDigestLength; | |
| } | |
| } | |
| protocol::String ConvertToDevtoolsEnum( | |
| network::mojom::ConnectionAllowlistIssue error) { | |
| using network::mojom::ConnectionAllowlistIssue; | |
| namespace ConnectionAllowlistErrorEnum = | |
| protocol::Audits::ConnectionAllowlistErrorEnum; | |
| switch (error) { | |
| case ConnectionAllowlistIssue::kInvalidHeader: | |
| return ConnectionAllowlistErrorEnum::InvalidHeader; | |
| case ConnectionAllowlistIssue::kMoreThanOneList: | |
| return ConnectionAllowlistErrorEnum::MoreThanOneList; | |
| case ConnectionAllowlistIssue::kItemNotInnerList: | |
| return ConnectionAllowlistErrorEnum::ItemNotInnerList; | |
| case ConnectionAllowlistIssue::kInvalidAllowlistItemType: | |
| return ConnectionAllowlistErrorEnum::InvalidAllowlistItemType; | |
| case ConnectionAllowlistIssue::kReportingEndpointNotToken: | |
| return ConnectionAllowlistErrorEnum::ReportingEndpointNotToken; | |
| case ConnectionAllowlistIssue::kInvalidUrlPattern: | |
| return ConnectionAllowlistErrorEnum::InvalidUrlPattern; | |
| } | |
| } | |
| } // namespace | |
| void NetworkServiceDevToolsObserver::OnSharedDictionaryError( | |
| const std::string& devtool_request_id, | |
| const GURL& url, | |
| network::mojom::SharedDictionaryError error) { | |
| RenderFrameHostImpl* rfhi = GetRenderFrameHostImplFrom(frame_tree_node_id_); | |
| if (!rfhi) { | |
| return; | |
| } | |
| auto affected_request = protocol::Audits::AffectedRequest::Create() | |
| .SetRequestId(devtool_request_id) | |
| .SetUrl(url.spec()) | |
| .Build(); | |
| auto shared_dictionary_issue_details = | |
| protocol::Audits::SharedDictionaryIssueDetails::Create() | |
| .SetSharedDictionaryError(BuildSharedDictionaryError(error)) | |
| .SetRequest(std::move(affected_request)) | |
| .Build(); | |
| auto details = protocol::Audits::InspectorIssueDetails::Create() | |
| .SetSharedDictionaryIssueDetails( | |
| std::move(shared_dictionary_issue_details)) | |
| .Build(); | |
| auto issue = | |
| protocol::Audits::InspectorIssue::Create() | |
| .SetCode( | |
| protocol::Audits::InspectorIssueCodeEnum::SharedDictionaryIssue) | |
| .SetDetails(std::move(details)) | |
| .Build(); | |
| devtools_instrumentation::ReportBrowserInitiatedIssue(rfhi, std::move(issue)); | |
| } | |
| void NetworkServiceDevToolsObserver::OnSRIMessageSignatureIssue( | |
| const std::string& devtool_request_id, | |
| const GURL& url, | |
| std::vector<network::mojom::SRIMessageSignatureIssuePtr> issues) { | |
| RenderFrameHostImpl* rfhi = GetRenderFrameHostImplFrom(frame_tree_node_id_); | |
| if (!rfhi) { | |
| return; | |
| } | |
| for (const auto& issue : issues) { | |
| auto affected_request = protocol::Audits::AffectedRequest::Create() | |
| .SetRequestId(devtool_request_id) | |
| .SetUrl(url.spec()) | |
| .Build(); | |
| auto issue_details = | |
| protocol::Audits::SRIMessageSignatureIssueDetails::Create() | |
| .SetError(ConvertToDevtoolsEnum(issue->error)) | |
| .SetRequest(std::move(affected_request)) | |
| .SetSignatureBase(issue->signature_base.value_or("")) | |
| .SetIntegrityAssertions( | |
| issue->integrity_assertions.has_value() | |
| ? std::make_unique<protocol::Array<protocol::String>>( | |
| std::move(issue->integrity_assertions.value())) | |
| : std::make_unique<protocol::Array<protocol::String>>()) | |
| .Build(); | |
| auto details = | |
| protocol::Audits::InspectorIssueDetails::Create() | |
| .SetSriMessageSignatureIssueDetails(std::move(issue_details)) | |
| .Build(); | |
| auto devtools_issue = | |
| protocol::Audits::InspectorIssue::Create() | |
| .SetCode(protocol::Audits::InspectorIssueCodeEnum:: | |
| SRIMessageSignatureIssue) | |
| .SetDetails(std::move(details)) | |
| .Build(); | |
| devtools_instrumentation::ReportBrowserInitiatedIssue( | |
| rfhi, std::move(devtools_issue)); | |
| } | |
| } | |
| void NetworkServiceDevToolsObserver::OnUnencodedDigestError( | |
| const std::string& devtool_request_id, | |
| const GURL& url, | |
| network::mojom::UnencodedDigestIssue issue) { | |
| RenderFrameHostImpl* rfhi = GetRenderFrameHostImplFrom(frame_tree_node_id_); | |
| if (!rfhi) { | |
| return; | |
| } | |
| auto affected_request = protocol::Audits::AffectedRequest::Create() | |
| .SetRequestId(devtool_request_id) | |
| .SetUrl(url.spec()) | |
| .Build(); | |
| auto issue_details = protocol::Audits::UnencodedDigestIssueDetails::Create() | |
| .SetError(ConvertToDevtoolsEnum(issue)) | |
| .SetRequest(std::move(affected_request)) | |
| .Build(); | |
| auto details = protocol::Audits::InspectorIssueDetails::Create() | |
| .SetUnencodedDigestIssueDetails(std::move(issue_details)) | |
| .Build(); | |
| auto devtools_issue = | |
| protocol::Audits::InspectorIssue::Create() | |
| .SetCode( | |
| protocol::Audits::InspectorIssueCodeEnum::UnencodedDigestIssue) | |
| .SetDetails(std::move(details)) | |
| .Build(); | |
| devtools_instrumentation::ReportBrowserInitiatedIssue( | |
| rfhi, std::move(devtools_issue)); | |
| } | |
| void NetworkServiceDevToolsObserver::OnConnectionAllowlistIssue( | |
| const std::string& devtool_request_id, | |
| const GURL& url, | |
| network::mojom::ConnectionAllowlistIssue issue) { | |
| RenderFrameHostImpl* rfhi = GetRenderFrameHostImplFrom(frame_tree_node_id_); | |
| if (!rfhi) { | |
| return; | |
| } | |
| auto affected_request = protocol::Audits::AffectedRequest::Create() | |
| .SetRequestId(devtool_request_id) | |
| .SetUrl(url.spec()) | |
| .Build(); | |
| auto issue_details = | |
| protocol::Audits::ConnectionAllowlistIssueDetails::Create() | |
| .SetError(ConvertToDevtoolsEnum(issue)) | |
| .SetRequest(std::move(affected_request)) | |
| .Build(); | |
| auto details = | |
| protocol::Audits::InspectorIssueDetails::Create() | |
| .SetConnectionAllowlistIssueDetails(std::move(issue_details)) | |
| .Build(); | |
| auto devtools_issue = protocol::Audits::InspectorIssue::Create() | |
| .SetCode(protocol::Audits::InspectorIssueCodeEnum:: | |
| ConnectionAllowlistIssue) | |
| .SetDetails(std::move(details)) | |
| .Build(); | |
| devtools_instrumentation::ReportBrowserInitiatedIssue( | |
| rfhi, std::move(devtools_issue)); | |
| } | |
| void NetworkServiceDevToolsObserver::Clone( | |
| mojo::PendingReceiver<network::mojom::DevToolsObserver> observer) { | |
| mojo::MakeSelfOwnedReceiver( | |
| std::make_unique<NetworkServiceDevToolsObserver>( | |
| base::PassKey<NetworkServiceDevToolsObserver>(), devtools_agent_id_, | |
| frame_tree_node_id_), | |
| std::move(observer)); | |
| } | |
| mojo::PendingRemote<network::mojom::DevToolsObserver> | |
| NetworkServiceDevToolsObserver::MakeSelfOwned(const std::string& id) { | |
| mojo::PendingRemote<network::mojom::DevToolsObserver> remote; | |
| mojo::MakeSelfOwnedReceiver( | |
| std::make_unique<NetworkServiceDevToolsObserver>( | |
| base::PassKey<NetworkServiceDevToolsObserver>(), id, | |
| FrameTreeNodeId()), | |
| remote.InitWithNewPipeAndPassReceiver()); | |
| return remote; | |
| } | |
| mojo::PendingRemote<network::mojom::DevToolsObserver> | |
| NetworkServiceDevToolsObserver::MakeSelfOwned(FrameTreeNode* frame_tree_node) { | |
| mojo::PendingRemote<network::mojom::DevToolsObserver> remote; | |
| mojo::MakeSelfOwnedReceiver( | |
| std::make_unique<NetworkServiceDevToolsObserver>( | |
| base::PassKey<NetworkServiceDevToolsObserver>(), std::string(), | |
| frame_tree_node->frame_tree_node_id()), | |
| remote.InitWithNewPipeAndPassReceiver()); | |
| return remote; | |
| } | |
| } // namespace content |