blob: a4b8ea510ba2172792025b53abcc06297aaf4e19 [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371/*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) IBM Corp. 2009 All rights reserved.
4 * Copyright (C) 2010 Google Inc. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
Paul Lewis56509652019-12-06 12:51:5831export class RequestHeadersView extends UI.VBox {
Blink Reformat4c46d092018-04-07 15:32:3732 /**
33 * @param {!SDK.NetworkRequest} request
34 */
35 constructor(request) {
36 super();
37 this.registerRequiredCSS('network/requestHeadersView.css');
38 this.element.classList.add('request-headers-view');
39
40 this._request = request;
41 this._decodeRequestParameters = true;
42 this._showRequestHeadersText = false;
43 this._showResponseHeadersText = false;
44
45 /** @type {?UI.TreeElement} */
46 this._highlightedElement = null;
47
48 const root = new UI.TreeOutlineInShadow();
Amanda Bakerc3d15272019-10-25 00:56:3949 root.registerRequiredCSS('object_ui/objectValue.css');
50 root.registerRequiredCSS('object_ui/objectPropertiesSection.css');
Blink Reformat4c46d092018-04-07 15:32:3751 root.registerRequiredCSS('network/requestHeadersTree.css');
52 root.element.classList.add('request-headers-tree');
Blink Reformat4c46d092018-04-07 15:32:3753 root.makeDense();
Blink Reformat4c46d092018-04-07 15:32:3754 this.element.appendChild(root.element);
55
Paul Lewis56509652019-12-06 12:51:5856 const generalCategory = new Category(root, 'general', Common.UIString('General'));
Blink Reformat4c46d092018-04-07 15:32:3757 generalCategory.hidden = false;
Amanda Baker2e19a1b2019-10-25 00:41:0258 this._root = generalCategory;
Blink Reformat4c46d092018-04-07 15:32:3759 this._urlItem = generalCategory.createLeaf();
60 this._requestMethodItem = generalCategory.createLeaf();
61 this._statusCodeItem = generalCategory.createLeaf();
62 this._remoteAddressItem = generalCategory.createLeaf();
63 this._remoteAddressItem.hidden = true;
64 this._referrerPolicyItem = generalCategory.createLeaf();
65 this._referrerPolicyItem.hidden = true;
66
Paul Lewis56509652019-12-06 12:51:5867 this._responseHeadersCategory = new Category(root, 'responseHeaders', '');
68 this._requestHeadersCategory = new Category(root, 'requestHeaders', '');
69 this._queryStringCategory = new Category(root, 'queryString', '');
70 this._formDataCategory = new Category(root, 'formData', '');
71 this._requestPayloadCategory = new Category(root, 'requestPayload', Common.UIString('Request Payload'));
Blink Reformat4c46d092018-04-07 15:32:3772 }
73
74 /**
75 * @override
76 */
77 wasShown() {
78 this._clearHighlight();
79 this._request.addEventListener(SDK.NetworkRequest.Events.RemoteAddressChanged, this._refreshRemoteAddress, this);
80 this._request.addEventListener(SDK.NetworkRequest.Events.RequestHeadersChanged, this._refreshRequestHeaders, this);
81 this._request.addEventListener(
82 SDK.NetworkRequest.Events.ResponseHeadersChanged, this._refreshResponseHeaders, this);
83 this._request.addEventListener(SDK.NetworkRequest.Events.FinishedLoading, this._refreshHTTPInformation, this);
84
85 this._refreshURL();
86 this._refreshQueryString();
87 this._refreshRequestHeaders();
88 this._refreshResponseHeaders();
89 this._refreshHTTPInformation();
90 this._refreshRemoteAddress();
91 this._refreshReferrerPolicy();
Amanda Baker2e19a1b2019-10-25 00:41:0292 this._root.select(/* omitFocus */ true, /* selectedByUser */ false);
Blink Reformat4c46d092018-04-07 15:32:3793 }
94
95 /**
96 * @override
97 */
98 willHide() {
99 this._request.removeEventListener(SDK.NetworkRequest.Events.RemoteAddressChanged, this._refreshRemoteAddress, this);
100 this._request.removeEventListener(
101 SDK.NetworkRequest.Events.RequestHeadersChanged, this._refreshRequestHeaders, this);
102 this._request.removeEventListener(
103 SDK.NetworkRequest.Events.ResponseHeadersChanged, this._refreshResponseHeaders, this);
104 this._request.removeEventListener(SDK.NetworkRequest.Events.FinishedLoading, this._refreshHTTPInformation, this);
105 }
106
107 /**
108 * @param {string} name
109 * @param {string} value
110 * @return {!DocumentFragment}
111 */
112 _formatHeader(name, value) {
113 const fragment = createDocumentFragment();
114 fragment.createChild('div', 'header-name').textContent = name + ': ';
115 fragment.createChild('span', 'header-separator');
116 fragment.createChild('div', 'header-value source-code').textContent = value;
117
118 return fragment;
119 }
120
121 /**
122 * @param {string} value
123 * @param {string} className
124 * @param {boolean} decodeParameters
125 * @return {!Element}
126 */
127 _formatParameter(value, className, decodeParameters) {
128 let errorDecoding = false;
129
130 if (decodeParameters) {
131 value = value.replace(/\+/g, ' ');
132 if (value.indexOf('%') >= 0) {
133 try {
134 value = decodeURIComponent(value);
135 } catch (e) {
136 errorDecoding = true;
137 }
138 }
139 }
140 const div = createElementWithClass('div', className);
Tim van der Lippe1d6e57a2019-09-30 11:55:34141 if (value === '') {
Blink Reformat4c46d092018-04-07 15:32:37142 div.classList.add('empty-value');
Tim van der Lippe1d6e57a2019-09-30 11:55:34143 }
144 if (errorDecoding) {
Blink Reformat4c46d092018-04-07 15:32:37145 div.createChild('span', 'header-decode-error').textContent = Common.UIString('(unable to decode value)');
Tim van der Lippe1d6e57a2019-09-30 11:55:34146 } else {
Blink Reformat4c46d092018-04-07 15:32:37147 div.textContent = value;
Tim van der Lippe1d6e57a2019-09-30 11:55:34148 }
Blink Reformat4c46d092018-04-07 15:32:37149 return div;
150 }
151
152 _refreshURL() {
153 this._urlItem.title = this._formatHeader(Common.UIString('Request URL'), this._request.url());
154 }
155
156 _refreshQueryString() {
157 const queryString = this._request.queryString();
158 const queryParameters = this._request.queryParameters;
159 this._queryStringCategory.hidden = !queryParameters;
160 if (queryParameters) {
161 this._refreshParams(
162 Common.UIString('Query String Parameters'), queryParameters, queryString, this._queryStringCategory);
163 }
164 }
165
166 async _refreshFormData() {
167 this._formDataCategory.hidden = true;
168 this._requestPayloadCategory.hidden = true;
169
170 const formData = await this._request.requestFormData();
Tim van der Lippe1d6e57a2019-09-30 11:55:34171 if (!formData) {
Blink Reformat4c46d092018-04-07 15:32:37172 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34173 }
Blink Reformat4c46d092018-04-07 15:32:37174
175 const formParameters = await this._request.formParameters();
176 if (formParameters) {
177 this._formDataCategory.hidden = false;
178 this._refreshParams(Common.UIString('Form Data'), formParameters, formData, this._formDataCategory);
179 } else {
180 this._requestPayloadCategory.hidden = false;
181 try {
182 const json = JSON.parse(formData);
183 this._refreshRequestJSONPayload(json, formData);
184 } catch (e) {
185 this._populateTreeElementWithSourceText(this._requestPayloadCategory, formData);
186 }
187 }
188 }
189
190 /**
191 * @param {!UI.TreeElement} treeElement
192 * @param {?string} sourceText
193 */
194 _populateTreeElementWithSourceText(treeElement, sourceText) {
195 const max_len = 3000;
196 const text = (sourceText || '').trim();
197 const trim = text.length > max_len;
198
199 const sourceTextElement = createElementWithClass('span', 'header-value source-code');
200 sourceTextElement.textContent = trim ? text.substr(0, max_len) : text;
201
202 const sourceTreeElement = new UI.TreeElement(sourceTextElement);
Blink Reformat4c46d092018-04-07 15:32:37203 treeElement.removeChildren();
204 treeElement.appendChild(sourceTreeElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34205 if (!trim) {
Blink Reformat4c46d092018-04-07 15:32:37206 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34207 }
Blink Reformat4c46d092018-04-07 15:32:37208
209 const showMoreButton = createElementWithClass('button', 'request-headers-show-more-button');
210 showMoreButton.textContent = Common.UIString('Show more');
Amanda Baker89806492019-10-25 01:49:02211
212 function showMore() {
Blink Reformat4c46d092018-04-07 15:32:37213 showMoreButton.remove();
214 sourceTextElement.textContent = text;
Amanda Baker89806492019-10-25 01:49:02215 sourceTreeElement.listItemElement.removeEventListener('contextmenu', onContextMenuShowMore);
216 }
217 showMoreButton.addEventListener('click', showMore);
218
219 /**
220 * @param {!Event} event
221 */
222 function onContextMenuShowMore(event) {
223 const contextMenu = new UI.ContextMenu(event);
224 const section = contextMenu.newSection();
225 section.appendItem(ls`Show more`, showMore);
226 contextMenu.show();
227 }
228 sourceTreeElement.listItemElement.addEventListener('contextmenu', onContextMenuShowMore);
Blink Reformat4c46d092018-04-07 15:32:37229 sourceTextElement.appendChild(showMoreButton);
230 }
231
232 /**
233 * @param {string} title
234 * @param {?Array.<!SDK.NetworkRequest.NameValue>} params
235 * @param {?string} sourceText
236 * @param {!UI.TreeElement} paramsTreeElement
237 */
238 _refreshParams(title, params, sourceText, paramsTreeElement) {
239 paramsTreeElement.removeChildren();
240
241 paramsTreeElement.listItemElement.removeChildren();
Amanda Baker2e19a1b2019-10-25 00:41:02242 paramsTreeElement.listItemElement.createChild('div', 'selection fill');
Blink Reformat4c46d092018-04-07 15:32:37243 paramsTreeElement.listItemElement.createTextChild(title);
244
245 const headerCount = createElementWithClass('span', 'header-count');
Mathias Bynens7d8cd342019-09-17 13:32:10246 headerCount.textContent = Common.UIString('\xA0(%d)', params.length);
Blink Reformat4c46d092018-04-07 15:32:37247 paramsTreeElement.listItemElement.appendChild(headerCount);
248
Paul Lewis56509652019-12-06 12:51:58249 const shouldViewSource = paramsTreeElement[_viewSourceSymbol];
Amanda Bakere2bb99d2019-10-25 01:28:43250 if (shouldViewSource) {
251 this._appendParamsSource(title, params, sourceText, paramsTreeElement);
252 } else {
253 this._appendParamsParsed(title, params, sourceText, paramsTreeElement);
254 }
255 }
256
257 /**
258 * @param {string} title
259 * @param {?Array.<!SDK.NetworkRequest.NameValue>} params
260 * @param {?string} sourceText
261 * @param {!UI.TreeElement} paramsTreeElement
262 */
263 _appendParamsSource(title, params, sourceText, paramsTreeElement) {
264 this._populateTreeElementWithSourceText(paramsTreeElement, sourceText);
265
266 const listItemElement = paramsTreeElement.listItemElement;
267
Blink Reformat4c46d092018-04-07 15:32:37268 /**
269 * @param {!Event} event
Paul Lewis56509652019-12-06 12:51:58270 * @this {RequestHeadersView}
Blink Reformat4c46d092018-04-07 15:32:37271 */
Amanda Bakere2bb99d2019-10-25 01:28:43272 const viewParsed = function(event) {
273 listItemElement.removeEventListener('contextmenu', viewParsedContextMenu);
274
Paul Lewis56509652019-12-06 12:51:58275 paramsTreeElement[_viewSourceSymbol] = false;
Blink Reformat4c46d092018-04-07 15:32:37276 this._refreshParams(title, params, sourceText, paramsTreeElement);
277 event.consume();
Amanda Bakere2bb99d2019-10-25 01:28:43278 };
Blink Reformat4c46d092018-04-07 15:32:37279
Amanda Bakere2bb99d2019-10-25 01:28:43280 /**
281 * @param {!Event} event
Paul Lewis56509652019-12-06 12:51:58282 * @this {RequestHeadersView}
Amanda Bakere2bb99d2019-10-25 01:28:43283 */
284 const viewParsedContextMenu = function(event) {
285 if (!paramsTreeElement.expanded) {
286 return;
287 }
288 const contextMenu = new UI.ContextMenu(event);
289 contextMenu.newSection().appendItem(ls`View parsed`, viewParsed.bind(this, event));
290 contextMenu.show();
291 }.bind(this);
Blink Reformat4c46d092018-04-07 15:32:37292
Amanda Bakere2bb99d2019-10-25 01:28:43293 const viewParsedButton = this._createViewSourceToggle(/* viewSource */ true, viewParsed.bind(this));
294 listItemElement.appendChild(viewParsedButton);
Blink Reformat4c46d092018-04-07 15:32:37295
Amanda Bakere2bb99d2019-10-25 01:28:43296 listItemElement.addEventListener('contextmenu', viewParsedContextMenu);
297 }
Blink Reformat4c46d092018-04-07 15:32:37298
Amanda Bakere2bb99d2019-10-25 01:28:43299 /**
300 * @param {string} title
301 * @param {?Array.<!SDK.NetworkRequest.NameValue>} params
302 * @param {?string} sourceText
303 * @param {!UI.TreeElement} paramsTreeElement
304 */
305 _appendParamsParsed(title, params, sourceText, paramsTreeElement) {
Blink Reformat4c46d092018-04-07 15:32:37306 for (let i = 0; i < params.length; ++i) {
307 const paramNameValue = createDocumentFragment();
308 if (params[i].name !== '') {
309 const name = this._formatParameter(params[i].name + ': ', 'header-name', this._decodeRequestParameters);
310 const value = this._formatParameter(params[i].value, 'header-value source-code', this._decodeRequestParameters);
311 paramNameValue.appendChild(name);
312 paramNameValue.createChild('span', 'header-separator');
313 paramNameValue.appendChild(value);
314 } else {
315 paramNameValue.appendChild(
316 this._formatParameter(Common.UIString('(empty)'), 'empty-request-header', this._decodeRequestParameters));
317 }
318
319 const paramTreeElement = new UI.TreeElement(paramNameValue);
Blink Reformat4c46d092018-04-07 15:32:37320 paramsTreeElement.appendChild(paramTreeElement);
321 }
Amanda Bakere2bb99d2019-10-25 01:28:43322
323 const listItemElement = paramsTreeElement.listItemElement;
324
325 /**
326 * @param {!Event} event
Paul Lewis56509652019-12-06 12:51:58327 * @this {RequestHeadersView}
Amanda Bakere2bb99d2019-10-25 01:28:43328 */
329 const viewSource = function(event) {
330 listItemElement.removeEventListener('contextmenu', viewSourceContextMenu);
331
Paul Lewis56509652019-12-06 12:51:58332 paramsTreeElement[_viewSourceSymbol] = true;
Amanda Bakere2bb99d2019-10-25 01:28:43333 this._refreshParams(title, params, sourceText, paramsTreeElement);
334 event.consume();
335 };
336
337 /**
338 * @param {!Event} event
Paul Lewis56509652019-12-06 12:51:58339 * @this {RequestHeadersView}
Amanda Bakere2bb99d2019-10-25 01:28:43340 */
341 const toggleURLDecoding = function(event) {
342 listItemElement.removeEventListener('contextmenu', viewSourceContextMenu);
343 this._toggleURLDecoding(event);
344 };
345
346 /**
347 * @param {!Event} event
Paul Lewis56509652019-12-06 12:51:58348 * @this {RequestHeadersView}
Amanda Bakere2bb99d2019-10-25 01:28:43349 */
350 const viewSourceContextMenu = function(event) {
351 if (!paramsTreeElement.expanded) {
352 return;
353 }
354 const contextMenu = new UI.ContextMenu(event);
355 const section = contextMenu.newSection();
356 section.appendItem(ls`View source`, viewSource.bind(this, event));
357 const viewURLEncodedText = this._decodeRequestParameters ? ls`View URL encoded` : ls`View decoded`;
358 section.appendItem(viewURLEncodedText, toggleURLDecoding.bind(this, event));
359 contextMenu.show();
360 }.bind(this);
361
362 const viewSourceButton = this._createViewSourceToggle(/* viewSource */ false, viewSource.bind(this));
363 listItemElement.appendChild(viewSourceButton);
364
365 const toggleTitle = this._decodeRequestParameters ? ls`view URL encoded` : ls`view decoded`;
366 const toggleButton = this._createToggleButton(toggleTitle);
367 toggleButton.addEventListener('click', toggleURLDecoding.bind(this), false);
368 listItemElement.appendChild(toggleButton);
369
370 listItemElement.addEventListener('contextmenu', viewSourceContextMenu);
Blink Reformat4c46d092018-04-07 15:32:37371 }
372
373 /**
374 * @param {*} parsedObject
375 * @param {string} sourceText
376 */
377 _refreshRequestJSONPayload(parsedObject, sourceText) {
Amanda Baker1815fca2019-10-25 01:16:00378 const rootListItem = this._requestPayloadCategory;
379 rootListItem.removeChildren();
Blink Reformat4c46d092018-04-07 15:32:37380
Amanda Baker1815fca2019-10-25 01:16:00381 const rootListItemElement = rootListItem.listItemElement;
382 rootListItemElement.removeChildren();
383 rootListItemElement.createChild('div', 'selection fill');
384 rootListItemElement.createTextChild(this._requestPayloadCategory.title);
385
Paul Lewis56509652019-12-06 12:51:58386 const shouldViewSource = rootListItem[_viewSourceSymbol];
Amanda Baker1815fca2019-10-25 01:16:00387 if (shouldViewSource) {
388 this._appendJSONPayloadSource(rootListItem, parsedObject, sourceText);
389 } else {
390 this._appendJSONPayloadParsed(rootListItem, parsedObject, sourceText);
391 }
392 }
393
394 /**
Paul Lewis56509652019-12-06 12:51:58395 * @param {!Category} rootListItem
Amanda Baker1815fca2019-10-25 01:16:00396 * @param {*} parsedObject
397 * @param {string} sourceText
398 */
399 _appendJSONPayloadSource(rootListItem, parsedObject, sourceText) {
400 const rootListItemElement = rootListItem.listItemElement;
401 this._populateTreeElementWithSourceText(rootListItem, sourceText);
Blink Reformat4c46d092018-04-07 15:32:37402
403 /**
404 * @param {!Event} event
Paul Lewis56509652019-12-06 12:51:58405 * @this {RequestHeadersView}
Blink Reformat4c46d092018-04-07 15:32:37406 */
Amanda Baker1815fca2019-10-25 01:16:00407 const viewParsed = function(event) {
408 rootListItemElement.removeEventListener('contextmenu', viewParsedContextMenu);
Paul Lewis56509652019-12-06 12:51:58409 rootListItem[_viewSourceSymbol] = false;
Blink Reformat4c46d092018-04-07 15:32:37410 this._refreshRequestJSONPayload(parsedObject, sourceText);
411 event.consume();
Amanda Baker1815fca2019-10-25 01:16:00412 };
Blink Reformat4c46d092018-04-07 15:32:37413
Amanda Baker1815fca2019-10-25 01:16:00414 const viewParsedButton = this._createViewSourceToggle(/* viewSource */ true, viewParsed.bind(this));
415 rootListItemElement.appendChild(viewParsedButton);
416
417 /**
418 * @param {!Event} event
Paul Lewis56509652019-12-06 12:51:58419 * @this {RequestHeadersView}
Amanda Baker1815fca2019-10-25 01:16:00420 */
421 const viewParsedContextMenu = function(event) {
422 if (!rootListItem.expanded) {
423 return;
424 }
425 const contextMenu = new UI.ContextMenu(event);
426 contextMenu.newSection().appendItem(ls`View parsed`, viewParsed.bind(this, event));
427 contextMenu.show();
428 }.bind(this);
429
430 rootListItemElement.addEventListener('contextmenu', viewParsedContextMenu);
431 }
432
433 /**
Paul Lewis56509652019-12-06 12:51:58434 * @param {!Category} rootListItem
Amanda Baker1815fca2019-10-25 01:16:00435 * @param {*} parsedObject
436 * @param {string} sourceText
437 */
438 _appendJSONPayloadParsed(rootListItem, parsedObject, sourceText) {
439 const object = /** @type {!SDK.LocalJSONObject} */ (SDK.RemoteObject.fromLocalObject(parsedObject));
440 const section = new ObjectUI.ObjectPropertiesSection.RootElement(object);
441 section.title = object.description;
442 section.expand();
443 section.editable = false;
444 rootListItem.childrenListElement.classList.add('source-code', 'object-properties-section');
445
446 rootListItem.appendChild(section);
447 const rootListItemElement = rootListItem.listItemElement;
448
449 /**
450 * @param {!Event} event
Paul Lewis56509652019-12-06 12:51:58451 * @this {RequestHeadersView}
Amanda Baker1815fca2019-10-25 01:16:00452 */
453 const viewSource = function(event) {
454 rootListItemElement.removeEventListener('contextmenu', viewSourceContextMenu);
455
Paul Lewis56509652019-12-06 12:51:58456 rootListItem[_viewSourceSymbol] = true;
Amanda Baker1815fca2019-10-25 01:16:00457 this._refreshRequestJSONPayload(parsedObject, sourceText);
458 event.consume();
459 };
460
461 /**
462 * @param {!Event} event
Paul Lewis56509652019-12-06 12:51:58463 * @this {RequestHeadersView}
Amanda Baker1815fca2019-10-25 01:16:00464 */
465 const viewSourceContextMenu = function(event) {
466 if (!rootListItem.expanded) {
467 return;
468 }
469 const contextMenu = new UI.ContextMenu(event);
470 contextMenu.newSection().appendItem(ls`View source`, viewSource.bind(this, event));
471 contextMenu.show();
472 }.bind(this);
473
474 const viewSourceButton = this._createViewSourceToggle(/* viewSource */ false, viewSource.bind(this));
475 rootListItemElement.appendChild(viewSourceButton);
476
477 rootListItemElement.addEventListener('contextmenu', viewSourceContextMenu);
Blink Reformat4c46d092018-04-07 15:32:37478 }
479
480 /**
481 * @param {boolean} viewSource
482 * @param {function(!Event)} handler
483 * @return {!Element}
484 */
485 _createViewSourceToggle(viewSource, handler) {
486 const viewSourceToggleTitle = viewSource ? Common.UIString('view parsed') : Common.UIString('view source');
487 const viewSourceToggleButton = this._createToggleButton(viewSourceToggleTitle);
488 viewSourceToggleButton.addEventListener('click', handler, false);
489 return viewSourceToggleButton;
490 }
491
492 /**
493 * @param {!Event} event
494 */
495 _toggleURLDecoding(event) {
496 this._decodeRequestParameters = !this._decodeRequestParameters;
497 this._refreshQueryString();
498 this._refreshFormData();
499 event.consume();
500 }
501
502 _refreshRequestHeaders() {
503 const treeElement = this._requestHeadersCategory;
504 const headers = this._request.requestHeaders().slice();
505 headers.sort(function(a, b) {
506 return a.name.toLowerCase().compareTo(b.name.toLowerCase());
507 });
508 const headersText = this._request.requestHeadersText();
509
Tim van der Lippe1d6e57a2019-09-30 11:55:34510 if (this._showRequestHeadersText && headersText) {
Blink Reformat4c46d092018-04-07 15:32:37511 this._refreshHeadersText(Common.UIString('Request Headers'), headers.length, headersText, treeElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34512 } else {
Blink Reformat4c46d092018-04-07 15:32:37513 this._refreshHeaders(Common.UIString('Request Headers'), headers, treeElement, headersText === undefined);
Tim van der Lippe1d6e57a2019-09-30 11:55:34514 }
Blink Reformat4c46d092018-04-07 15:32:37515
516 if (headersText) {
517 const toggleButton = this._createHeadersToggleButton(this._showRequestHeadersText);
518 toggleButton.addEventListener('click', this._toggleRequestHeadersText.bind(this), false);
519 treeElement.listItemElement.appendChild(toggleButton);
520 }
521
522 this._refreshFormData();
523 }
524
525 _refreshResponseHeaders() {
526 const treeElement = this._responseHeadersCategory;
527 const headers = this._request.sortedResponseHeaders.slice();
528 const headersText = this._request.responseHeadersText;
529
Joey Arhar7199a942019-09-10 22:37:39530 if (this._showResponseHeadersText) {
Blink Reformat4c46d092018-04-07 15:32:37531 this._refreshHeadersText(Common.UIString('Response Headers'), headers.length, headersText, treeElement);
Joey Arhar7199a942019-09-10 22:37:39532 } else {
533 this._refreshHeaders(
534 Common.UIString('Response Headers'), headers, treeElement, /* provisional */ false,
535 this._request.blockedResponseCookies());
536 }
Blink Reformat4c46d092018-04-07 15:32:37537
538 if (headersText) {
539 const toggleButton = this._createHeadersToggleButton(this._showResponseHeadersText);
540 toggleButton.addEventListener('click', this._toggleResponseHeadersText.bind(this), false);
541 treeElement.listItemElement.appendChild(toggleButton);
542 }
543 }
544
545 _refreshHTTPInformation() {
546 const requestMethodElement = this._requestMethodItem;
547 requestMethodElement.hidden = !this._request.statusCode;
548 const statusCodeElement = this._statusCodeItem;
549 statusCodeElement.hidden = !this._request.statusCode;
550
551 if (this._request.statusCode) {
552 const statusCodeFragment = createDocumentFragment();
Tsuyoshi Horo41dcffd2019-05-24 03:59:05553 statusCodeFragment.createChild('div', 'header-name').textContent = ls`Status Code` +
554 ': ';
Blink Reformat4c46d092018-04-07 15:32:37555 statusCodeFragment.createChild('span', 'header-separator');
556
Joel Einbinder7fbe24c2019-01-24 05:19:01557 const statusCodeImage = statusCodeFragment.createChild('span', 'resource-status-image', 'dt-icon-label');
Blink Reformat4c46d092018-04-07 15:32:37558 statusCodeImage.title = this._request.statusCode + ' ' + this._request.statusText;
559
Tim van der Lippe1d6e57a2019-09-30 11:55:34560 if (this._request.statusCode < 300 || this._request.statusCode === 304) {
Blink Reformat4c46d092018-04-07 15:32:37561 statusCodeImage.type = 'smallicon-green-ball';
Tim van der Lippe1d6e57a2019-09-30 11:55:34562 } else if (this._request.statusCode < 400) {
Blink Reformat4c46d092018-04-07 15:32:37563 statusCodeImage.type = 'smallicon-orange-ball';
Tim van der Lippe1d6e57a2019-09-30 11:55:34564 } else {
Blink Reformat4c46d092018-04-07 15:32:37565 statusCodeImage.type = 'smallicon-red-ball';
Tim van der Lippe1d6e57a2019-09-30 11:55:34566 }
Blink Reformat4c46d092018-04-07 15:32:37567
Tsuyoshi Horo41dcffd2019-05-24 03:59:05568 requestMethodElement.title = this._formatHeader(ls`Request Method`, this._request.requestMethod);
Blink Reformat4c46d092018-04-07 15:32:37569
570 const statusTextElement = statusCodeFragment.createChild('div', 'header-value source-code');
571 let statusText = this._request.statusCode + ' ' + this._request.statusText;
Ben Kelly0375f502018-09-11 17:05:50572 if (this._request.cachedInMemory()) {
Tsuyoshi Horo41dcffd2019-05-24 03:59:05573 statusText += ' ' + ls`(from memory cache)`;
Ben Kelly0375f502018-09-11 17:05:50574 statusTextElement.classList.add('status-from-cache');
575 } else if (this._request.fetchedViaServiceWorker) {
Tsuyoshi Horo41dcffd2019-05-24 03:59:05576 statusText += ' ' + ls`(from ServiceWorker)`;
Blink Reformat4c46d092018-04-07 15:32:37577 statusTextElement.classList.add('status-from-cache');
Tsuyoshi Horo8f6a2b12018-10-01 22:24:03578 } else if (
579 this._request.redirectSource() && this._request.redirectSource().signedExchangeInfo() &&
580 !this._request.redirectSource().signedExchangeInfo().errors) {
Tsuyoshi Horo41dcffd2019-05-24 03:59:05581 statusText += ' ' + ls`(from signed-exchange)`;
582 statusTextElement.classList.add('status-from-cache');
583 } else if (this._request.fromPrefetchCache()) {
584 statusText += ' ' + ls`(from prefetch cache)`;
Tsuyoshi Horo02266c32018-05-21 17:01:18585 statusTextElement.classList.add('status-from-cache');
Blink Reformat4c46d092018-04-07 15:32:37586 } else if (this._request.cached()) {
Tsuyoshi Horo41dcffd2019-05-24 03:59:05587 statusText += ' ' + ls`(from disk cache)`;
Blink Reformat4c46d092018-04-07 15:32:37588 statusTextElement.classList.add('status-from-cache');
589 }
590 statusTextElement.textContent = statusText;
591
592 statusCodeElement.title = statusCodeFragment;
593 }
594 }
595
596 /**
597 * @param {string} title
598 * @param {!UI.TreeElement} headersTreeElement
599 * @param {number} headersLength
600 */
601 _refreshHeadersTitle(title, headersTreeElement, headersLength) {
602 headersTreeElement.listItemElement.removeChildren();
Amanda Baker2e19a1b2019-10-25 00:41:02603 headersTreeElement.listItemElement.createChild('div', 'selection fill');
Blink Reformat4c46d092018-04-07 15:32:37604 headersTreeElement.listItemElement.createTextChild(title);
605
Mathias Bynens7d8cd342019-09-17 13:32:10606 const headerCount = Common.UIString('\xA0(%d)', headersLength);
Blink Reformat4c46d092018-04-07 15:32:37607 headersTreeElement.listItemElement.createChild('span', 'header-count').textContent = headerCount;
608 }
609
610 /**
611 * @param {string} title
612 * @param {!Array.<!SDK.NetworkRequest.NameValue>} headers
613 * @param {!UI.TreeElement} headersTreeElement
614 * @param {boolean=} provisionalHeaders
Joey Arhar7199a942019-09-10 22:37:39615 * @param {!Array<!SDK.NetworkRequest.BlockedSetCookieWithReason>=} blockedResponseCookies
Blink Reformat4c46d092018-04-07 15:32:37616 */
Joey Arhar7199a942019-09-10 22:37:39617 _refreshHeaders(title, headers, headersTreeElement, provisionalHeaders, blockedResponseCookies) {
Blink Reformat4c46d092018-04-07 15:32:37618 headersTreeElement.removeChildren();
619
620 const length = headers.length;
621 this._refreshHeadersTitle(title, headersTreeElement, length);
622
623 if (provisionalHeaders) {
624 const cautionText = Common.UIString('Provisional headers are shown');
625 const cautionFragment = createDocumentFragment();
Joel Einbinder7fbe24c2019-01-24 05:19:01626 cautionFragment.createChild('span', '', 'dt-icon-label').type = 'smallicon-warning';
Blink Reformat4c46d092018-04-07 15:32:37627 cautionFragment.createChild('div', 'caution').textContent = cautionText;
628 const cautionTreeElement = new UI.TreeElement(cautionFragment);
Blink Reformat4c46d092018-04-07 15:32:37629 headersTreeElement.appendChild(cautionTreeElement);
630 }
631
Joey Arhar41a5fad2019-09-13 22:18:45632 /** @type {!Map<string, !Array<!Protocol.Network.SetCookieBlockedReason>>} */
633 const blockedCookieLineToReasons = new Map();
Joey Arhar7199a942019-09-10 22:37:39634 if (blockedResponseCookies) {
635 blockedResponseCookies.forEach(blockedCookie => {
Joey Arhar41a5fad2019-09-13 22:18:45636 blockedCookieLineToReasons.set(blockedCookie.cookieLine, blockedCookie.blockedReasons);
Joey Arhar7199a942019-09-10 22:37:39637 });
638 }
639
Blink Reformat4c46d092018-04-07 15:32:37640 headersTreeElement.hidden = !length && !provisionalHeaders;
641 for (let i = 0; i < length; ++i) {
642 const headerTreeElement = new UI.TreeElement(this._formatHeader(headers[i].name, headers[i].value));
Paul Lewis56509652019-12-06 12:51:58643 headerTreeElement[_headerNameSymbol] = headers[i].name;
Joey Arhar7199a942019-09-10 22:37:39644
645 if (headers[i].name.toLowerCase() === 'set-cookie') {
Joey Arhar41a5fad2019-09-13 22:18:45646 const matchingBlockedReasons = blockedCookieLineToReasons.get(headers[i].value);
647 if (matchingBlockedReasons) {
Joey Arhar7199a942019-09-10 22:37:39648 const icon = UI.Icon.create('smallicon-warning', '');
649 headerTreeElement.listItemElement.appendChild(icon);
Joey Arhar41a5fad2019-09-13 22:18:45650
651 let titleText = '';
652 for (const blockedReason of matchingBlockedReasons) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34653 if (titleText) {
Joey Arhar41a5fad2019-09-13 22:18:45654 titleText += '\n';
Tim van der Lippe1d6e57a2019-09-30 11:55:34655 }
Joey Arhar41a5fad2019-09-13 22:18:45656 titleText += SDK.NetworkRequest.setCookieBlockedReasonToUiString(blockedReason);
657 }
658 icon.title = titleText;
Joey Arhar7199a942019-09-10 22:37:39659 }
660 }
661
662 headersTreeElement.appendChild(headerTreeElement);
Blink Reformat4c46d092018-04-07 15:32:37663 }
664 }
665
666 /**
667 * @param {string} title
668 * @param {number} count
669 * @param {string} headersText
670 * @param {!UI.TreeElement} headersTreeElement
671 */
672 _refreshHeadersText(title, count, headersText, headersTreeElement) {
673 this._populateTreeElementWithSourceText(headersTreeElement, headersText);
674 this._refreshHeadersTitle(title, headersTreeElement, count);
675 }
676
677 _refreshRemoteAddress() {
678 const remoteAddress = this._request.remoteAddress();
679 const treeElement = this._remoteAddressItem;
680 treeElement.hidden = !remoteAddress;
Tim van der Lippe1d6e57a2019-09-30 11:55:34681 if (remoteAddress) {
Blink Reformat4c46d092018-04-07 15:32:37682 treeElement.title = this._formatHeader(Common.UIString('Remote Address'), remoteAddress);
Tim van der Lippe1d6e57a2019-09-30 11:55:34683 }
Blink Reformat4c46d092018-04-07 15:32:37684 }
685
686 _refreshReferrerPolicy() {
687 const referrerPolicy = this._request.referrerPolicy();
688 const treeElement = this._referrerPolicyItem;
689 treeElement.hidden = !referrerPolicy;
Tim van der Lippe1d6e57a2019-09-30 11:55:34690 if (referrerPolicy) {
Blink Reformat4c46d092018-04-07 15:32:37691 treeElement.title = this._formatHeader(Common.UIString('Referrer Policy'), referrerPolicy);
Tim van der Lippe1d6e57a2019-09-30 11:55:34692 }
Blink Reformat4c46d092018-04-07 15:32:37693 }
694
695 /**
696 * @param {!Event} event
697 */
698 _toggleRequestHeadersText(event) {
699 this._showRequestHeadersText = !this._showRequestHeadersText;
700 this._refreshRequestHeaders();
701 event.consume();
702 }
703
704 /**
705 * @param {!Event} event
706 */
707 _toggleResponseHeadersText(event) {
708 this._showResponseHeadersText = !this._showResponseHeadersText;
709 this._refreshResponseHeaders();
710 event.consume();
711 }
712
713 /**
714 * @param {string} title
715 * @return {!Element}
716 */
717 _createToggleButton(title) {
718 const button = createElementWithClass('span', 'header-toggle');
719 button.textContent = title;
720 return button;
721 }
722
723 /**
724 * @param {boolean} isHeadersTextShown
725 * @return {!Element}
726 */
727 _createHeadersToggleButton(isHeadersTextShown) {
728 const toggleTitle = isHeadersTextShown ? Common.UIString('view parsed') : Common.UIString('view source');
729 return this._createToggleButton(toggleTitle);
730 }
731
732 _clearHighlight() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34733 if (this._highlightedElement) {
Blink Reformat4c46d092018-04-07 15:32:37734 this._highlightedElement.listItemElement.classList.remove('header-highlight');
Tim van der Lippe1d6e57a2019-09-30 11:55:34735 }
Blink Reformat4c46d092018-04-07 15:32:37736 this._highlightedElement = null;
737 }
738
739
740 /**
741 * @param {?UI.TreeElement} category
742 * @param {string} name
743 */
744 _revealAndHighlight(category, name) {
745 this._clearHighlight();
746 for (const element of category.children()) {
Paul Lewis56509652019-12-06 12:51:58747 if (element[_headerNameSymbol] !== name) {
Blink Reformat4c46d092018-04-07 15:32:37748 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34749 }
Blink Reformat4c46d092018-04-07 15:32:37750 this._highlightedElement = element;
751 element.reveal();
752 element.listItemElement.classList.add('header-highlight');
753 return;
754 }
755 }
756
757 /**
758 * @param {string} header
759 */
760 revealRequestHeader(header) {
761 this._revealAndHighlight(this._requestHeadersCategory, header);
762 }
763
764 /**
765 * @param {string} header
766 */
767 revealResponseHeader(header) {
768 this._revealAndHighlight(this._responseHeadersCategory, header);
769 }
Paul Lewis56509652019-12-06 12:51:58770}
Blink Reformat4c46d092018-04-07 15:32:37771
Paul Lewis56509652019-12-06 12:51:58772export const _headerNameSymbol = Symbol('HeaderName');
773export const _viewSourceSymbol = Symbol('ViewSource');
Blink Reformat4c46d092018-04-07 15:32:37774
775/**
776 * @unrestricted
777 */
Paul Lewis56509652019-12-06 12:51:58778export class Category extends UI.TreeElement {
Blink Reformat4c46d092018-04-07 15:32:37779 /**
780 * @param {!UI.TreeOutline} root
781 * @param {string} name
782 * @param {string=} title
783 */
784 constructor(root, name, title) {
785 super(title || '', true);
Blink Reformat4c46d092018-04-07 15:32:37786 this.toggleOnClick = true;
787 this.hidden = true;
788 this._expandedSetting = Common.settings.createSetting('request-info-' + name + '-category-expanded', true);
789 this.expanded = this._expandedSetting.get();
790 root.appendChild(this);
791 }
792
793 /**
794 * @return {!UI.TreeElement}
795 */
796 createLeaf() {
797 const leaf = new UI.TreeElement();
Blink Reformat4c46d092018-04-07 15:32:37798 this.appendChild(leaf);
799 return leaf;
800 }
801
802 /**
803 * @override
804 */
805 onexpand() {
806 this._expandedSetting.set(true);
807 }
808
809 /**
810 * @override
811 */
812 oncollapse() {
813 this._expandedSetting.set(false);
814 }
Paul Lewis56509652019-12-06 12:51:58815}
816
817/* Legacy exported object */
818self.Network = self.Network || {};
819
820/* Legacy exported object */
821Network = Network || {};
822
823/**
824 * @constructor
825 */
826Network.RequestHeadersView = RequestHeadersView;
827
828Network.RequestHeadersView._headerNameSymbol = _headerNameSymbol;
829Network.RequestHeadersView._viewSourceSymbol = _viewSourceSymbol;
830
831/**
832 * @constructor
833 */
834Network.RequestHeadersView.Category = Category;