Commit 4ac04d63 authored by Tsuyoshi Horo's avatar Tsuyoshi Horo Committed by Commit Bot

Brush up DevTools SignedExchange support

This incorporats with dgozman's comments in crrev.com/c/1004890
- Change "from SignedExchange" to "from signed-exchange" in NetworkRequestNode.
- Show the signed exchagne url as the initiator of certificate request.
- Show "from signed-exchange" in the headers tab of the inner request.
- Add "View request" link in the preview tab of signed exchange to show the inner request.
- Add "Learn more" link in the preview tab of signed exchange.

Bug: 830505
Change-Id: Ica7ae52e563efb283c600c812be196951a12a336
Reviewed-on: https://chromium-review.googlesource.com/1065558
Commit-Queue: Tsuyoshi Horo <horo@chromium.org>
Reviewed-by: default avatarDmitry Gozman <dgozman@chromium.org>
Reviewed-by: default avatarKunihiko Sakamoto <ksakamoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#560287}
parent 07e3d0d9
...@@ -1588,12 +1588,17 @@ void NetworkHandler::NavigationRequestWillBeSent( ...@@ -1588,12 +1588,17 @@ void NetworkHandler::NavigationRequestWillBeSent(
void NetworkHandler::RequestSent(const std::string& request_id, void NetworkHandler::RequestSent(const std::string& request_id,
const std::string& loader_id, const std::string& loader_id,
const network::ResourceRequest& request, const network::ResourceRequest& request,
const char* initiator_type) { const char* initiator_type,
const base::Optional<GURL>& initiator_url) {
if (!enabled_) if (!enabled_)
return; return;
std::unique_ptr<DictionaryValue> headers_dict(DictionaryValue::create()); std::unique_ptr<DictionaryValue> headers_dict(DictionaryValue::create());
for (net::HttpRequestHeaders::Iterator it(request.headers); it.GetNext();) for (net::HttpRequestHeaders::Iterator it(request.headers); it.GetNext();)
headers_dict->setString(it.name(), it.value()); headers_dict->setString(it.name(), it.value());
std::unique_ptr<Network::Initiator> initiator =
Network::Initiator::Create().SetType(initiator_type).Build();
if (initiator_url)
initiator->SetUrl(initiator_url->spec());
frontend_->RequestWillBeSent( frontend_->RequestWillBeSent(
request_id, loader_id, StripFragment(request.url), request_id, loader_id, StripFragment(request.url),
Network::Request::Create() Network::Request::Create()
...@@ -1605,8 +1610,7 @@ void NetworkHandler::RequestSent(const std::string& request_id, ...@@ -1605,8 +1610,7 @@ void NetworkHandler::RequestSent(const std::string& request_id,
.Build(), .Build(),
base::TimeTicks::Now().ToInternalValue() / base::TimeTicks::Now().ToInternalValue() /
static_cast<double>(base::Time::kMicrosecondsPerSecond), static_cast<double>(base::Time::kMicrosecondsPerSecond),
base::Time::Now().ToDoubleT(), base::Time::Now().ToDoubleT(), std::move(initiator),
Network::Initiator::Create().SetType(initiator_type).Build(),
std::unique_ptr<Network::Response>(), std::unique_ptr<Network::Response>(),
std::string(Page::ResourceTypeEnum::Other), std::string(Page::ResourceTypeEnum::Other),
Maybe<std::string>() /* frame_id */, request.has_user_gesture); Maybe<std::string>() /* frame_id */, request.has_user_gesture);
......
...@@ -149,7 +149,8 @@ class NetworkHandler : public DevToolsDomainHandler, ...@@ -149,7 +149,8 @@ class NetworkHandler : public DevToolsDomainHandler,
void RequestSent(const std::string& request_id, void RequestSent(const std::string& request_id,
const std::string& loader_id, const std::string& loader_id,
const network::ResourceRequest& request, const network::ResourceRequest& request,
const char* initiator_type); const char* initiator_type,
const base::Optional<GURL>& initiator_url);
void ResponseReceived(const std::string& request_id, void ResponseReceived(const std::string& request_id,
const std::string& loader_id, const std::string& loader_id,
const GURL& url, const GURL& url,
......
...@@ -244,10 +244,12 @@ void RenderFrameDevToolsAgentHost::OnSignedExchangeCertificateRequestSent( ...@@ -244,10 +244,12 @@ void RenderFrameDevToolsAgentHost::OnSignedExchangeCertificateRequestSent(
FrameTreeNode* frame_tree_node, FrameTreeNode* frame_tree_node,
const base::UnguessableToken& request_id, const base::UnguessableToken& request_id,
const base::UnguessableToken& loader_id, const base::UnguessableToken& loader_id,
const network::ResourceRequest& request) { const network::ResourceRequest& request,
const GURL& signed_exchange_url) {
DispatchToAgents(frame_tree_node, &protocol::NetworkHandler::RequestSent, DispatchToAgents(frame_tree_node, &protocol::NetworkHandler::RequestSent,
request_id.ToString(), loader_id.ToString(), request, request_id.ToString(), loader_id.ToString(), request,
protocol::Network::Initiator::TypeEnum::Other); protocol::Network::Initiator::TypeEnum::SignedExchange,
signed_exchange_url);
} }
// static // static
......
...@@ -108,7 +108,8 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost ...@@ -108,7 +108,8 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
FrameTreeNode* frame_tree_node, FrameTreeNode* frame_tree_node,
const base::UnguessableToken& request_id, const base::UnguessableToken& request_id,
const base::UnguessableToken& loader_id, const base::UnguessableToken& loader_id,
const network::ResourceRequest& request); const network::ResourceRequest& request,
const GURL& signed_exchange_url);
static void OnSignedExchangeCertificateResponseReceived( static void OnSignedExchangeCertificateResponseReceived(
FrameTreeNode* frame_tree_node, FrameTreeNode* frame_tree_node,
const base::UnguessableToken& request_id, const base::UnguessableToken& request_id,
......
...@@ -188,7 +188,8 @@ void ServiceWorkerDevToolsManager::NavigationPreloadRequestSent( ...@@ -188,7 +188,8 @@ void ServiceWorkerDevToolsManager::NavigationPreloadRequestSent(
for (auto* network : for (auto* network :
protocol::NetworkHandler::ForAgentHost(it->second.get())) { protocol::NetworkHandler::ForAgentHost(it->second.get())) {
network->RequestSent(request_id, std::string(), request, network->RequestSent(request_id, std::string(), request,
protocol::Network::Initiator::TypeEnum::Preload); protocol::Network::Initiator::TypeEnum::Preload,
base::nullopt /* initiator_url */);
} }
} }
......
...@@ -32,13 +32,14 @@ void CertificateRequestSentOnUI( ...@@ -32,13 +32,14 @@ void CertificateRequestSentOnUI(
base::RepeatingCallback<int(void)> frame_tree_node_id_getter, base::RepeatingCallback<int(void)> frame_tree_node_id_getter,
const base::UnguessableToken& request_id, const base::UnguessableToken& request_id,
const base::UnguessableToken& loader_id, const base::UnguessableToken& loader_id,
const network::ResourceRequest& request) { const network::ResourceRequest& request,
const GURL& signed_exchange_url) {
FrameTreeNode* frame_tree_node = FrameTreeNode* frame_tree_node =
FrameTreeNode::GloballyFindByID(frame_tree_node_id_getter.Run()); FrameTreeNode::GloballyFindByID(frame_tree_node_id_getter.Run());
if (!frame_tree_node) if (!frame_tree_node)
return; return;
RenderFrameDevToolsAgentHost::OnSignedExchangeCertificateRequestSent( RenderFrameDevToolsAgentHost::OnSignedExchangeCertificateRequestSent(
frame_tree_node, request_id, loader_id, request); frame_tree_node, request_id, loader_id, request, signed_exchange_url);
} }
void CertificateResponseReceivedOnUI( void CertificateResponseReceivedOnUI(
...@@ -125,7 +126,7 @@ void SignedExchangeDevToolsProxy::CertificateRequestSent( ...@@ -125,7 +126,7 @@ void SignedExchangeDevToolsProxy::CertificateRequestSent(
base::BindOnce( base::BindOnce(
&CertificateRequestSentOnUI, frame_tree_node_id_getter_, request_id, &CertificateRequestSentOnUI, frame_tree_node_id_getter_, request_id,
devtools_navigation_token_ ? *devtools_navigation_token_ : request_id, devtools_navigation_token_ ? *devtools_navigation_token_ : request_id,
request)); request, outer_request_url_));
} }
void SignedExchangeDevToolsProxy::CertificateResponseReceived( void SignedExchangeDevToolsProxy::CertificateResponseReceived(
......
...@@ -3542,10 +3542,11 @@ domain Network ...@@ -3542,10 +3542,11 @@ domain Network
parser parser
script script
preload preload
SignedExchange
other other
# Initiator JavaScript stack trace, set for Script only. # Initiator JavaScript stack trace, set for Script only.
optional Runtime.StackTrace stack optional Runtime.StackTrace stack
# Initiator URL, set for Parser type or for Script type (when script is importing module). # Initiator URL, set for Parser type or for Script type (when script is importing module) or for SignedExchange type.
optional string url optional string url
# Initiator line number, set for Parser type or for Script type (when script is importing # Initiator line number, set for Parser type or for Script type (when script is importing
# module) (0-based). # module) (0-based).
......
...@@ -209,6 +209,9 @@ BrowserSDK.NetworkLog = class extends Common.Object { ...@@ -209,6 +209,9 @@ BrowserSDK.NetworkLog = class extends Common.Object {
initiatorStack = initiator.stack || null; initiatorStack = initiator.stack || null;
} else if (initiator.type === Protocol.Network.InitiatorType.Preload) { } else if (initiator.type === Protocol.Network.InitiatorType.Preload) {
type = SDK.NetworkRequest.InitiatorType.Preload; type = SDK.NetworkRequest.InitiatorType.Preload;
} else if (initiator.type === Protocol.Network.InitiatorType.SignedExchange) {
type = SDK.NetworkRequest.InitiatorType.SignedExchange;
url = initiator.url;
} }
} }
......
...@@ -932,6 +932,11 @@ Network.NetworkRequestNode = class extends Network.NetworkNode { ...@@ -932,6 +932,11 @@ Network.NetworkRequestNode = class extends Network.NetworkNode {
cell.appendChild(createTextNode(Common.UIString('Preload'))); cell.appendChild(createTextNode(Common.UIString('Preload')));
break; break;
case SDK.NetworkRequest.InitiatorType.SignedExchange:
cell.appendChild(Components.Linkifier.linkifyURL(initiator.url));
this._appendSubtitle(cell, Common.UIString('signed-exchange'));
break;
default: default:
cell.title = Common.UIString('Other'); cell.title = Common.UIString('Other');
cell.classList.add('network-dim-cell'); cell.classList.add('network-dim-cell');
...@@ -947,7 +952,7 @@ Network.NetworkRequestNode = class extends Network.NetworkNode { ...@@ -947,7 +952,7 @@ Network.NetworkRequestNode = class extends Network.NetworkNode {
this._setTextAndTitle(cell, Common.UIString('(from ServiceWorker)')); this._setTextAndTitle(cell, Common.UIString('(from ServiceWorker)'));
cell.classList.add('network-dim-cell'); cell.classList.add('network-dim-cell');
} else if (this._request.redirectSource() && this._request.redirectSource().signedExchangeInfo()) { } else if (this._request.redirectSource() && this._request.redirectSource().signedExchangeInfo()) {
this._setTextAndTitle(cell, Common.UIString('(from SignedExchange)')); this._setTextAndTitle(cell, Common.UIString('(from signed-exchange)'));
cell.classList.add('network-dim-cell'); cell.classList.add('network-dim-cell');
} else if (this._request.cached()) { } else if (this._request.cached()) {
if (this._request.cachedInMemory()) if (this._request.cachedInMemory())
......
...@@ -396,6 +396,9 @@ Network.RequestHeadersView = class extends UI.VBox { ...@@ -396,6 +396,9 @@ Network.RequestHeadersView = class extends UI.VBox {
if (this._request.fetchedViaServiceWorker) { if (this._request.fetchedViaServiceWorker) {
statusText += ' ' + Common.UIString('(from ServiceWorker)'); statusText += ' ' + Common.UIString('(from ServiceWorker)');
statusTextElement.classList.add('status-from-cache'); statusTextElement.classList.add('status-from-cache');
} else if (this._request.redirectSource() && this._request.redirectSource().signedExchangeInfo()) {
statusText += ' ' + Common.UIString('(from signed-exchange)');
statusTextElement.classList.add('status-from-cache');
} else if (this._request.cached()) { } else if (this._request.cached()) {
if (this._request.cachedInMemory()) if (this._request.cachedInMemory())
statusText += ' ' + Common.UIString('(from memory cache)'); statusText += ' ' + Common.UIString('(from memory cache)');
......
...@@ -79,9 +79,8 @@ Network.RequestPreviewView = class extends Network.RequestResponseView { ...@@ -79,9 +79,8 @@ Network.RequestPreviewView = class extends Network.RequestResponseView {
* @return {!Promise<!UI.Widget>} * @return {!Promise<!UI.Widget>}
*/ */
async createPreview() { async createPreview() {
const signedExchangeInfo = this.request.signedExchangeInfo(); if (this.request.signedExchangeInfo())
if (signedExchangeInfo) return new Network.SignedExchangeInfoView(this.request);
return new Network.SignedExchangeInfoView(signedExchangeInfo);
const htmlErrorPreview = await this._htmlPreview(); const htmlErrorPreview = await this._htmlPreview();
if (htmlErrorPreview) if (htmlErrorPreview)
......
...@@ -4,10 +4,13 @@ ...@@ -4,10 +4,13 @@
Network.SignedExchangeInfoView = class extends UI.VBox { Network.SignedExchangeInfoView = class extends UI.VBox {
/** /**
* @param {!Protocol.Network.SignedExchangeInfo} signedExchangeInfo * @param {!SDK.NetworkRequest} request
*/ */
constructor(signedExchangeInfo) { constructor(request) {
super(); super();
const signedExchangeInfo = request.signedExchangeInfo();
console.assert(signedExchangeInfo);
this.registerRequiredCSS('network/signedExchangeInfoView.css'); this.registerRequiredCSS('network/signedExchangeInfoView.css');
this.element.classList.add('signed-exchange-info-view'); this.element.classList.add('signed-exchange-info-view');
...@@ -30,8 +33,21 @@ Network.SignedExchangeInfoView = class extends UI.VBox { ...@@ -30,8 +33,21 @@ Network.SignedExchangeInfoView = class extends UI.VBox {
} }
if (signedExchangeInfo.header) { if (signedExchangeInfo.header) {
const header = signedExchangeInfo.header; const header = signedExchangeInfo.header;
const headerCategory = new Network.SignedExchangeInfoView.Category(root, Common.UIString('Signed HTTP exchange')); const titleElement = createDocumentFragment();
headerCategory.createLeaf(this._formatHeader(Common.UIString('Request URL'), header.requestUrl)); titleElement.createChild('div', 'header-name').textContent = Common.UIString('Signed HTTP exchange');
const learnMoreNode =
UI.XLink.create('https://github.com/WICG/webpackage', Common.UIString('Learn\xa0more'), 'header-toggle');
titleElement.appendChild(learnMoreNode);
const headerCategory = new Network.SignedExchangeInfoView.Category(root, titleElement);
const redirectDestination = request.redirectDestination();
const requestURLElement = this._formatHeader(Common.UIString('Request URL'), header.requestUrl);
if (redirectDestination) {
const viewRequestLink = Components.Linkifier.linkifyRevealable(redirectDestination, 'View request');
viewRequestLink.classList.add('header-toggle');
requestURLElement.appendChild(viewRequestLink);
}
headerCategory.createLeaf(requestURLElement);
headerCategory.createLeaf(this._formatHeader(Common.UIString('Request method'), header.requestMethod)); headerCategory.createLeaf(this._formatHeader(Common.UIString('Request method'), header.requestMethod));
headerCategory.createLeaf(this._formatHeader(Common.UIString('Response code'), header.responseCode + '')); headerCategory.createLeaf(this._formatHeader(Common.UIString('Response code'), header.responseCode + ''));
...@@ -90,7 +106,7 @@ Network.SignedExchangeInfoView = class extends UI.VBox { ...@@ -90,7 +106,7 @@ Network.SignedExchangeInfoView = class extends UI.VBox {
Network.SignedExchangeInfoView.Category = class extends UI.TreeElement { Network.SignedExchangeInfoView.Category = class extends UI.TreeElement {
/** /**
* @param {!UI.TreeOutline} root * @param {!UI.TreeOutline} root
* @param {string} title * @param {(string|!Node)=} title
*/ */
constructor(root, title) { constructor(root, title) {
super(title, true); super(title, true);
......
...@@ -59,6 +59,18 @@ ...@@ -59,6 +59,18 @@
margin-top: 1px; margin-top: 1px;
} }
.tree-outline .header-toggle {
display: inline;
margin-left: 30px;
font-weight: normal;
color: rgb(45%, 45%, 45%);
}
.tree-outline .header-toggle:hover {
color: rgb(20%, 20%, 45%);
cursor: pointer;
}
.tree-outline .error-log { .tree-outline .error-log {
color: red; color: red;
display: inline-block; display: inline-block;
......
...@@ -786,6 +786,7 @@ SDK.NetworkDispatcher = class { ...@@ -786,6 +786,7 @@ SDK.NetworkDispatcher = class {
requestId, originalNetworkRequest.frameId, originalNetworkRequest.loaderId, redirectURL, requestId, originalNetworkRequest.frameId, originalNetworkRequest.loaderId, redirectURL,
originalNetworkRequest.documentURL, originalNetworkRequest.initiator()); originalNetworkRequest.documentURL, originalNetworkRequest.initiator());
newNetworkRequest.setRedirectSource(originalNetworkRequest); newNetworkRequest.setRedirectSource(originalNetworkRequest);
originalNetworkRequest.setRedirectDestination(newNetworkRequest);
return newNetworkRequest; return newNetworkRequest;
} }
......
...@@ -53,6 +53,8 @@ SDK.NetworkRequest = class extends Common.Object { ...@@ -53,6 +53,8 @@ SDK.NetworkRequest = class extends Common.Object {
this._initiator = initiator; this._initiator = initiator;
/** @type {?SDK.NetworkRequest} */ /** @type {?SDK.NetworkRequest} */
this._redirectSource = null; this._redirectSource = null;
/** @type {?SDK.NetworkRequest} */
this._redirectDestination = null;
this._issueTime = -1; this._issueTime = -1;
this._startTime = -1; this._startTime = -1;
this._endTime = -1; this._endTime = -1;
...@@ -622,6 +624,20 @@ SDK.NetworkRequest = class extends Common.Object { ...@@ -622,6 +624,20 @@ SDK.NetworkRequest = class extends Common.Object {
this._redirectSource = originatingRequest; this._redirectSource = originatingRequest;
} }
/**
* @return {?SDK.NetworkRequest}
*/
redirectDestination() {
return this._redirectDestination;
}
/**
* @param {?SDK.NetworkRequest} redirectDestination
*/
setRedirectDestination(redirectDestination) {
this._redirectDestination = redirectDestination;
}
/** /**
* @return {!Array.<!SDK.NetworkRequest.NameValue>} * @return {!Array.<!SDK.NetworkRequest.NameValue>}
*/ */
...@@ -1167,7 +1183,8 @@ SDK.NetworkRequest.InitiatorType = { ...@@ -1167,7 +1183,8 @@ SDK.NetworkRequest.InitiatorType = {
Parser: 'parser', Parser: 'parser',
Redirect: 'redirect', Redirect: 'redirect',
Script: 'script', Script: 'script',
Preload: 'preload' Preload: 'preload',
SignedExchange: 'signedExchange'
}; };
/** @typedef {!{name: string, value: string}} */ /** @typedef {!{name: string, value: string}} */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment