blob: b43edc2af8ef8bf794453ebfe875e204d2c478d5 [file] [log] [blame]
Wolfgang Beyer40530b682022-05-17 13:02:011// Copyright 2022 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import * as Common from '../../../core/common/common.js';
Wolfgang Beyer7f495ee2022-07-08 13:45:136import * as Host from '../../../core/host/host.js';
Wolfgang Beyer40530b682022-05-17 13:02:017import * as i18n from '../../../core/i18n/i18n.js';
Wolfgang Beyer7f495ee2022-07-08 13:45:138import * as Platform from '../../../core/platform/platform.js';
Wolfgang Beyer185fb1f2022-08-01 13:48:259import * as Root from '../../../core/root/root.js';
Wolfgang Beyer40530b682022-05-17 13:02:0110import * as SDK from '../../../core/sdk/sdk.js';
Wolfgang Beyer7f495ee2022-07-08 13:45:1311import * as Protocol from '../../../generated/protocol.js';
12import * as IssuesManager from '../../../models/issues_manager/issues_manager.js';
Wolfgang Beyer185fb1f2022-08-01 13:48:2513import * as Persistence from '../../../models/persistence/persistence.js';
14import * as Workspace from '../../../models/workspace/workspace.js';
Wolfgang Beyerbcf4a832022-07-25 12:34:4715import * as ClientVariations from '../../../third_party/chromium/client-variations/client-variations.js';
Wolfgang Beyerd1dd7962022-05-24 15:48:4816import * as Buttons from '../../../ui/components/buttons/buttons.js';
Wolfgang Beyer40530b682022-05-17 13:02:0117import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js';
Wolfgang Beyer7f495ee2022-07-08 13:45:1318import * as IconButton from '../../../ui/components/icon_button/icon_button.js';
Jack Franklin1f19d522022-07-06 14:00:1819import * as Input from '../../../ui/components/input/input.js';
Wolfgang Beyer40530b682022-05-17 13:02:0120import * as UI from '../../../ui/legacy/legacy.js';
21import * as LitHtml from '../../../ui/lit-html/lit-html.js';
Wolfgang Beyer185fb1f2022-08-01 13:48:2522import * as Sources from '../../sources/sources.js';
Wolfgang Beyer40530b682022-05-17 13:02:0123
24import requestHeadersViewStyles from './RequestHeadersView.css.js';
25
Wolfgang Beyerd1dd7962022-05-24 15:48:4826const RAW_HEADER_CUTOFF = 3000;
Wolfgang Beyer40530b682022-05-17 13:02:0127const {render, html} = LitHtml;
28
29const UIStrings = {
30 /**
Wolfgang Beyerbcf4a832022-07-25 12:34:4731 *@description Comment used in decoded X-Client-Data HTTP header output in Headers View of the Network panel
32 */
33 activeClientExperimentVariation: 'Active `client experiment variation IDs`.',
34 /**
35 *@description Comment used in decoded X-Client-Data HTTP header output in Headers View of the Network panel
36 */
37 activeClientExperimentVariationIds: 'Active `client experiment variation IDs` that trigger server-side behavior.',
38 /**
Wolfgang Beyer7f495ee2022-07-08 13:45:1339 *@description Text in Headers View of the Network panel
40 */
41 chooseThisOptionIfTheResourceAnd:
42 'Choose this option if the resource and the document are served from the same site.',
43 /**
Wolfgang Beyerbcf4a832022-07-25 12:34:4744 *@description Text in Headers View of the Network panel for X-Client-Data HTTP headers
45 */
46 decoded: 'Decoded:',
47 /**
Wolfgang Beyer40530b682022-05-17 13:02:0148 *@description Text in Request Headers View of the Network panel
49 */
Wolfgang Beyer37fcd282022-06-29 09:34:1750 fromDiskCache: '(from disk cache)',
51 /**
52 *@description Text in Request Headers View of the Network panel
53 */
Wolfgang Beyer40530b682022-05-17 13:02:0154 fromMemoryCache: '(from memory cache)',
55 /**
56 *@description Text in Request Headers View of the Network panel
57 */
Wolfgang Beyer37fcd282022-06-29 09:34:1758 fromPrefetchCache: '(from prefetch cache)',
59 /**
60 *@description Text in Request Headers View of the Network panel
61 */
Wolfgang Beyer40530b682022-05-17 13:02:0162 fromServiceWorker: '(from `service worker`)',
63 /**
64 *@description Text in Request Headers View of the Network panel
65 */
66 fromSignedexchange: '(from signed-exchange)',
67 /**
68 *@description Text in Request Headers View of the Network panel
69 */
Wolfgang Beyer40530b682022-05-17 13:02:0170 fromWebBundle: '(from Web Bundle)',
71 /**
72 *@description Section header for a list of the main aspects of a http request
73 */
74 general: 'General',
75 /**
Wolfgang Beyer185fb1f2022-08-01 13:48:2576 *@description Label for a link from the network panel's headers view to the file in which
77 * header overrides are defined in the sources panel.
78 */
79 headerOverrides: 'Header overrides',
80 /**
Wolfgang Beyer7f495ee2022-07-08 13:45:1381 *@description Text that is usually a hyperlink to more documentation
82 */
83 learnMore: 'Learn more',
84 /**
85 *@description Text for a link to the issues panel
86 */
87 learnMoreInTheIssuesTab: 'Learn more in the issues tab',
88 /**
Wolfgang Beyer235544c2022-05-24 08:07:4589 *@description Label for a checkbox to switch between raw and parsed headers
90 */
91 raw: 'Raw',
92 /**
Wolfgang Beyer7f495ee2022-07-08 13:45:1393 *@description Text in Headers View of the Network panel
94 */
95 onlyChooseThisOptionIfAn:
96 'Only choose this option if an arbitrary website including this resource does not impose a security risk.',
97 /**
Wolfgang Beyerd0ab3a62022-07-12 12:59:0298 *@description Message to explain lack of raw headers for a particular network request
99 */
100 provisionalHeadersAreShownDisableCache: 'Provisional headers are shown. Disable cache to see full headers.',
101 /**
102 *@description Tooltip to explain lack of raw headers for a particular network request
103 */
104 onlyProvisionalHeadersAre:
105 'Only provisional headers are available because this request was not sent over the network and instead was served from a local cache, which doesn’t store the original request headers. Disable cache to see full request headers.',
106 /**
107 *@description Message to explain lack of raw headers for a particular network request
108 */
109 provisionalHeadersAreShown: 'Provisional headers are shown.',
110 /**
Wolfgang Beyer235544c2022-05-24 08:07:45111 *@description Text in Request Headers View of the Network panel
112 */
Wolfgang Beyer37fcd282022-06-29 09:34:17113 referrerPolicy: 'Referrer Policy',
Wolfgang Beyer235544c2022-05-24 08:07:45114 /**
Wolfgang Beyer37fcd282022-06-29 09:34:17115 *@description Text in Network Log View Columns of the Network panel
Wolfgang Beyer40530b682022-05-17 13:02:01116 */
Wolfgang Beyer37fcd282022-06-29 09:34:17117 remoteAddress: 'Remote Address',
118 /**
119 *@description Text in Request Headers View of the Network panel
120 */
121 requestHeaders: 'Request Headers',
Wolfgang Beyer40530b682022-05-17 13:02:01122 /**
123 *@description The HTTP method of a request
124 */
125 requestMethod: 'Request Method',
126 /**
Wolfgang Beyer37fcd282022-06-29 09:34:17127 *@description The URL of a request
128 */
129 requestUrl: 'Request URL',
130 /**
Wolfgang Beyer235544c2022-05-24 08:07:45131 *@description A context menu item in the Network Log View Columns of the Network panel
132 */
133 responseHeaders: 'Response Headers',
134 /**
Wolfgang Beyerd1dd7962022-05-24 15:48:48135 *@description Text to show more content
136 */
137 showMore: 'Show more',
138 /**
Wolfgang Beyer40530b682022-05-17 13:02:01139 *@description HTTP response code
140 */
141 statusCode: 'Status Code',
Wolfgang Beyer7f495ee2022-07-08 13:45:13142 /**
143 *@description Text in Headers View of the Network panel
144 */
145 thisDocumentWasBlockedFrom:
146 'This document was blocked from loading in an `iframe` with a `sandbox` attribute because this document specified a cross-origin opener policy.',
147 /**
148 *@description Text in Headers View of the Network panel
149 */
150 toEmbedThisFrameInYourDocument:
151 'To embed this frame in your document, the response needs to enable the cross-origin embedder policy by specifying the following response header:',
152 /**
153 *@description Text in Headers View of the Network panel
154 */
155 toUseThisResourceFromADifferent:
156 'To use this resource from a different origin, the server needs to specify a cross-origin resource policy in the response headers:',
157 /**
158 *@description Text in Headers View of the Network panel
159 */
160 toUseThisResourceFromADifferentOrigin:
161 'To use this resource from a different origin, the server may relax the cross-origin resource policy response header:',
162 /**
163 *@description Text in Headers View of the Network panel
164 */
165 toUseThisResourceFromADifferentSite:
166 'To use this resource from a different site, the server may relax the cross-origin resource policy response header:',
Wolfgang Beyer40530b682022-05-17 13:02:01167};
168const str_ = i18n.i18n.registerUIStrings('panels/network/components/RequestHeadersView.ts', UIStrings);
169const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
Wolfgang Beyer7f495ee2022-07-08 13:45:13170const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);
Wolfgang Beyer40530b682022-05-17 13:02:01171
172export class RequestHeadersView extends UI.Widget.VBox {
173 readonly #headersView = new RequestHeadersComponent();
174 readonly #request: SDK.NetworkRequest.NetworkRequest;
175
176 constructor(request: SDK.NetworkRequest.NetworkRequest) {
177 super();
178 this.#request = request;
179 this.contentElement.appendChild(this.#headersView);
180 }
181
182 wasShown(): void {
183 this.#request.addEventListener(SDK.NetworkRequest.Events.RemoteAddressChanged, this.#refreshHeadersView, this);
184 this.#request.addEventListener(SDK.NetworkRequest.Events.FinishedLoading, this.#refreshHeadersView, this);
Wolfgang Beyer87150062022-07-29 10:45:47185 this.#request.addEventListener(SDK.NetworkRequest.Events.RequestHeadersChanged, this.#refreshHeadersView, this);
186 this.#request.addEventListener(SDK.NetworkRequest.Events.ResponseHeadersChanged, this.#refreshHeadersView, this);
Wolfgang Beyer40530b682022-05-17 13:02:01187 this.#refreshHeadersView();
188 }
189
190 willHide(): void {
191 this.#request.removeEventListener(SDK.NetworkRequest.Events.RemoteAddressChanged, this.#refreshHeadersView, this);
192 this.#request.removeEventListener(SDK.NetworkRequest.Events.FinishedLoading, this.#refreshHeadersView, this);
Wolfgang Beyer87150062022-07-29 10:45:47193 this.#request.removeEventListener(SDK.NetworkRequest.Events.RequestHeadersChanged, this.#refreshHeadersView, this);
194 this.#request.removeEventListener(SDK.NetworkRequest.Events.ResponseHeadersChanged, this.#refreshHeadersView, this);
Wolfgang Beyer40530b682022-05-17 13:02:01195 }
196
197 #refreshHeadersView(): void {
198 this.#headersView.data = {
199 request: this.#request,
200 };
201 }
202}
203
204export interface RequestHeadersComponentData {
205 request: SDK.NetworkRequest.NetworkRequest;
206}
207
208export class RequestHeadersComponent extends HTMLElement {
209 static readonly litTagName = LitHtml.literal`devtools-request-headers`;
210 readonly #shadow = this.attachShadow({mode: 'open'});
211 #request?: Readonly<SDK.NetworkRequest.NetworkRequest>;
Wolfgang Beyer235544c2022-05-24 08:07:45212 #showResponseHeadersText = false;
213 #showRequestHeadersText = false;
Wolfgang Beyerd1dd7962022-05-24 15:48:48214 #showResponseHeadersTextFull = false;
215 #showRequestHeadersTextFull = false;
Wolfgang Beyer185fb1f2022-08-01 13:48:25216 readonly #workspace = Workspace.Workspace.WorkspaceImpl.instance();
Wolfgang Beyer40530b682022-05-17 13:02:01217
218 set data(data: RequestHeadersComponentData) {
219 this.#request = data.request;
220 this.#render();
221 }
222
223 connectedCallback(): void {
224 this.#shadow.adoptedStyleSheets = [requestHeadersViewStyles];
Wolfgang Beyer185fb1f2022-08-01 13:48:25225 this.#workspace.addEventListener(
226 Workspace.Workspace.Events.UISourceCodeAdded, this.#uiSourceCodeAddedOrRemoved, this);
227 this.#workspace.addEventListener(
228 Workspace.Workspace.Events.UISourceCodeRemoved, this.#uiSourceCodeAddedOrRemoved, this);
229 }
230
231 disconnectedCallback(): void {
232 this.#workspace.removeEventListener(
233 Workspace.Workspace.Events.UISourceCodeAdded, this.#uiSourceCodeAddedOrRemoved, this);
234 this.#workspace.removeEventListener(
235 Workspace.Workspace.Events.UISourceCodeRemoved, this.#uiSourceCodeAddedOrRemoved, this);
236 }
237
238 #uiSourceCodeAddedOrRemoved(event: Common.EventTarget.EventTargetEvent<Workspace.UISourceCode.UISourceCode>): void {
239 if (this.#getHeaderOverridesFileUrl() === event.data.url()) {
240 this.#render();
241 }
Wolfgang Beyer40530b682022-05-17 13:02:01242 }
243
244 #render(): void {
Wolfgang Beyer3e62bd72022-07-28 14:26:48245 if (!this.#request) {
246 return;
247 }
Wolfgang Beyer40530b682022-05-17 13:02:01248
249 // Disabled until https://crbug.com/1079231 is fixed.
250 // clang-format off
251 render(html`
252 ${this.#renderGeneralSection()}
Wolfgang Beyer235544c2022-05-24 08:07:45253 ${this.#renderResponseHeaders()}
254 ${this.#renderRequestHeaders()}
Wolfgang Beyer40530b682022-05-17 13:02:01255 `, this.#shadow, {host: this});
256 // clang-format on
257 }
258
Wolfgang Beyer3e62bd72022-07-28 14:26:48259 #renderResponseHeaders(): LitHtml.LitTemplate {
260 if (!this.#request) {
261 return LitHtml.nothing;
262 }
Wolfgang Beyer235544c2022-05-24 08:07:45263
Wolfgang Beyer7f495ee2022-07-08 13:45:13264 const headersWithIssues = [];
265 if (this.#request.wasBlocked()) {
266 const headerWithIssues =
267 BlockedReasonDetails.get((this.#request.blockedReason() as Protocol.Network.BlockedReason));
268 if (headerWithIssues) {
269 headersWithIssues.push(headerWithIssues);
270 }
271 }
272
273 function mergeHeadersWithIssues(
274 headers: SDK.NetworkRequest.NameValue[], headersWithIssues: HeaderDescriptor[]): HeaderDescriptor[] {
275 let i = 0, j = 0;
276 const result: HeaderDescriptor[] = [];
277 while (i < headers.length && j < headersWithIssues.length) {
278 if (headers[i].name < headersWithIssues[j].name) {
279 result.push({...headers[i++], headerNotSet: false});
280 } else if (headers[i].name > headersWithIssues[j].name) {
281 result.push({...headersWithIssues[j++], headerNotSet: true});
282 } else {
283 result.push({...headersWithIssues[j++], ...headers[i++], headerNotSet: false});
284 }
285 }
286 while (i < headers.length) {
287 result.push({...headers[i++], headerNotSet: false});
288 }
289 while (j < headersWithIssues.length) {
290 result.push({...headersWithIssues[j++], headerNotSet: true});
291 }
292 return result;
293 }
294
295 const mergedHeaders = mergeHeadersWithIssues(this.#request.sortedResponseHeaders.slice(), headersWithIssues);
296
Wolfgang Beyer21894d52022-07-26 12:12:44297 const blockedResponseCookies = this.#request.blockedResponseCookies();
298 const blockedCookieLineToReasons = new Map<string, Protocol.Network.SetCookieBlockedReason[]>(
299 blockedResponseCookies?.map(c => [c.cookieLine, c.blockedReasons]));
300 for (const header of mergedHeaders) {
301 if (header.name.toLowerCase() === 'set-cookie' && header.value) {
302 const matchingBlockedReasons = blockedCookieLineToReasons.get(header.value.toString());
303 if (matchingBlockedReasons) {
304 header.setCookieBlockedReasons = matchingBlockedReasons;
305 }
306 }
307 }
308
Wolfgang Beyer235544c2022-05-24 08:07:45309 const toggleShowRaw = (): void => {
310 this.#showResponseHeadersText = !this.#showResponseHeadersText;
311 this.#render();
312 };
313
314 // Disabled until https://crbug.com/1079231 is fixed.
315 // clang-format off
316 return html`
317 <${Category.litTagName}
318 @togglerawevent=${toggleShowRaw}
319 .data=${{
320 name: 'responseHeaders',
321 title: i18nString(UIStrings.responseHeaders),
322 headerCount: this.#request.sortedResponseHeaders.length,
323 checked: this.#request.responseHeadersText ? this.#showResponseHeadersText : undefined,
Wolfgang Beyer185fb1f2022-08-01 13:48:25324 additionalContent: this.#renderHeaderOverridesLink(),
Wolfgang Beyer235544c2022-05-24 08:07:45325 } as CategoryData}
326 aria-label=${i18nString(UIStrings.responseHeaders)}
327 >
Wolfgang Beyerd1dd7962022-05-24 15:48:48328 ${this.#showResponseHeadersText ?
329 this.#renderRawHeaders(this.#request.responseHeadersText, true) : html`
Wolfgang Beyer7f495ee2022-07-08 13:45:13330 ${mergedHeaders.map(header => this.#renderHeader(header))}
Wolfgang Beyer235544c2022-05-24 08:07:45331 `}
332 </${Category.litTagName}>
333 `;
Wolfgang Beyerbcf4a832022-07-25 12:34:47334 // clang-format on
Wolfgang Beyer235544c2022-05-24 08:07:45335 }
336
Wolfgang Beyer185fb1f2022-08-01 13:48:25337 #renderHeaderOverridesLink(): LitHtml.LitTemplate {
338 const overrideable = Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.HEADER_OVERRIDES);
339 if (!overrideable || !this.#workspace.uiSourceCodeForURL(this.#getHeaderOverridesFileUrl())) {
340 return LitHtml.nothing;
341 }
342
343 const overridesSetting: Common.Settings.Setting<boolean> =
344 Common.Settings.Settings.instance().moduleSetting('persistenceNetworkOverridesEnabled');
345 // Disabled until https://crbug.com/1079231 is fixed.
346 // clang-format off
347 const fileIcon = overridesSetting.get() ? html`
348 <${IconButton.Icon.Icon.litTagName} class="inline-icon purple-dot" .data=${{
349 iconName: 'file-sync_icon',
350 width: '11px',
351 height: '13px',
352 } as IconButton.Icon.IconData}>
353 </${IconButton.Icon.Icon.litTagName}>` : html`
354 <${IconButton.Icon.Icon.litTagName} class="inline-icon" .data=${{
355 iconName: 'file_icon',
356 color: 'var(--color-text-primary)',
357 width: '12px',
358 height: '12px',
359 } as IconButton.Icon.IconData}>
360 </${IconButton.Icon.Icon.litTagName}>`;
361 // clang-format on
362
363 const revealHeadersFile = (event: Event): void => {
364 event.preventDefault();
365 const uiSourceCode = this.#workspace.uiSourceCodeForURL(this.#getHeaderOverridesFileUrl());
366 if (uiSourceCode) {
367 Sources.SourcesPanel.SourcesPanel.instance().showUISourceCode(uiSourceCode);
368 }
369 };
370
371 return html`
372 <x-link @click=${revealHeadersFile} class="link devtools-link">
373 ${fileIcon}${i18nString(UIStrings.headerOverrides)}
374 </x-link>
375 `;
376 }
377
378 #getHeaderOverridesFileUrl(): Platform.DevToolsPath.UrlString {
379 if (!this.#request) {
380 return Platform.DevToolsPath.EmptyUrlString;
381 }
382 const fileUrl = Persistence.NetworkPersistenceManager.NetworkPersistenceManager.instance().fileUrlFromNetworkUrl(
383 this.#request.url(), /* ignoreInactive */ true);
384 return fileUrl.substring(0, fileUrl.lastIndexOf('/')) + '/' +
385 Persistence.NetworkPersistenceManager.HEADERS_FILENAME as Platform.DevToolsPath.UrlString;
386 }
387
Wolfgang Beyer3e62bd72022-07-28 14:26:48388 #renderRequestHeaders(): LitHtml.LitTemplate {
389 if (!this.#request) {
390 return LitHtml.nothing;
391 }
Wolfgang Beyer235544c2022-05-24 08:07:45392
Wolfgang Beyer7f495ee2022-07-08 13:45:13393 const headers = this.#request.requestHeaders().slice();
394 headers.sort(function(a, b) {
395 return Platform.StringUtilities.compare(a.name.toLowerCase(), b.name.toLowerCase());
396 });
397 const requestHeadersText = this.#request.requestHeadersText();
398
Wolfgang Beyer235544c2022-05-24 08:07:45399 const toggleShowRaw = (): void => {
400 this.#showRequestHeadersText = !this.#showRequestHeadersText;
401 this.#render();
402 };
403
Wolfgang Beyer235544c2022-05-24 08:07:45404 // Disabled until https://crbug.com/1079231 is fixed.
405 // clang-format off
406 return html`
407 <${Category.litTagName}
408 @togglerawevent=${toggleShowRaw}
409 .data=${{
410 name: 'requestHeaders',
411 title: i18nString(UIStrings.requestHeaders),
412 headerCount: this.#request.requestHeaders().length,
413 checked: requestHeadersText? this.#showRequestHeadersText : undefined,
414 } as CategoryData}
415 aria-label=${i18nString(UIStrings.requestHeaders)}
416 >
Wolfgang Beyerd1dd7962022-05-24 15:48:48417 ${(this.#showRequestHeadersText && requestHeadersText) ?
418 this.#renderRawHeaders(requestHeadersText, false) : html`
Wolfgang Beyerd0ab3a62022-07-12 12:59:02419 ${this.#maybeRenderProvisionalHeadersWarning()}
Wolfgang Beyer7f495ee2022-07-08 13:45:13420 ${headers.map(header => this.#renderHeader({...header, headerNotSet: false}))}
Wolfgang Beyer235544c2022-05-24 08:07:45421 `}
422 </${Category.litTagName}>
423 `;
Wolfgang Beyerbcf4a832022-07-25 12:34:47424 // clang-format on
Wolfgang Beyer235544c2022-05-24 08:07:45425 }
426
Wolfgang Beyerd0ab3a62022-07-12 12:59:02427 #maybeRenderProvisionalHeadersWarning(): LitHtml.LitTemplate {
Wolfgang Beyer3e62bd72022-07-28 14:26:48428 if (!this.#request || this.#request.requestHeadersText() !== undefined) {
Wolfgang Beyerd0ab3a62022-07-12 12:59:02429 return LitHtml.nothing;
430 }
431
432 let cautionText;
433 let cautionTitle = '';
434 if (this.#request.cachedInMemory() || this.#request.cached()) {
435 cautionText = i18nString(UIStrings.provisionalHeadersAreShownDisableCache);
436 cautionTitle = i18nString(UIStrings.onlyProvisionalHeadersAre);
437 } else {
438 cautionText = i18nString(UIStrings.provisionalHeadersAreShown);
439 }
Wolfgang Beyerb7dadd32022-07-27 12:34:52440 // Disabled until https://crbug.com/1079231 is fixed.
441 // clang-format off
Wolfgang Beyerd0ab3a62022-07-12 12:59:02442 return html`
443 <div class="call-to-action">
444 <div class="call-to-action-body">
445 <div class="explanation" title=${cautionTitle}>
446 <${IconButton.Icon.Icon.litTagName} class="inline-icon" .data=${{
Wolfgang Beyerb7dadd32022-07-27 12:34:52447 iconName: 'clear-warning_icon',
448 width: '12px',
449 height: '12px',
Wolfgang Beyerd0ab3a62022-07-12 12:59:02450 } as IconButton.Icon.IconData}>
451 </${IconButton.Icon.Icon.litTagName}>
452 ${cautionText} <x-link href="https://developer.chrome.com/docs/devtools/network/reference/#provisional-headers" class="link">${i18nString(UIStrings.learnMore)}</x-link>
453 </div>
454 </div>
455 </div>
456 `;
Wolfgang Beyerb7dadd32022-07-27 12:34:52457 // clang-format on
Wolfgang Beyerd0ab3a62022-07-12 12:59:02458 }
459
Wolfgang Beyer7f495ee2022-07-08 13:45:13460 #renderHeader(header: HeaderDescriptor): LitHtml.TemplateResult {
Wolfgang Beyerbcf4a832022-07-25 12:34:47461 // Disabled until https://crbug.com/1079231 is fixed.
462 // clang-format off
Wolfgang Beyer7f495ee2022-07-08 13:45:13463 return html`
464 <div class="row">
Wolfgang Beyerbcf4a832022-07-25 12:34:47465 <div class="header-name">
Wolfgang Beyerfccc2762022-07-27 12:03:09466 ${header.headerNotSet ?
467 html`<div class="header-badge header-badge-text">${i18n.i18n.lockedString('not-set')}</div>` :
468 LitHtml.nothing
469 }${header.name}:
Wolfgang Beyerbcf4a832022-07-25 12:34:47470 </div>
Wolfgang Beyerd815e1f2022-07-28 16:01:29471 <div
472 class="header-value ${header.headerValueIncorrect ? 'header-warning' : ''}"
473 @copy=${():void => Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue)}
474 >
Wolfgang Beyer21894d52022-07-26 12:12:44475 ${header.value?.toString() || ''}
476 ${this.#maybeRenderHeaderValueSuffix(header)}
477 </div>
Wolfgang Beyer7f495ee2022-07-08 13:45:13478 </div>
Wolfgang Beyer21894d52022-07-26 12:12:44479 ${this.#maybeRenderBlockedDetails(header.blockedDetails)}
Wolfgang Beyer7f495ee2022-07-08 13:45:13480 `;
Wolfgang Beyerbcf4a832022-07-25 12:34:47481 // clang-format on
482 }
483
Wolfgang Beyer21894d52022-07-26 12:12:44484 #maybeRenderHeaderValueSuffix(header: HeaderDescriptor): LitHtml.LitTemplate {
Wolfgang Beyerbcf4a832022-07-25 12:34:47485 const headerId = header.name.toLowerCase();
Wolfgang Beyer21894d52022-07-26 12:12:44486
487 if (headerId === 'set-cookie' && header.setCookieBlockedReasons) {
488 const titleText =
489 header.setCookieBlockedReasons.map(SDK.NetworkRequest.setCookieBlockedReasonToUiString).join('\n');
490 // Disabled until https://crbug.com/1079231 is fixed.
491 // clang-format off
492 return html`
493 <${IconButton.Icon.Icon.litTagName} class="inline-icon" title=${titleText} .data=${{
Wolfgang Beyerb7dadd32022-07-27 12:34:52494 iconName: 'clear-warning_icon',
495 width: '12px',
496 height: '12px',
497 } as IconButton.Icon.IconData}>
Wolfgang Beyer21894d52022-07-26 12:12:44498 </${IconButton.Icon.Icon.litTagName}>
499 `;
500 // clang-format on
501 }
502
Wolfgang Beyerbcf4a832022-07-25 12:34:47503 if (headerId === 'x-client-data') {
504 const data = ClientVariations.parseClientVariations(header.value?.toString() || '');
505 const output = ClientVariations.formatClientVariations(
506 data, i18nString(UIStrings.activeClientExperimentVariation),
507 i18nString(UIStrings.activeClientExperimentVariationIds));
508 return html`
Wolfgang Beyer21894d52022-07-26 12:12:44509 <div>${i18nString(UIStrings.decoded)}</div>
510 <code>${output}</code>
Wolfgang Beyerbcf4a832022-07-25 12:34:47511 `;
512 }
513
Wolfgang Beyer21894d52022-07-26 12:12:44514 return LitHtml.nothing;
Wolfgang Beyer7f495ee2022-07-08 13:45:13515 }
516
Wolfgang Beyer21894d52022-07-26 12:12:44517 #maybeRenderBlockedDetails(blockedDetails?: BlockedDetailsDescriptor): LitHtml.LitTemplate {
518 if (!blockedDetails) {
Wolfgang Beyer7f495ee2022-07-08 13:45:13519 return LitHtml.nothing;
520 }
Wolfgang Beyer21894d52022-07-26 12:12:44521 // Disabled until https://crbug.com/1079231 is fixed.
522 // clang-format off
Wolfgang Beyer7f495ee2022-07-08 13:45:13523 return html`
Wolfgang Beyerd0ab3a62022-07-12 12:59:02524 <div class="call-to-action">
525 <div class="call-to-action-body">
Wolfgang Beyer21894d52022-07-26 12:12:44526 <div class="explanation">${blockedDetails.explanation()}</div>
527 ${blockedDetails.examples.map(example => html`
Wolfgang Beyerd0ab3a62022-07-12 12:59:02528 <div class="example">
529 <code>${example.codeSnippet}</code>
530 ${example.comment ? html`
531 <span class="comment">${example.comment()}</span>
532 ` : ''}
533 </div>
534 `)}
Wolfgang Beyer21894d52022-07-26 12:12:44535 ${this.#maybeRenderBlockedDetailsLink(blockedDetails)}
Wolfgang Beyer7f495ee2022-07-08 13:45:13536 </div>
537 </div>
538 `;
Wolfgang Beyer21894d52022-07-26 12:12:44539 // clang-format on
Wolfgang Beyer7f495ee2022-07-08 13:45:13540 }
541
Wolfgang Beyer21894d52022-07-26 12:12:44542 #maybeRenderBlockedDetailsLink(blockedDetails?: BlockedDetailsDescriptor): LitHtml.LitTemplate {
Wolfgang Beyer7f495ee2022-07-08 13:45:13543 if (this.#request && IssuesManager.RelatedIssue.hasIssueOfCategory(this.#request, IssuesManager.Issue.IssueCategory.CrossOriginEmbedderPolicy)) {
544 const followLink = (): void => {
545 Host.userMetrics.issuesPanelOpenedFrom(Host.UserMetrics.IssueOpener.LearnMoreLinkCOEP);
546 if (this.#request) {
547 void IssuesManager.RelatedIssue.reveal(
548 this.#request, IssuesManager.Issue.IssueCategory.CrossOriginEmbedderPolicy);
549 }
550 };
551 return html`
552 <div class="devtools-link" @click=${followLink}>
553 <${IconButton.Icon.Icon.litTagName} class="inline-icon" .data=${{
554 iconName: 'issue-exclamation-icon',
555 color: 'var(--issue-color-yellow)',
556 width: '16px',
557 height: '16px',
558 } as IconButton.Icon.IconData}>
559 </${IconButton.Icon.Icon.litTagName}>
560 ${i18nString(UIStrings.learnMoreInTheIssuesTab)}
561 </div>
562 `;
563 }
Wolfgang Beyer21894d52022-07-26 12:12:44564 if (blockedDetails?.link) {
565 // Disabled until https://crbug.com/1079231 is fixed.
566 // clang-format off
Wolfgang Beyer7f495ee2022-07-08 13:45:13567 return html`
Wolfgang Beyer21894d52022-07-26 12:12:44568 <x-link href=${blockedDetails.link.url} class="link">
Wolfgang Beyer7f495ee2022-07-08 13:45:13569 <${IconButton.Icon.Icon.litTagName} class="inline-icon" .data=${{
570 iconName: 'link_icon',
571 color: 'var(--color-link)',
572 width: '16px',
573 height: '16px',
574 } as IconButton.Icon.IconData}>
575 </${IconButton.Icon.Icon.litTagName}
576 >${i18nString(UIStrings.learnMore)}
577 </x-link>
578 `;
Wolfgang Beyer21894d52022-07-26 12:12:44579 // clang-format on
Wolfgang Beyer7f495ee2022-07-08 13:45:13580 }
581 return LitHtml.nothing;
582 }
583
Wolfgang Beyerd1dd7962022-05-24 15:48:48584 #renderRawHeaders(rawHeadersText: string, forResponseHeaders: boolean): LitHtml.TemplateResult {
585 const trimmed = rawHeadersText.trim();
586 const showFull = forResponseHeaders ? this.#showResponseHeadersTextFull : this.#showRequestHeadersTextFull;
587 const isShortened = !showFull && trimmed.length > RAW_HEADER_CUTOFF;
588
589 const showMore = ():void => {
590 if (forResponseHeaders) {
591 this.#showResponseHeadersTextFull = true;
592 } else {
593 this.#showRequestHeadersTextFull = true;
594 }
595 this.#render();
596 };
597
598 const onContextMenuOpen = (event: Event): void => {
599 const showFull = forResponseHeaders ? this.#showResponseHeadersTextFull : this.#showRequestHeadersTextFull;
600 if (!showFull) {
601 const contextMenu = new UI.ContextMenu.ContextMenu(event);
602 const section = contextMenu.newSection();
603 section.appendItem(i18nString(UIStrings.showMore), showMore);
604 void contextMenu.show();
605 }
606 };
607
608 const addContextMenuListener = (el: Element):void => {
609 if (isShortened) {
610 el.addEventListener('contextmenu', onContextMenuOpen);
611 }
612 };
613
614 return html`
615 <div class="row raw-headers-row" on-render=${ComponentHelpers.Directives.nodeRenderedCallback(addContextMenuListener)}>
616 <div class="raw-headers">${isShortened ? trimmed.substring(0, RAW_HEADER_CUTOFF) : trimmed}</div>
617 ${isShortened ? html`
618 <${Buttons.Button.Button.litTagName}
619 .size=${Buttons.Button.Size.SMALL}
620 .variant=${Buttons.Button.Variant.SECONDARY}
621 @click=${showMore}
622 >${i18nString(UIStrings.showMore)}</${Buttons.Button.Button.litTagName}>
623 ` : LitHtml.nothing}
624 </div>
625 `;
626 }
627
Wolfgang Beyer3e62bd72022-07-28 14:26:48628 #renderGeneralSection(): LitHtml.LitTemplate {
629 if (!this.#request) {
630 return LitHtml.nothing;
631 }
Wolfgang Beyer40530b682022-05-17 13:02:01632
633 let coloredCircleClassName = 'red-circle';
634 if (this.#request.statusCode < 300 || this.#request.statusCode === 304) {
635 coloredCircleClassName = 'green-circle';
636 } else if (this.#request.statusCode < 400) {
637 coloredCircleClassName = 'yellow-circle';
638 }
639
640 let statusText = this.#request.statusCode + ' ' + this.#request.statusText;
641 let statusTextHasComment = false;
642 if (this.#request.cachedInMemory()) {
643 statusText += ' ' + i18nString(UIStrings.fromMemoryCache);
644 statusTextHasComment = true;
645 } else if (this.#request.fetchedViaServiceWorker) {
646 statusText += ' ' + i18nString(UIStrings.fromServiceWorker);
647 statusTextHasComment = true;
648 } else if (this.#request.redirectSourceSignedExchangeInfoHasNoErrors()) {
649 statusText += ' ' + i18nString(UIStrings.fromSignedexchange);
650 statusTextHasComment = true;
651 } else if (this.#request.webBundleInnerRequestInfo()) {
652 statusText += ' ' + i18nString(UIStrings.fromWebBundle);
653 statusTextHasComment = true;
654 } else if (this.#request.fromPrefetchCache()) {
655 statusText += ' ' + i18nString(UIStrings.fromPrefetchCache);
656 statusTextHasComment = true;
657 } else if (this.#request.cached()) {
658 statusText += ' ' + i18nString(UIStrings.fromDiskCache);
659 statusTextHasComment = true;
660 }
661
662 // Disabled until https://crbug.com/1079231 is fixed.
663 // clang-format off
664 return html`
Wolfgang Beyer235544c2022-05-24 08:07:45665 <${Category.litTagName}
666 .data=${{name: 'general', title: i18nString(UIStrings.general)} as CategoryData}
667 aria-label=${i18nString(UIStrings.general)}
668 >
Wolfgang Beyer40530b682022-05-17 13:02:01669 <div class="row">
670 <div class="header-name">${i18nString(UIStrings.requestUrl)}:</div>
Wolfgang Beyerd815e1f2022-07-28 16:01:29671 <div
672 class="header-value"
673 @copy=${():void => Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue)}
674 >${this.#request.url()}</div>
Wolfgang Beyer40530b682022-05-17 13:02:01675 </div>
676 ${this.#request.statusCode? html`
677 <div class="row">
678 <div class="header-name">${i18nString(UIStrings.requestMethod)}:</div>
Wolfgang Beyerd815e1f2022-07-28 16:01:29679 <div
680 class="header-value"
681 @copy=${():void => Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue)}
682 >${this.#request.requestMethod}</div>
Wolfgang Beyer40530b682022-05-17 13:02:01683 </div>
684 <div class="row">
685 <div class="header-name">${i18nString(UIStrings.statusCode)}:</div>
Wolfgang Beyerd815e1f2022-07-28 16:01:29686 <div
687 class="header-value ${coloredCircleClassName} ${statusTextHasComment ? 'status-with-comment' : ''}"
688 @copy=${():void => Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue)}
689 >${statusText}</div>
Wolfgang Beyer40530b682022-05-17 13:02:01690 </div>
691 ` : ''}
692 ${this.#request.remoteAddress()? html`
693 <div class="row">
694 <div class="header-name">${i18nString(UIStrings.remoteAddress)}:</div>
Wolfgang Beyerd815e1f2022-07-28 16:01:29695 <div
696 class="header-value"
697 @copy=${():void => Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue)}
698 >${this.#request.remoteAddress()}</div>
Wolfgang Beyer40530b682022-05-17 13:02:01699 </div>
700 ` : ''}
701 ${this.#request.referrerPolicy()? html`
702 <div class="row">
703 <div class="header-name">${i18nString(UIStrings.referrerPolicy)}:</div>
Wolfgang Beyerd815e1f2022-07-28 16:01:29704 <div
705 class="header-value"
706 @copy=${():void => Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue)}
707 >${this.#request.referrerPolicy()}</div>
Wolfgang Beyer40530b682022-05-17 13:02:01708 </div>
709 ` : ''}
710 </${Category.litTagName}>
711 `;
712 // clang-format on
713 }
714}
715
Wolfgang Beyer235544c2022-05-24 08:07:45716export class ToggleRawHeadersEvent extends Event {
717 static readonly eventName = 'togglerawevent';
718
719 constructor() {
720 super(ToggleRawHeadersEvent.eventName, {});
721 }
722}
723
Wolfgang Beyer40530b682022-05-17 13:02:01724export interface CategoryData {
725 name: string;
726 title: Common.UIString.LocalizedString;
Wolfgang Beyer235544c2022-05-24 08:07:45727 headerCount?: number;
728 checked?: boolean;
Wolfgang Beyer185fb1f2022-08-01 13:48:25729 additionalContent?: LitHtml.LitTemplate;
Wolfgang Beyer40530b682022-05-17 13:02:01730}
731
732export class Category extends HTMLElement {
733 static readonly litTagName = LitHtml.literal`devtools-request-headers-category`;
734 readonly #shadow = this.attachShadow({mode: 'open'});
735 #expandedSetting?: Common.Settings.Setting<boolean>;
736 #title: Common.UIString.LocalizedString = Common.UIString.LocalizedEmptyString;
Wolfgang Beyer235544c2022-05-24 08:07:45737 #headerCount?: number = undefined;
738 #checked: boolean|undefined = undefined;
Wolfgang Beyer185fb1f2022-08-01 13:48:25739 #additionalContent: LitHtml.LitTemplate|undefined = undefined;
Wolfgang Beyer40530b682022-05-17 13:02:01740
741 connectedCallback(): void {
Jack Franklin1f19d522022-07-06 14:00:18742 this.#shadow.adoptedStyleSheets = [requestHeadersViewStyles, Input.checkboxStyles];
Wolfgang Beyer40530b682022-05-17 13:02:01743 }
744
745 set data(data: CategoryData) {
746 this.#title = data.title;
747 this.#expandedSetting =
748 Common.Settings.Settings.instance().createSetting('request-info-' + data.name + '-category-expanded', true);
Wolfgang Beyer235544c2022-05-24 08:07:45749 this.#headerCount = data.headerCount;
750 this.#checked = data.checked;
Wolfgang Beyer185fb1f2022-08-01 13:48:25751 this.#additionalContent = data.additionalContent;
Wolfgang Beyer40530b682022-05-17 13:02:01752 this.#render();
753 }
754
Wolfgang Beyer235544c2022-05-24 08:07:45755 #onCheckboxToggle(): void {
756 this.dispatchEvent(new ToggleRawHeadersEvent());
757 }
758
Wolfgang Beyer40530b682022-05-17 13:02:01759 #render(): void {
Wolfgang Beyer235544c2022-05-24 08:07:45760 const isOpen = this.#expandedSetting ? this.#expandedSetting.get() : true;
Wolfgang Beyer40530b682022-05-17 13:02:01761 // Disabled until https://crbug.com/1079231 is fixed.
762 // clang-format off
763 render(html`
Wolfgang Beyer235544c2022-05-24 08:07:45764 <details ?open=${isOpen} @toggle=${this.#onToggle}>
765 <summary class="header" @keydown=${this.#onSummaryKeyDown}>
Wolfgang Beyer185fb1f2022-08-01 13:48:25766 <div class="header-grid-container">
767 <div>
768 ${this.#title}${this.#headerCount ?
769 html`<span class="header-count"> (${this.#headerCount})</span>` :
770 LitHtml.nothing
771 }
772 </div>
773 <div class="hide-when-closed">
774 ${this.#checked !== undefined ? html`
775 <label><input type="checkbox" .checked=${this.#checked} @change=${this.#onCheckboxToggle} />${i18nString(UIStrings.raw)}</label>
776 ` : LitHtml.nothing}
777 </div>
778 <div class="hide-when-closed">${this.#additionalContent}</div>
Wolfgang Beyer235544c2022-05-24 08:07:45779 </summary>
Wolfgang Beyer40530b682022-05-17 13:02:01780 <slot></slot>
781 </details>
782 `, this.#shadow, {host: this});
783 // clang-format on
784 }
785
786 #onSummaryKeyDown(event: KeyboardEvent): void {
787 if (!event.target) {
788 return;
789 }
790 const summaryElement = event.target as HTMLElement;
791 const detailsElement = summaryElement.parentElement as HTMLDetailsElement;
792 if (!detailsElement) {
793 throw new Error('<details> element is not found for a <summary> element');
794 }
795 switch (event.key) {
796 case 'ArrowLeft':
797 detailsElement.open = false;
798 break;
799 case 'ArrowRight':
800 detailsElement.open = true;
801 break;
802 }
803 }
804
805 #onToggle(event: Event): void {
806 this.#expandedSetting?.set((event.target as HTMLDetailsElement).open);
807 }
808}
809
810ComponentHelpers.CustomElements.defineComponent('devtools-request-headers', RequestHeadersComponent);
811ComponentHelpers.CustomElements.defineComponent('devtools-request-headers-category', Category);
812
813declare global {
814 // eslint-disable-next-line @typescript-eslint/no-unused-vars
815 interface HTMLElementTagNameMap {
816 'devtools-request-headers': RequestHeadersComponent;
817 'devtools-request-headers-category': Category;
818 }
819}
Wolfgang Beyer7f495ee2022-07-08 13:45:13820
Wolfgang Beyer21894d52022-07-26 12:12:44821interface BlockedDetailsDescriptor {
Wolfgang Beyer7f495ee2022-07-08 13:45:13822 explanation: () => string;
823 examples: Array<{
824 codeSnippet: string,
825 comment?: (() => string),
826 }>;
827 link: {
828 url: string,
829 }|null;
830}
831
832interface HeaderDescriptor {
833 name: string;
834 value: Object|null;
835 headerValueIncorrect?: boolean|null;
Wolfgang Beyer21894d52022-07-26 12:12:44836 blockedDetails?: BlockedDetailsDescriptor;
Wolfgang Beyer7f495ee2022-07-08 13:45:13837 headerNotSet: boolean|null;
Wolfgang Beyer21894d52022-07-26 12:12:44838 setCookieBlockedReasons?: Protocol.Network.SetCookieBlockedReason[];
Wolfgang Beyer7f495ee2022-07-08 13:45:13839}
840
841const BlockedReasonDetails = new Map<Protocol.Network.BlockedReason, HeaderDescriptor>([
842 [
843 Protocol.Network.BlockedReason.CoepFrameResourceNeedsCoepHeader,
844 {
845 name: 'cross-origin-embedder-policy',
846 value: null,
847 headerValueIncorrect: null,
Wolfgang Beyer21894d52022-07-26 12:12:44848 blockedDetails: {
Wolfgang Beyer7f495ee2022-07-08 13:45:13849 explanation: i18nLazyString(UIStrings.toEmbedThisFrameInYourDocument),
850 examples: [{codeSnippet: 'Cross-Origin-Embedder-Policy: require-corp', comment: undefined}],
851 link: {url: 'https://web.dev/coop-coep/'},
852 },
853 headerNotSet: null,
854 },
855 ],
856 [
857 Protocol.Network.BlockedReason.CorpNotSameOriginAfterDefaultedToSameOriginByCoep,
858 {
859 name: 'cross-origin-resource-policy',
860 value: null,
861 headerValueIncorrect: null,
Wolfgang Beyer21894d52022-07-26 12:12:44862 blockedDetails: {
Wolfgang Beyer7f495ee2022-07-08 13:45:13863 explanation: i18nLazyString(UIStrings.toUseThisResourceFromADifferent),
864 examples: [
865 {
866 codeSnippet: 'Cross-Origin-Resource-Policy: same-site',
867 comment: i18nLazyString(UIStrings.chooseThisOptionIfTheResourceAnd),
868 },
869 {
870 codeSnippet: 'Cross-Origin-Resource-Policy: cross-origin',
871 comment: i18nLazyString(UIStrings.onlyChooseThisOptionIfAn),
872 },
873 ],
874 link: {url: 'https://web.dev/coop-coep/'},
875 },
876 headerNotSet: null,
877 },
878 ],
879 [
880 Protocol.Network.BlockedReason.CoopSandboxedIframeCannotNavigateToCoopPage,
881 {
882 name: 'cross-origin-opener-policy',
883 value: null,
884 headerValueIncorrect: false,
Wolfgang Beyer21894d52022-07-26 12:12:44885 blockedDetails: {
Wolfgang Beyer7f495ee2022-07-08 13:45:13886 explanation: i18nLazyString(UIStrings.thisDocumentWasBlockedFrom),
887 examples: [],
888 link: {url: 'https://web.dev/coop-coep/'},
889 },
890 headerNotSet: null,
891 },
892 ],
893 [
894 Protocol.Network.BlockedReason.CorpNotSameSite,
895 {
896 name: 'cross-origin-resource-policy',
897 value: null,
898 headerValueIncorrect: true,
Wolfgang Beyer21894d52022-07-26 12:12:44899 blockedDetails: {
Wolfgang Beyer7f495ee2022-07-08 13:45:13900 explanation: i18nLazyString(UIStrings.toUseThisResourceFromADifferentSite),
901 examples: [
902 {
903 codeSnippet: 'Cross-Origin-Resource-Policy: cross-origin',
904 comment: i18nLazyString(UIStrings.onlyChooseThisOptionIfAn),
905 },
906 ],
907 link: null,
908 },
909 headerNotSet: null,
910 },
911 ],
912 [
913 Protocol.Network.BlockedReason.CorpNotSameOrigin,
914 {
915 name: 'cross-origin-resource-policy',
916 value: null,
917 headerValueIncorrect: true,
Wolfgang Beyer21894d52022-07-26 12:12:44918 blockedDetails: {
Wolfgang Beyer7f495ee2022-07-08 13:45:13919 explanation: i18nLazyString(UIStrings.toUseThisResourceFromADifferentOrigin),
920 examples: [
921 {
922 codeSnippet: 'Cross-Origin-Resource-Policy: same-site',
923 comment: i18nLazyString(UIStrings.chooseThisOptionIfTheResourceAnd),
924 },
925 {
926 codeSnippet: 'Cross-Origin-Resource-Policy: cross-origin',
927 comment: i18nLazyString(UIStrings.onlyChooseThisOptionIfAn),
928 },
929 ],
930 link: null,
931 },
932 headerNotSet: null,
933 },
934 ],
935]);