blob: 1c1614421847e8c1aaefa8c7ac5768f4fef9a04b [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
31Network.RequestHeadersView = class extends UI.VBox {
32 /**
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();
49 root.registerRequiredCSS('network/requestHeadersTree.css');
50 root.element.classList.add('request-headers-tree');
Blink Reformat4c46d092018-04-07 15:32:3751 root.makeDense();
Blink Reformat4c46d092018-04-07 15:32:3752 this.element.appendChild(root.element);
53
54 const generalCategory = new Network.RequestHeadersView.Category(root, 'general', Common.UIString('General'));
55 generalCategory.hidden = false;
Amanda Baker2e19a1b2019-10-25 00:41:0256 this._root = generalCategory;
Blink Reformat4c46d092018-04-07 15:32:3757 this._urlItem = generalCategory.createLeaf();
58 this._requestMethodItem = generalCategory.createLeaf();
59 this._statusCodeItem = generalCategory.createLeaf();
60 this._remoteAddressItem = generalCategory.createLeaf();
61 this._remoteAddressItem.hidden = true;
62 this._referrerPolicyItem = generalCategory.createLeaf();
63 this._referrerPolicyItem.hidden = true;
64
65 this._responseHeadersCategory = new Network.RequestHeadersView.Category(root, 'responseHeaders', '');
66 this._requestHeadersCategory = new Network.RequestHeadersView.Category(root, 'requestHeaders', '');
67 this._queryStringCategory = new Network.RequestHeadersView.Category(root, 'queryString', '');
68 this._formDataCategory = new Network.RequestHeadersView.Category(root, 'formData', '');
69 this._requestPayloadCategory =
70 new Network.RequestHeadersView.Category(root, 'requestPayload', Common.UIString('Request Payload'));
71 }
72
73 /**
74 * @override
75 */
76 wasShown() {
77 this._clearHighlight();
78 this._request.addEventListener(SDK.NetworkRequest.Events.RemoteAddressChanged, this._refreshRemoteAddress, this);
79 this._request.addEventListener(SDK.NetworkRequest.Events.RequestHeadersChanged, this._refreshRequestHeaders, this);
80 this._request.addEventListener(
81 SDK.NetworkRequest.Events.ResponseHeadersChanged, this._refreshResponseHeaders, this);
82 this._request.addEventListener(SDK.NetworkRequest.Events.FinishedLoading, this._refreshHTTPInformation, this);
83
84 this._refreshURL();
85 this._refreshQueryString();
86 this._refreshRequestHeaders();
87 this._refreshResponseHeaders();
88 this._refreshHTTPInformation();
89 this._refreshRemoteAddress();
90 this._refreshReferrerPolicy();
Amanda Baker2e19a1b2019-10-25 00:41:0291 this._root.select(/* omitFocus */ true, /* selectedByUser */ false);
Blink Reformat4c46d092018-04-07 15:32:3792 }
93
94 /**
95 * @override
96 */
97 willHide() {
98 this._request.removeEventListener(SDK.NetworkRequest.Events.RemoteAddressChanged, this._refreshRemoteAddress, this);
99 this._request.removeEventListener(
100 SDK.NetworkRequest.Events.RequestHeadersChanged, this._refreshRequestHeaders, this);
101 this._request.removeEventListener(
102 SDK.NetworkRequest.Events.ResponseHeadersChanged, this._refreshResponseHeaders, this);
103 this._request.removeEventListener(SDK.NetworkRequest.Events.FinishedLoading, this._refreshHTTPInformation, this);
104 }
105
106 /**
107 * @param {string} name
108 * @param {string} value
109 * @return {!DocumentFragment}
110 */
111 _formatHeader(name, value) {
112 const fragment = createDocumentFragment();
113 fragment.createChild('div', 'header-name').textContent = name + ': ';
114 fragment.createChild('span', 'header-separator');
115 fragment.createChild('div', 'header-value source-code').textContent = value;
116
117 return fragment;
118 }
119
120 /**
121 * @param {string} value
122 * @param {string} className
123 * @param {boolean} decodeParameters
124 * @return {!Element}
125 */
126 _formatParameter(value, className, decodeParameters) {
127 let errorDecoding = false;
128
129 if (decodeParameters) {
130 value = value.replace(/\+/g, ' ');
131 if (value.indexOf('%') >= 0) {
132 try {
133 value = decodeURIComponent(value);
134 } catch (e) {
135 errorDecoding = true;
136 }
137 }
138 }
139 const div = createElementWithClass('div', className);
Tim van der Lippe1d6e57a2019-09-30 11:55:34140 if (value === '') {
Blink Reformat4c46d092018-04-07 15:32:37141 div.classList.add('empty-value');
Tim van der Lippe1d6e57a2019-09-30 11:55:34142 }
143 if (errorDecoding) {
Blink Reformat4c46d092018-04-07 15:32:37144 div.createChild('span', 'header-decode-error').textContent = Common.UIString('(unable to decode value)');
Tim van der Lippe1d6e57a2019-09-30 11:55:34145 } else {
Blink Reformat4c46d092018-04-07 15:32:37146 div.textContent = value;
Tim van der Lippe1d6e57a2019-09-30 11:55:34147 }
Blink Reformat4c46d092018-04-07 15:32:37148 return div;
149 }
150
151 _refreshURL() {
152 this._urlItem.title = this._formatHeader(Common.UIString('Request URL'), this._request.url());
153 }
154
155 _refreshQueryString() {
156 const queryString = this._request.queryString();
157 const queryParameters = this._request.queryParameters;
158 this._queryStringCategory.hidden = !queryParameters;
159 if (queryParameters) {
160 this._refreshParams(
161 Common.UIString('Query String Parameters'), queryParameters, queryString, this._queryStringCategory);
162 }
163 }
164
165 async _refreshFormData() {
166 this._formDataCategory.hidden = true;
167 this._requestPayloadCategory.hidden = true;
168
169 const formData = await this._request.requestFormData();
Tim van der Lippe1d6e57a2019-09-30 11:55:34170 if (!formData) {
Blink Reformat4c46d092018-04-07 15:32:37171 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34172 }
Blink Reformat4c46d092018-04-07 15:32:37173
174 const formParameters = await this._request.formParameters();
175 if (formParameters) {
176 this._formDataCategory.hidden = false;
177 this._refreshParams(Common.UIString('Form Data'), formParameters, formData, this._formDataCategory);
178 } else {
179 this._requestPayloadCategory.hidden = false;
180 try {
181 const json = JSON.parse(formData);
182 this._refreshRequestJSONPayload(json, formData);
183 } catch (e) {
184 this._populateTreeElementWithSourceText(this._requestPayloadCategory, formData);
185 }
186 }
187 }
188
189 /**
190 * @param {!UI.TreeElement} treeElement
191 * @param {?string} sourceText
192 */
193 _populateTreeElementWithSourceText(treeElement, sourceText) {
194 const max_len = 3000;
195 const text = (sourceText || '').trim();
196 const trim = text.length > max_len;
197
198 const sourceTextElement = createElementWithClass('span', 'header-value source-code');
199 sourceTextElement.textContent = trim ? text.substr(0, max_len) : text;
200
201 const sourceTreeElement = new UI.TreeElement(sourceTextElement);
Blink Reformat4c46d092018-04-07 15:32:37202 treeElement.removeChildren();
203 treeElement.appendChild(sourceTreeElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34204 if (!trim) {
Blink Reformat4c46d092018-04-07 15:32:37205 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34206 }
Blink Reformat4c46d092018-04-07 15:32:37207
208 const showMoreButton = createElementWithClass('button', 'request-headers-show-more-button');
209 showMoreButton.textContent = Common.UIString('Show more');
210 showMoreButton.addEventListener('click', () => {
211 showMoreButton.remove();
212 sourceTextElement.textContent = text;
213 });
214 sourceTextElement.appendChild(showMoreButton);
215 }
216
217 /**
218 * @param {string} title
219 * @param {?Array.<!SDK.NetworkRequest.NameValue>} params
220 * @param {?string} sourceText
221 * @param {!UI.TreeElement} paramsTreeElement
222 */
223 _refreshParams(title, params, sourceText, paramsTreeElement) {
224 paramsTreeElement.removeChildren();
225
226 paramsTreeElement.listItemElement.removeChildren();
Amanda Baker2e19a1b2019-10-25 00:41:02227 paramsTreeElement.listItemElement.createChild('div', 'selection fill');
Blink Reformat4c46d092018-04-07 15:32:37228 paramsTreeElement.listItemElement.createTextChild(title);
229
230 const headerCount = createElementWithClass('span', 'header-count');
Mathias Bynens7d8cd342019-09-17 13:32:10231 headerCount.textContent = Common.UIString('\xA0(%d)', params.length);
Blink Reformat4c46d092018-04-07 15:32:37232 paramsTreeElement.listItemElement.appendChild(headerCount);
233
234 /**
235 * @param {!Event} event
236 * @this {Network.RequestHeadersView}
237 */
238 function toggleViewSource(event) {
239 paramsTreeElement[Network.RequestHeadersView._viewSourceSymbol] =
240 !paramsTreeElement[Network.RequestHeadersView._viewSourceSymbol];
241 this._refreshParams(title, params, sourceText, paramsTreeElement);
242 event.consume();
243 }
244
245 paramsTreeElement.listItemElement.appendChild(this._createViewSourceToggle(
246 paramsTreeElement[Network.RequestHeadersView._viewSourceSymbol], toggleViewSource.bind(this)));
247
248 if (paramsTreeElement[Network.RequestHeadersView._viewSourceSymbol]) {
249 this._populateTreeElementWithSourceText(paramsTreeElement, sourceText);
250 return;
251 }
252
253 const toggleTitle =
254 this._decodeRequestParameters ? Common.UIString('view URL encoded') : Common.UIString('view decoded');
255 const toggleButton = this._createToggleButton(toggleTitle);
256 toggleButton.addEventListener('click', this._toggleURLDecoding.bind(this), false);
257 paramsTreeElement.listItemElement.appendChild(toggleButton);
258
259 for (let i = 0; i < params.length; ++i) {
260 const paramNameValue = createDocumentFragment();
261 if (params[i].name !== '') {
262 const name = this._formatParameter(params[i].name + ': ', 'header-name', this._decodeRequestParameters);
263 const value = this._formatParameter(params[i].value, 'header-value source-code', this._decodeRequestParameters);
264 paramNameValue.appendChild(name);
265 paramNameValue.createChild('span', 'header-separator');
266 paramNameValue.appendChild(value);
267 } else {
268 paramNameValue.appendChild(
269 this._formatParameter(Common.UIString('(empty)'), 'empty-request-header', this._decodeRequestParameters));
270 }
271
272 const paramTreeElement = new UI.TreeElement(paramNameValue);
Blink Reformat4c46d092018-04-07 15:32:37273 paramsTreeElement.appendChild(paramTreeElement);
274 }
275 }
276
277 /**
278 * @param {*} parsedObject
279 * @param {string} sourceText
280 */
281 _refreshRequestJSONPayload(parsedObject, sourceText) {
282 const treeElement = this._requestPayloadCategory;
283 treeElement.removeChildren();
284
285 const listItem = this._requestPayloadCategory.listItemElement;
286 listItem.removeChildren();
Amanda Baker2e19a1b2019-10-25 00:41:02287 listItem.createChild('div', 'selection fill');
Blink Reformat4c46d092018-04-07 15:32:37288 listItem.createTextChild(this._requestPayloadCategory.title);
289
290 /**
291 * @param {!Event} event
292 * @this {Network.RequestHeadersView}
293 */
294 function toggleViewSource(event) {
295 treeElement[Network.RequestHeadersView._viewSourceSymbol] =
296 !treeElement[Network.RequestHeadersView._viewSourceSymbol];
297 this._refreshRequestJSONPayload(parsedObject, sourceText);
298 event.consume();
299 }
300
301 listItem.appendChild(this._createViewSourceToggle(
302 treeElement[Network.RequestHeadersView._viewSourceSymbol], toggleViewSource.bind(this)));
303 if (treeElement[Network.RequestHeadersView._viewSourceSymbol]) {
304 this._populateTreeElementWithSourceText(this._requestPayloadCategory, sourceText);
305 } else {
306 const object = SDK.RemoteObject.fromLocalObject(parsedObject);
307 const section = new ObjectUI.ObjectPropertiesSection(object, object.description);
308 section.expand();
309 section.editable = false;
310 treeElement.appendChild(new UI.TreeElement(section.element));
311 }
312 }
313
314 /**
315 * @param {boolean} viewSource
316 * @param {function(!Event)} handler
317 * @return {!Element}
318 */
319 _createViewSourceToggle(viewSource, handler) {
320 const viewSourceToggleTitle = viewSource ? Common.UIString('view parsed') : Common.UIString('view source');
321 const viewSourceToggleButton = this._createToggleButton(viewSourceToggleTitle);
322 viewSourceToggleButton.addEventListener('click', handler, false);
323 return viewSourceToggleButton;
324 }
325
326 /**
327 * @param {!Event} event
328 */
329 _toggleURLDecoding(event) {
330 this._decodeRequestParameters = !this._decodeRequestParameters;
331 this._refreshQueryString();
332 this._refreshFormData();
333 event.consume();
334 }
335
336 _refreshRequestHeaders() {
337 const treeElement = this._requestHeadersCategory;
338 const headers = this._request.requestHeaders().slice();
339 headers.sort(function(a, b) {
340 return a.name.toLowerCase().compareTo(b.name.toLowerCase());
341 });
342 const headersText = this._request.requestHeadersText();
343
Tim van der Lippe1d6e57a2019-09-30 11:55:34344 if (this._showRequestHeadersText && headersText) {
Blink Reformat4c46d092018-04-07 15:32:37345 this._refreshHeadersText(Common.UIString('Request Headers'), headers.length, headersText, treeElement);
Tim van der Lippe1d6e57a2019-09-30 11:55:34346 } else {
Blink Reformat4c46d092018-04-07 15:32:37347 this._refreshHeaders(Common.UIString('Request Headers'), headers, treeElement, headersText === undefined);
Tim van der Lippe1d6e57a2019-09-30 11:55:34348 }
Blink Reformat4c46d092018-04-07 15:32:37349
350 if (headersText) {
351 const toggleButton = this._createHeadersToggleButton(this._showRequestHeadersText);
352 toggleButton.addEventListener('click', this._toggleRequestHeadersText.bind(this), false);
353 treeElement.listItemElement.appendChild(toggleButton);
354 }
355
356 this._refreshFormData();
357 }
358
359 _refreshResponseHeaders() {
360 const treeElement = this._responseHeadersCategory;
361 const headers = this._request.sortedResponseHeaders.slice();
362 const headersText = this._request.responseHeadersText;
363
Joey Arhar7199a942019-09-10 22:37:39364 if (this._showResponseHeadersText) {
Blink Reformat4c46d092018-04-07 15:32:37365 this._refreshHeadersText(Common.UIString('Response Headers'), headers.length, headersText, treeElement);
Joey Arhar7199a942019-09-10 22:37:39366 } else {
367 this._refreshHeaders(
368 Common.UIString('Response Headers'), headers, treeElement, /* provisional */ false,
369 this._request.blockedResponseCookies());
370 }
Blink Reformat4c46d092018-04-07 15:32:37371
372 if (headersText) {
373 const toggleButton = this._createHeadersToggleButton(this._showResponseHeadersText);
374 toggleButton.addEventListener('click', this._toggleResponseHeadersText.bind(this), false);
375 treeElement.listItemElement.appendChild(toggleButton);
376 }
377 }
378
379 _refreshHTTPInformation() {
380 const requestMethodElement = this._requestMethodItem;
381 requestMethodElement.hidden = !this._request.statusCode;
382 const statusCodeElement = this._statusCodeItem;
383 statusCodeElement.hidden = !this._request.statusCode;
384
385 if (this._request.statusCode) {
386 const statusCodeFragment = createDocumentFragment();
Tsuyoshi Horo41dcffd2019-05-24 03:59:05387 statusCodeFragment.createChild('div', 'header-name').textContent = ls`Status Code` +
388 ': ';
Blink Reformat4c46d092018-04-07 15:32:37389 statusCodeFragment.createChild('span', 'header-separator');
390
Joel Einbinder7fbe24c2019-01-24 05:19:01391 const statusCodeImage = statusCodeFragment.createChild('span', 'resource-status-image', 'dt-icon-label');
Blink Reformat4c46d092018-04-07 15:32:37392 statusCodeImage.title = this._request.statusCode + ' ' + this._request.statusText;
393
Tim van der Lippe1d6e57a2019-09-30 11:55:34394 if (this._request.statusCode < 300 || this._request.statusCode === 304) {
Blink Reformat4c46d092018-04-07 15:32:37395 statusCodeImage.type = 'smallicon-green-ball';
Tim van der Lippe1d6e57a2019-09-30 11:55:34396 } else if (this._request.statusCode < 400) {
Blink Reformat4c46d092018-04-07 15:32:37397 statusCodeImage.type = 'smallicon-orange-ball';
Tim van der Lippe1d6e57a2019-09-30 11:55:34398 } else {
Blink Reformat4c46d092018-04-07 15:32:37399 statusCodeImage.type = 'smallicon-red-ball';
Tim van der Lippe1d6e57a2019-09-30 11:55:34400 }
Blink Reformat4c46d092018-04-07 15:32:37401
Tsuyoshi Horo41dcffd2019-05-24 03:59:05402 requestMethodElement.title = this._formatHeader(ls`Request Method`, this._request.requestMethod);
Blink Reformat4c46d092018-04-07 15:32:37403
404 const statusTextElement = statusCodeFragment.createChild('div', 'header-value source-code');
405 let statusText = this._request.statusCode + ' ' + this._request.statusText;
Ben Kelly0375f502018-09-11 17:05:50406 if (this._request.cachedInMemory()) {
Tsuyoshi Horo41dcffd2019-05-24 03:59:05407 statusText += ' ' + ls`(from memory cache)`;
Ben Kelly0375f502018-09-11 17:05:50408 statusTextElement.classList.add('status-from-cache');
409 } else if (this._request.fetchedViaServiceWorker) {
Tsuyoshi Horo41dcffd2019-05-24 03:59:05410 statusText += ' ' + ls`(from ServiceWorker)`;
Blink Reformat4c46d092018-04-07 15:32:37411 statusTextElement.classList.add('status-from-cache');
Tsuyoshi Horo8f6a2b12018-10-01 22:24:03412 } else if (
413 this._request.redirectSource() && this._request.redirectSource().signedExchangeInfo() &&
414 !this._request.redirectSource().signedExchangeInfo().errors) {
Tsuyoshi Horo41dcffd2019-05-24 03:59:05415 statusText += ' ' + ls`(from signed-exchange)`;
416 statusTextElement.classList.add('status-from-cache');
417 } else if (this._request.fromPrefetchCache()) {
418 statusText += ' ' + ls`(from prefetch cache)`;
Tsuyoshi Horo02266c32018-05-21 17:01:18419 statusTextElement.classList.add('status-from-cache');
Blink Reformat4c46d092018-04-07 15:32:37420 } else if (this._request.cached()) {
Tsuyoshi Horo41dcffd2019-05-24 03:59:05421 statusText += ' ' + ls`(from disk cache)`;
Blink Reformat4c46d092018-04-07 15:32:37422 statusTextElement.classList.add('status-from-cache');
423 }
424 statusTextElement.textContent = statusText;
425
426 statusCodeElement.title = statusCodeFragment;
427 }
428 }
429
430 /**
431 * @param {string} title
432 * @param {!UI.TreeElement} headersTreeElement
433 * @param {number} headersLength
434 */
435 _refreshHeadersTitle(title, headersTreeElement, headersLength) {
436 headersTreeElement.listItemElement.removeChildren();
Amanda Baker2e19a1b2019-10-25 00:41:02437 headersTreeElement.listItemElement.createChild('div', 'selection fill');
Blink Reformat4c46d092018-04-07 15:32:37438 headersTreeElement.listItemElement.createTextChild(title);
439
Mathias Bynens7d8cd342019-09-17 13:32:10440 const headerCount = Common.UIString('\xA0(%d)', headersLength);
Blink Reformat4c46d092018-04-07 15:32:37441 headersTreeElement.listItemElement.createChild('span', 'header-count').textContent = headerCount;
442 }
443
444 /**
445 * @param {string} title
446 * @param {!Array.<!SDK.NetworkRequest.NameValue>} headers
447 * @param {!UI.TreeElement} headersTreeElement
448 * @param {boolean=} provisionalHeaders
Joey Arhar7199a942019-09-10 22:37:39449 * @param {!Array<!SDK.NetworkRequest.BlockedSetCookieWithReason>=} blockedResponseCookies
Blink Reformat4c46d092018-04-07 15:32:37450 */
Joey Arhar7199a942019-09-10 22:37:39451 _refreshHeaders(title, headers, headersTreeElement, provisionalHeaders, blockedResponseCookies) {
Blink Reformat4c46d092018-04-07 15:32:37452 headersTreeElement.removeChildren();
453
454 const length = headers.length;
455 this._refreshHeadersTitle(title, headersTreeElement, length);
456
457 if (provisionalHeaders) {
458 const cautionText = Common.UIString('Provisional headers are shown');
459 const cautionFragment = createDocumentFragment();
Joel Einbinder7fbe24c2019-01-24 05:19:01460 cautionFragment.createChild('span', '', 'dt-icon-label').type = 'smallicon-warning';
Blink Reformat4c46d092018-04-07 15:32:37461 cautionFragment.createChild('div', 'caution').textContent = cautionText;
462 const cautionTreeElement = new UI.TreeElement(cautionFragment);
Blink Reformat4c46d092018-04-07 15:32:37463 headersTreeElement.appendChild(cautionTreeElement);
464 }
465
Joey Arhar41a5fad2019-09-13 22:18:45466 /** @type {!Map<string, !Array<!Protocol.Network.SetCookieBlockedReason>>} */
467 const blockedCookieLineToReasons = new Map();
Joey Arhar7199a942019-09-10 22:37:39468 if (blockedResponseCookies) {
469 blockedResponseCookies.forEach(blockedCookie => {
Joey Arhar41a5fad2019-09-13 22:18:45470 blockedCookieLineToReasons.set(blockedCookie.cookieLine, blockedCookie.blockedReasons);
Joey Arhar7199a942019-09-10 22:37:39471 });
472 }
473
Blink Reformat4c46d092018-04-07 15:32:37474 headersTreeElement.hidden = !length && !provisionalHeaders;
475 for (let i = 0; i < length; ++i) {
476 const headerTreeElement = new UI.TreeElement(this._formatHeader(headers[i].name, headers[i].value));
Blink Reformat4c46d092018-04-07 15:32:37477 headerTreeElement[Network.RequestHeadersView._headerNameSymbol] = headers[i].name;
Joey Arhar7199a942019-09-10 22:37:39478
479 if (headers[i].name.toLowerCase() === 'set-cookie') {
Joey Arhar41a5fad2019-09-13 22:18:45480 const matchingBlockedReasons = blockedCookieLineToReasons.get(headers[i].value);
481 if (matchingBlockedReasons) {
Joey Arhar7199a942019-09-10 22:37:39482 const icon = UI.Icon.create('smallicon-warning', '');
483 headerTreeElement.listItemElement.appendChild(icon);
Joey Arhar41a5fad2019-09-13 22:18:45484
485 let titleText = '';
486 for (const blockedReason of matchingBlockedReasons) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34487 if (titleText) {
Joey Arhar41a5fad2019-09-13 22:18:45488 titleText += '\n';
Tim van der Lippe1d6e57a2019-09-30 11:55:34489 }
Joey Arhar41a5fad2019-09-13 22:18:45490 titleText += SDK.NetworkRequest.setCookieBlockedReasonToUiString(blockedReason);
491 }
492 icon.title = titleText;
Joey Arhar7199a942019-09-10 22:37:39493 }
494 }
495
496 headersTreeElement.appendChild(headerTreeElement);
Blink Reformat4c46d092018-04-07 15:32:37497 }
498 }
499
500 /**
501 * @param {string} title
502 * @param {number} count
503 * @param {string} headersText
504 * @param {!UI.TreeElement} headersTreeElement
505 */
506 _refreshHeadersText(title, count, headersText, headersTreeElement) {
507 this._populateTreeElementWithSourceText(headersTreeElement, headersText);
508 this._refreshHeadersTitle(title, headersTreeElement, count);
509 }
510
511 _refreshRemoteAddress() {
512 const remoteAddress = this._request.remoteAddress();
513 const treeElement = this._remoteAddressItem;
514 treeElement.hidden = !remoteAddress;
Tim van der Lippe1d6e57a2019-09-30 11:55:34515 if (remoteAddress) {
Blink Reformat4c46d092018-04-07 15:32:37516 treeElement.title = this._formatHeader(Common.UIString('Remote Address'), remoteAddress);
Tim van der Lippe1d6e57a2019-09-30 11:55:34517 }
Blink Reformat4c46d092018-04-07 15:32:37518 }
519
520 _refreshReferrerPolicy() {
521 const referrerPolicy = this._request.referrerPolicy();
522 const treeElement = this._referrerPolicyItem;
523 treeElement.hidden = !referrerPolicy;
Tim van der Lippe1d6e57a2019-09-30 11:55:34524 if (referrerPolicy) {
Blink Reformat4c46d092018-04-07 15:32:37525 treeElement.title = this._formatHeader(Common.UIString('Referrer Policy'), referrerPolicy);
Tim van der Lippe1d6e57a2019-09-30 11:55:34526 }
Blink Reformat4c46d092018-04-07 15:32:37527 }
528
529 /**
530 * @param {!Event} event
531 */
532 _toggleRequestHeadersText(event) {
533 this._showRequestHeadersText = !this._showRequestHeadersText;
534 this._refreshRequestHeaders();
535 event.consume();
536 }
537
538 /**
539 * @param {!Event} event
540 */
541 _toggleResponseHeadersText(event) {
542 this._showResponseHeadersText = !this._showResponseHeadersText;
543 this._refreshResponseHeaders();
544 event.consume();
545 }
546
547 /**
548 * @param {string} title
549 * @return {!Element}
550 */
551 _createToggleButton(title) {
552 const button = createElementWithClass('span', 'header-toggle');
553 button.textContent = title;
554 return button;
555 }
556
557 /**
558 * @param {boolean} isHeadersTextShown
559 * @return {!Element}
560 */
561 _createHeadersToggleButton(isHeadersTextShown) {
562 const toggleTitle = isHeadersTextShown ? Common.UIString('view parsed') : Common.UIString('view source');
563 return this._createToggleButton(toggleTitle);
564 }
565
566 _clearHighlight() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34567 if (this._highlightedElement) {
Blink Reformat4c46d092018-04-07 15:32:37568 this._highlightedElement.listItemElement.classList.remove('header-highlight');
Tim van der Lippe1d6e57a2019-09-30 11:55:34569 }
Blink Reformat4c46d092018-04-07 15:32:37570 this._highlightedElement = null;
571 }
572
573
574 /**
575 * @param {?UI.TreeElement} category
576 * @param {string} name
577 */
578 _revealAndHighlight(category, name) {
579 this._clearHighlight();
580 for (const element of category.children()) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34581 if (element[Network.RequestHeadersView._headerNameSymbol] !== name) {
Blink Reformat4c46d092018-04-07 15:32:37582 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34583 }
Blink Reformat4c46d092018-04-07 15:32:37584 this._highlightedElement = element;
585 element.reveal();
586 element.listItemElement.classList.add('header-highlight');
587 return;
588 }
589 }
590
591 /**
592 * @param {string} header
593 */
594 revealRequestHeader(header) {
595 this._revealAndHighlight(this._requestHeadersCategory, header);
596 }
597
598 /**
599 * @param {string} header
600 */
601 revealResponseHeader(header) {
602 this._revealAndHighlight(this._responseHeadersCategory, header);
603 }
604};
605
606Network.RequestHeadersView._headerNameSymbol = Symbol('HeaderName');
607Network.RequestHeadersView._viewSourceSymbol = Symbol('ViewSource');
608
609/**
610 * @unrestricted
611 */
612Network.RequestHeadersView.Category = class extends UI.TreeElement {
613 /**
614 * @param {!UI.TreeOutline} root
615 * @param {string} name
616 * @param {string=} title
617 */
618 constructor(root, name, title) {
619 super(title || '', true);
Blink Reformat4c46d092018-04-07 15:32:37620 this.toggleOnClick = true;
621 this.hidden = true;
622 this._expandedSetting = Common.settings.createSetting('request-info-' + name + '-category-expanded', true);
623 this.expanded = this._expandedSetting.get();
624 root.appendChild(this);
625 }
626
627 /**
628 * @return {!UI.TreeElement}
629 */
630 createLeaf() {
631 const leaf = new UI.TreeElement();
Blink Reformat4c46d092018-04-07 15:32:37632 this.appendChild(leaf);
633 return leaf;
634 }
635
636 /**
637 * @override
638 */
639 onexpand() {
640 this._expandedSetting.set(true);
641 }
642
643 /**
644 * @override
645 */
646 oncollapse() {
647 this._expandedSetting.set(false);
648 }
649};