blob: adb142325592f09e385a3c4158e6410c4576cc4d [file] [log] [blame]
// 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,
network::mojom::ClientSecurityStatePtr security_state,
network::mojom::OtherPartitionInfoPtr other_partition_info) {
auto* host = GetDevToolsAgentHost();
if (!host)
return;
DispatchToAgents(host,
&protocol::NetworkHandler::OnRequestWillBeSentExtraInfo,
devtools_request_id, request_cookie_list, request_headers,
timestamp, security_state, other_partition_info);
}
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::OnPrivateNetworkRequest(
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::InsecurePrivateNetwork)
.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));
}
void NetworkServiceDevToolsObserver::OnSubresourceWebBundleMetadata(
const std::string& devtools_request_id,
const std::vector<GURL>& urls) {
auto* host = GetDevToolsAgentHost();
if (!host)
return;
DispatchToAgents(host,
&protocol::NetworkHandler::OnSubresourceWebBundleMetadata,
devtools_request_id, urls);
}
void NetworkServiceDevToolsObserver::OnSubresourceWebBundleMetadataError(
const std::string& devtools_request_id,
const std::string& error_message) {
auto* host = GetDevToolsAgentHost();
if (!host)
return;
DispatchToAgents(
host, &protocol::NetworkHandler::OnSubresourceWebBundleMetadataError,
devtools_request_id, error_message);
}
void NetworkServiceDevToolsObserver::OnSubresourceWebBundleInnerResponse(
const std::string& inner_request_devtools_id,
const GURL& url,
const std::optional<std::string>& bundle_request_devtools_id) {
auto* host = GetDevToolsAgentHost();
if (!host)
return;
DispatchToAgents(
host, &protocol::NetworkHandler::OnSubresourceWebBundleInnerResponse,
inner_request_devtools_id, url, bundle_request_devtools_id);
}
void NetworkServiceDevToolsObserver::OnSubresourceWebBundleInnerResponseError(
const std::string& inner_request_devtools_id,
const GURL& url,
const std::string& error_message,
const std::optional<std::string>& bundle_request_devtools_id) {
auto* host = GetDevToolsAgentHost();
if (!host)
return;
DispatchToAgents(
host, &protocol::NetworkHandler::OnSubresourceWebBundleInnerResponseError,
inner_request_devtools_id, url, error_message,
bundle_request_devtools_id);
}
namespace {
protocol::String BuildSharedDictionaryError(
network::mojom::SharedDictionaryError write_error) {
using network::mojom::SharedDictionaryError;
namespace SharedDictionaryErrorEnum =
protocol::Audits::SharedDictionaryErrorEnum;
switch (write_error) {
case SharedDictionaryError::kUseErrorCrossOriginNoCorsRequest:
return SharedDictionaryErrorEnum::UseErrorCrossOriginNoCorsRequest;
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::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::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;
}
}
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;
}
}
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;
}
}
} // 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::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