blob: 35c7937a1ffd93bc9cc925f477a4ae378d0d2d75 [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371/*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008, 2009 Anthony Ricaud <[email protected]>
4 * Copyright (C) 2011 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
31/**
32 * @implements {SDK.SDKModelObserver<!SDK.NetworkManager>}
33 */
Paul Lewis56509652019-12-06 12:51:5834export default class NetworkLogView extends UI.VBox {
Blink Reformat4c46d092018-04-07 15:32:3735 /**
36 * @param {!UI.FilterBar} filterBar
37 * @param {!Element} progressBarContainer
38 * @param {!Common.Setting} networkLogLargeRowsSetting
39 */
40 constructor(filterBar, progressBarContainer, networkLogLargeRowsSetting) {
41 super();
42 this.setMinimumSize(50, 64);
43 this.registerRequiredCSS('network/networkLogView.css');
44
45 this.element.id = 'network-container';
Brandon Goddard88d885a2019-10-31 16:11:0546 this.element.classList.add('no-node-selected');
Blink Reformat4c46d092018-04-07 15:32:3747
48 this._networkHideDataURLSetting = Common.settings.createSetting('networkHideDataURL', false);
Jan Scheffler1ae7c9e2019-12-03 15:48:3749 this._networkShowIssuesOnlySetting = Common.settings.createSetting('networkShowIssuesOnly', false);
Blink Reformat4c46d092018-04-07 15:32:3750 this._networkResourceTypeFiltersSetting = Common.settings.createSetting('networkResourceTypeFilters', {});
51
52 this._rawRowHeight = 0;
53 this._progressBarContainer = progressBarContainer;
54 this._networkLogLargeRowsSetting = networkLogLargeRowsSetting;
55 this._networkLogLargeRowsSetting.addChangeListener(updateRowHeight.bind(this), this);
56
57 /**
Paul Lewis56509652019-12-06 12:51:5858 * @this {NetworkLogView}
Blink Reformat4c46d092018-04-07 15:32:3759 */
60 function updateRowHeight() {
61 this._rawRowHeight = !!this._networkLogLargeRowsSetting.get() ? 41 : 21;
62 this._rowHeight = this._computeRowHeight();
63 }
64 this._rawRowHeight = 0;
65 this._rowHeight = 0;
66 updateRowHeight.call(this);
67
68 /** @type {!Network.NetworkTransferTimeCalculator} */
69 this._timeCalculator = new Network.NetworkTransferTimeCalculator();
70 /** @type {!Network.NetworkTransferDurationCalculator} */
71 this._durationCalculator = new Network.NetworkTransferDurationCalculator();
72 this._calculator = this._timeCalculator;
73
74 this._columns = new Network.NetworkLogViewColumns(
75 this, this._timeCalculator, this._durationCalculator, networkLogLargeRowsSetting);
76 this._columns.show(this.element);
77
78 /** @type {!Set<!SDK.NetworkRequest>} */
79 this._staleRequests = new Set();
80 /** @type {number} */
81 this._mainRequestLoadTime = -1;
82 /** @type {number} */
83 this._mainRequestDOMContentLoadedTime = -1;
84 this._highlightedSubstringChanges = [];
85
86 /** @type {!Array.<!Network.NetworkLogView.Filter>} */
87 this._filters = [];
88 /** @type {?Network.NetworkLogView.Filter} */
89 this._timeFilter = null;
90 /** @type {?Network.NetworkNode} */
91 this._hoveredNode = null;
92 /** @type {?Element} */
93 this._recordingHint = null;
94 /** @type {?number} */
95 this._refreshRequestId = null;
96 /** @type {?Network.NetworkRequestNode} */
97 this._highlightedNode = null;
98
99 this.linkifier = new Components.Linkifier();
Blink Reformat4c46d092018-04-07 15:32:37100
101 this._recording = false;
102 this._needsRefresh = false;
103
104 this._headerHeight = 0;
105
Paul Lewis56509652019-12-06 12:51:58106 /** @type {!Map<string, !GroupLookupInterface>} */
Blink Reformat4c46d092018-04-07 15:32:37107 this._groupLookups = new Map();
108 this._groupLookups.set('Frame', new Network.NetworkFrameGrouper(this));
109
Paul Lewis56509652019-12-06 12:51:58110 /** @type {?GroupLookupInterface} */
Blink Reformat4c46d092018-04-07 15:32:37111 this._activeGroupLookup = null;
112
113 this._textFilterUI = new UI.TextFilterUI();
114 this._textFilterUI.addEventListener(UI.FilterUI.Events.FilterChanged, this._filterChanged, this);
115 filterBar.addFilter(this._textFilterUI);
116
117 this._dataURLFilterUI = new UI.CheckboxFilterUI(
118 'hide-data-url', Common.UIString('Hide data URLs'), true, this._networkHideDataURLSetting);
119 this._dataURLFilterUI.addEventListener(UI.FilterUI.Events.FilterChanged, this._filterChanged.bind(this), this);
Joey Arharba99d622019-02-01 19:10:48120 this._dataURLFilterUI.element().title = ls`Hides data: and blob: URLs`;
Blink Reformat4c46d092018-04-07 15:32:37121 filterBar.addFilter(this._dataURLFilterUI);
122
123 const filterItems =
124 Object.values(Common.resourceCategories)
125 .map(category => ({name: category.title, label: category.shortTitle, title: category.title}));
126 this._resourceCategoryFilterUI = new UI.NamedBitSetFilterUI(filterItems, this._networkResourceTypeFiltersSetting);
Brandon Goddard568cef12019-06-27 17:18:20127 UI.ARIAUtils.setAccessibleName(this._resourceCategoryFilterUI.element(), ls`Resource types to include`);
Blink Reformat4c46d092018-04-07 15:32:37128 this._resourceCategoryFilterUI.addEventListener(
129 UI.FilterUI.Events.FilterChanged, this._filterChanged.bind(this), this);
130 filterBar.addFilter(this._resourceCategoryFilterUI);
131
Jan Scheffler341eea52019-12-12 09:08:41132 this._onlyIssuesFilterUI =
133 new UI.CheckboxFilterUI('only-show-issues', ls`Has blocked cookies`, true, this._networkShowIssuesOnlySetting);
Jan Scheffler1ae7c9e2019-12-03 15:48:37134 this._onlyIssuesFilterUI.addEventListener(UI.FilterUI.Events.FilterChanged, this._filterChanged.bind(this), this);
Jan Scheffler341eea52019-12-12 09:08:41135 this._onlyIssuesFilterUI.element().title = ls`Only show requests with blocked response cookies`;
Jan Scheffler1ae7c9e2019-12-03 15:48:37136 filterBar.addFilter(this._onlyIssuesFilterUI);
137
138
Paul Lewis56509652019-12-06 12:51:58139 this._filterParser = new TextUtils.FilterParser(_searchKeys);
140 this._suggestionBuilder = new UI.FilterSuggestionBuilder(_searchKeys, NetworkLogView._sortSearchValues);
Blink Reformat4c46d092018-04-07 15:32:37141 this._resetSuggestionBuilder();
142
143 this._dataGrid = this._columns.dataGrid();
144 this._setupDataGrid();
145 this._columns.sortByCurrentColumn();
Erik Luo0187a022018-05-31 18:35:49146 filterBar.filterButton().addEventListener(
147 UI.ToolbarButton.Events.Click, this._dataGrid.scheduleUpdate.bind(this._dataGrid, true /* isFromUser */));
Blink Reformat4c46d092018-04-07 15:32:37148
Joey Arhara86c14e2019-03-12 03:20:50149 this._summaryToolbar = new UI.Toolbar('network-summary-bar', this.element);
Blink Reformat4c46d092018-04-07 15:32:37150
151 new UI.DropTarget(
152 this.element, [UI.DropTarget.Type.File], Common.UIString('Drop HAR files here'), this._handleDrop.bind(this));
153
154 Common.moduleSetting('networkColorCodeResourceTypes')
155 .addChangeListener(this._invalidateAllItems.bind(this, false), this);
156
157 SDK.targetManager.observeModels(SDK.NetworkManager, this);
Pavel Feldman18d13562018-07-31 03:31:18158 SDK.networkLog.addEventListener(SDK.NetworkLog.Events.RequestAdded, this._onRequestUpdated, this);
159 SDK.networkLog.addEventListener(SDK.NetworkLog.Events.RequestUpdated, this._onRequestUpdated, this);
160 SDK.networkLog.addEventListener(SDK.NetworkLog.Events.Reset, this._reset, this);
Blink Reformat4c46d092018-04-07 15:32:37161
162 this._updateGroupByFrame();
163 Common.moduleSetting('network.group-by-frame').addChangeListener(() => this._updateGroupByFrame());
164
165 this._filterBar = filterBar;
Blink Reformat4c46d092018-04-07 15:32:37166 }
167
Blink Reformat4c46d092018-04-07 15:32:37168 _updateGroupByFrame() {
169 const value = Common.moduleSetting('network.group-by-frame').get();
170 this._setGrouping(value ? 'Frame' : null);
171 }
172
173 /**
174 * @param {string} key
175 * @param {!Array<string>} values
176 */
177 static _sortSearchValues(key, values) {
Paul Lewis56509652019-12-06 12:51:58178 if (key === FilterType.Priority) {
Blink Reformat4c46d092018-04-07 15:32:37179 values.sort((a, b) => {
180 const aPriority = /** @type {!Protocol.Network.ResourcePriority} */ (PerfUI.uiLabelToNetworkPriority(a));
181 const bPriority = /** @type {!Protocol.Network.ResourcePriority} */ (PerfUI.uiLabelToNetworkPriority(b));
182 return PerfUI.networkPriorityWeight(aPriority) - PerfUI.networkPriorityWeight(bPriority);
183 });
184 } else {
185 values.sort();
186 }
187 }
188
189 /**
190 * @param {!Network.NetworkLogView.Filter} filter
191 * @param {!SDK.NetworkRequest} request
192 * @return {boolean}
193 */
194 static _negativeFilter(filter, request) {
195 return !filter(request);
196 }
197
198 /**
199 * @param {?RegExp} regex
200 * @param {!SDK.NetworkRequest} request
201 * @return {boolean}
202 */
203 static _requestPathFilter(regex, request) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34204 if (!regex) {
Blink Reformat4c46d092018-04-07 15:32:37205 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:34206 }
Blink Reformat4c46d092018-04-07 15:32:37207
208 return regex.test(request.path() + '/' + request.name());
209 }
210
211 /**
212 * @param {string} domain
213 * @return {!Array.<string>}
214 */
215 static _subdomains(domain) {
216 const result = [domain];
217 let indexOfPeriod = domain.indexOf('.');
218 while (indexOfPeriod !== -1) {
219 result.push('*' + domain.substring(indexOfPeriod));
220 indexOfPeriod = domain.indexOf('.', indexOfPeriod + 1);
221 }
222 return result;
223 }
224
225 /**
226 * @param {string} value
227 * @return {!Network.NetworkLogView.Filter}
228 */
229 static _createRequestDomainFilter(value) {
230 /**
231 * @param {string} string
232 * @return {string}
233 */
234 function escapeForRegExp(string) {
235 return string.escapeForRegExp();
236 }
237 const escapedPattern = value.split('*').map(escapeForRegExp).join('.*');
Paul Lewis56509652019-12-06 12:51:58238 return NetworkLogView._requestDomainFilter.bind(null, new RegExp('^' + escapedPattern + '$', 'i'));
Blink Reformat4c46d092018-04-07 15:32:37239 }
240
241 /**
242 * @param {!RegExp} regex
243 * @param {!SDK.NetworkRequest} request
244 * @return {boolean}
245 */
246 static _requestDomainFilter(regex, request) {
247 return regex.test(request.domain);
248 }
249
250 /**
251 * @param {!SDK.NetworkRequest} request
252 * @return {boolean}
253 */
254 static _runningRequestFilter(request) {
255 return !request.finished;
256 }
257
258 /**
259 * @param {!SDK.NetworkRequest} request
260 * @return {boolean}
261 */
262 static _fromCacheRequestFilter(request) {
263 return request.cached();
264 }
265
266 /**
Joey Arhard183e7e2019-02-28 03:37:05267 * @param {!SDK.NetworkRequest} request
268 * @return {boolean}
269 */
270 static _interceptedByServiceWorkerFilter(request) {
271 return request.fetchedViaServiceWorker;
272 }
273
274 /**
275 * @param {!SDK.NetworkRequest} request
276 * @return {boolean}
277 */
278 static _initiatedByServiceWorkerFilter(request) {
279 return request.initiatedByServiceWorker();
280 }
281
282 /**
Blink Reformat4c46d092018-04-07 15:32:37283 * @param {string} value
284 * @param {!SDK.NetworkRequest} request
285 * @return {boolean}
286 */
287 static _requestResponseHeaderFilter(value, request) {
288 return request.responseHeaderValue(value) !== undefined;
289 }
290
291 /**
292 * @param {string} value
293 * @param {!SDK.NetworkRequest} request
294 * @return {boolean}
295 */
296 static _requestMethodFilter(value, request) {
297 return request.requestMethod === value;
298 }
299
300 /**
301 * @param {string} value
302 * @param {!SDK.NetworkRequest} request
303 * @return {boolean}
304 */
305 static _requestPriorityFilter(value, request) {
306 return request.priority() === value;
307 }
308
309 /**
310 * @param {string} value
311 * @param {!SDK.NetworkRequest} request
312 * @return {boolean}
313 */
314 static _requestMimeTypeFilter(value, request) {
315 return request.mimeType === value;
316 }
317
318 /**
Paul Lewis56509652019-12-06 12:51:58319 * @param {!MixedContentFilterValues} value
Blink Reformat4c46d092018-04-07 15:32:37320 * @param {!SDK.NetworkRequest} request
321 * @return {boolean}
322 */
323 static _requestMixedContentFilter(value, request) {
Paul Lewis56509652019-12-06 12:51:58324 if (value === MixedContentFilterValues.Displayed) {
Blink Reformat4c46d092018-04-07 15:32:37325 return request.mixedContentType === Protocol.Security.MixedContentType.OptionallyBlockable;
Paul Lewis56509652019-12-06 12:51:58326 } else if (value === MixedContentFilterValues.Blocked) {
Blink Reformat4c46d092018-04-07 15:32:37327 return request.mixedContentType === Protocol.Security.MixedContentType.Blockable && request.wasBlocked();
Paul Lewis56509652019-12-06 12:51:58328 } else if (value === MixedContentFilterValues.BlockOverridden) {
Blink Reformat4c46d092018-04-07 15:32:37329 return request.mixedContentType === Protocol.Security.MixedContentType.Blockable && !request.wasBlocked();
Paul Lewis56509652019-12-06 12:51:58330 } else if (value === MixedContentFilterValues.All) {
Blink Reformat4c46d092018-04-07 15:32:37331 return request.mixedContentType !== Protocol.Security.MixedContentType.None;
Tim van der Lippe1d6e57a2019-09-30 11:55:34332 }
Blink Reformat4c46d092018-04-07 15:32:37333
334 return false;
335 }
336
337 /**
338 * @param {string} value
339 * @param {!SDK.NetworkRequest} request
340 * @return {boolean}
341 */
342 static _requestSchemeFilter(value, request) {
343 return request.scheme === value;
344 }
345
346 /**
347 * @param {string} value
348 * @param {!SDK.NetworkRequest} request
349 * @return {boolean}
350 */
Jan Scheffler341eea52019-12-12 09:08:41351 static _requestCookieDomainFilter(value, request) {
352 return request.allCookiesIncludingBlockedOnes().some(cookie => cookie.domain() === value);
353 }
354
355 /**
356 * @param {string} value
357 * @param {!SDK.NetworkRequest} request
358 * @return {boolean}
359 */
360 static _requestCookieNameFilter(value, request) {
361 return request.allCookiesIncludingBlockedOnes().some(cookie => cookie.name() === value);
362 }
363
364 /**
365 * @param {string} value
366 * @param {!SDK.NetworkRequest} request
367 * @return {boolean}
368 */
369 static _requestCookieValueFilter(value, request) {
370 return request.allCookiesIncludingBlockedOnes().some(cookie => cookie.value() === value);
371 }
372
373 /**
374 * @param {string} value
375 * @param {!SDK.NetworkRequest} request
376 * @return {boolean}
377 */
Blink Reformat4c46d092018-04-07 15:32:37378 static _requestSetCookieDomainFilter(value, request) {
Jan Scheffler341eea52019-12-12 09:08:41379 return request.responseCookies.some(cookie => cookie.domain() === value);
Blink Reformat4c46d092018-04-07 15:32:37380 }
381
382 /**
383 * @param {string} value
384 * @param {!SDK.NetworkRequest} request
385 * @return {boolean}
386 */
387 static _requestSetCookieNameFilter(value, request) {
Jan Scheffler341eea52019-12-12 09:08:41388 return request.responseCookies.some(cookie => cookie.name() === value);
Blink Reformat4c46d092018-04-07 15:32:37389 }
390
391 /**
392 * @param {string} value
393 * @param {!SDK.NetworkRequest} request
394 * @return {boolean}
395 */
396 static _requestSetCookieValueFilter(value, request) {
Jan Scheffler341eea52019-12-12 09:08:41397 return request.responseCookies.some(cookie => cookie.value() === value);
Blink Reformat4c46d092018-04-07 15:32:37398 }
399
400 /**
401 * @param {number} value
402 * @param {!SDK.NetworkRequest} request
403 * @return {boolean}
404 */
405 static _requestSizeLargerThanFilter(value, request) {
406 return request.transferSize >= value;
407 }
408
409 /**
410 * @param {string} value
411 * @param {!SDK.NetworkRequest} request
412 * @return {boolean}
413 */
414 static _statusCodeFilter(value, request) {
415 return ('' + request.statusCode) === value;
416 }
417
418 /**
419 * @param {!SDK.NetworkRequest} request
420 * @return {boolean}
421 */
422 static HTTPRequestsFilter(request) {
Paul Lewis56509652019-12-06 12:51:58423 return request.parsedURL.isValid && (request.scheme in HTTPSchemas);
Blink Reformat4c46d092018-04-07 15:32:37424 }
425
426 /**
Blink Reformat4c46d092018-04-07 15:32:37427 * @param {number} windowStart
428 * @param {number} windowEnd
429 * @param {!SDK.NetworkRequest} request
430 * @return {boolean}
431 */
432 static _requestTimeFilter(windowStart, windowEnd, request) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34433 if (request.issueTime() > windowEnd) {
Blink Reformat4c46d092018-04-07 15:32:37434 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:34435 }
436 if (request.endTime !== -1 && request.endTime < windowStart) {
Blink Reformat4c46d092018-04-07 15:32:37437 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:34438 }
Blink Reformat4c46d092018-04-07 15:32:37439 return true;
440 }
441
442 /**
443 * @param {!SDK.NetworkRequest} request
444 */
445 static _copyRequestHeaders(request) {
Tim van der Lippe50cfa9b2019-10-01 10:40:58446 Host.InspectorFrontendHost.copyText(request.requestHeadersText());
Blink Reformat4c46d092018-04-07 15:32:37447 }
448
449 /**
450 * @param {!SDK.NetworkRequest} request
451 */
452 static _copyResponseHeaders(request) {
Tim van der Lippe50cfa9b2019-10-01 10:40:58453 Host.InspectorFrontendHost.copyText(request.responseHeadersText);
Blink Reformat4c46d092018-04-07 15:32:37454 }
455
456 /**
457 * @param {!SDK.NetworkRequest} request
458 */
459 static async _copyResponse(request) {
460 const contentData = await request.contentData();
Ingvar Stepanyan1c771842018-10-10 14:35:08461 let content = contentData.content || '';
Tim van der Lippe1d6e57a2019-09-30 11:55:34462 if (!request.contentType().isTextType()) {
Ingvar Stepanyan1c771842018-10-10 14:35:08463 content = Common.ContentProvider.contentAsDataURL(content, request.mimeType, contentData.encoded);
Tim van der Lippe1d6e57a2019-09-30 11:55:34464 } else if (contentData.encoded) {
Ingvar Stepanyan1c771842018-10-10 14:35:08465 content = window.atob(content);
Tim van der Lippe1d6e57a2019-09-30 11:55:34466 }
Tim van der Lippe50cfa9b2019-10-01 10:40:58467 Host.InspectorFrontendHost.copyText(content);
Blink Reformat4c46d092018-04-07 15:32:37468 }
469
470 /**
471 * @param {!DataTransfer} dataTransfer
472 */
473 _handleDrop(dataTransfer) {
474 const items = dataTransfer.items;
Tim van der Lippe1d6e57a2019-09-30 11:55:34475 if (!items.length) {
Blink Reformat4c46d092018-04-07 15:32:37476 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34477 }
Blink Reformat4c46d092018-04-07 15:32:37478 const entry = items[0].webkitGetAsEntry();
Tim van der Lippe1d6e57a2019-09-30 11:55:34479 if (entry.isDirectory) {
Blink Reformat4c46d092018-04-07 15:32:37480 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34481 }
Blink Reformat4c46d092018-04-07 15:32:37482
Joey Arhar0e1093c2019-05-21 00:34:22483 entry.file(this.onLoadFromFile.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37484 }
485
486 /**
487 * @param {!File} file
488 */
Joey Arhar0e1093c2019-05-21 00:34:22489 async onLoadFromFile(file) {
Blink Reformat4c46d092018-04-07 15:32:37490 const outputStream = new Common.StringOutputStream();
491 const reader = new Bindings.ChunkedFileReader(file, /* chunkSize */ 10000000);
492 const success = await reader.read(outputStream);
493 if (!success) {
494 this._harLoadFailed(reader.error().message);
495 return;
496 }
497 let harRoot;
498 try {
499 // HARRoot and JSON.parse might throw.
500 harRoot = new HARImporter.HARRoot(JSON.parse(outputStream.data()));
501 } catch (e) {
502 this._harLoadFailed(e);
503 return;
504 }
Pavel Feldman18d13562018-07-31 03:31:18505 SDK.networkLog.importRequests(HARImporter.Importer.requestsFromHARLog(harRoot.log));
Blink Reformat4c46d092018-04-07 15:32:37506 }
507
508 /**
509 * @param {string} message
510 */
511 _harLoadFailed(message) {
512 Common.console.error('Failed to load HAR file with following error: ' + message);
513 }
514
515 /**
516 * @param {?string} groupKey
517 */
518 _setGrouping(groupKey) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34519 if (this._activeGroupLookup) {
Blink Reformat4c46d092018-04-07 15:32:37520 this._activeGroupLookup.reset();
Tim van der Lippe1d6e57a2019-09-30 11:55:34521 }
Blink Reformat4c46d092018-04-07 15:32:37522 const groupLookup = groupKey ? this._groupLookups.get(groupKey) || null : null;
523 this._activeGroupLookup = groupLookup;
524 this._invalidateAllItems();
525 }
526
527 /**
528 * @return {number}
529 */
530 _computeRowHeight() {
531 return Math.round(this._rawRowHeight * window.devicePixelRatio) / window.devicePixelRatio;
532 }
533
534 /**
535 * @param {!SDK.NetworkRequest} request
536 * @return {?Network.NetworkRequestNode}
537 */
538 nodeForRequest(request) {
Paul Lewis56509652019-12-06 12:51:58539 return request[_networkNodeSymbol] || null;
Blink Reformat4c46d092018-04-07 15:32:37540 }
541
542 /**
543 * @return {number}
544 */
545 headerHeight() {
546 return this._headerHeight;
547 }
548
549 /**
550 * @param {boolean} recording
551 */
552 setRecording(recording) {
553 this._recording = recording;
554 this._updateSummaryBar();
555 }
556
557 /**
558 * @override
559 * @param {!SDK.NetworkManager} networkManager
560 */
561 modelAdded(networkManager) {
562 // TODO(allada) Remove dependency on networkManager and instead use NetworkLog and PageLoad for needed data.
Tim van der Lippe1d6e57a2019-09-30 11:55:34563 if (networkManager.target().parentTarget()) {
Blink Reformat4c46d092018-04-07 15:32:37564 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34565 }
Blink Reformat4c46d092018-04-07 15:32:37566 const resourceTreeModel = networkManager.target().model(SDK.ResourceTreeModel);
567 if (resourceTreeModel) {
568 resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.Load, this._loadEventFired, this);
569 resourceTreeModel.addEventListener(
570 SDK.ResourceTreeModel.Events.DOMContentLoaded, this._domContentLoadedEventFired, this);
571 }
572 }
573
574 /**
575 * @override
576 * @param {!SDK.NetworkManager} networkManager
577 */
578 modelRemoved(networkManager) {
579 if (!networkManager.target().parentTarget()) {
580 const resourceTreeModel = networkManager.target().model(SDK.ResourceTreeModel);
581 if (resourceTreeModel) {
582 resourceTreeModel.removeEventListener(SDK.ResourceTreeModel.Events.Load, this._loadEventFired, this);
583 resourceTreeModel.removeEventListener(
584 SDK.ResourceTreeModel.Events.DOMContentLoaded, this._domContentLoadedEventFired, this);
585 }
586 }
587 }
588
589 /**
590 * @param {number} start
591 * @param {number} end
592 */
593 setWindow(start, end) {
594 if (!start && !end) {
595 this._timeFilter = null;
596 this._timeCalculator.setWindow(null);
597 } else {
Paul Lewis56509652019-12-06 12:51:58598 this._timeFilter = NetworkLogView._requestTimeFilter.bind(null, start, end);
Blink Reformat4c46d092018-04-07 15:32:37599 this._timeCalculator.setWindow(new Network.NetworkTimeBoundary(start, end));
600 }
601 this._filterRequests();
602 }
603
Brandon Goddard88d885a2019-10-31 16:11:05604 resetFocus() {
605 this._dataGrid.element.focus();
Blink Reformat4c46d092018-04-07 15:32:37606 }
607
608 _resetSuggestionBuilder() {
609 this._suggestionBuilder.clear();
Paul Lewis56509652019-12-06 12:51:58610 this._suggestionBuilder.addItem(FilterType.Is, IsFilterType.Running);
611 this._suggestionBuilder.addItem(FilterType.Is, IsFilterType.FromCache);
612 this._suggestionBuilder.addItem(FilterType.Is, IsFilterType.ServiceWorkerIntercepted);
613 this._suggestionBuilder.addItem(FilterType.Is, IsFilterType.ServiceWorkerInitiated);
614 this._suggestionBuilder.addItem(FilterType.LargerThan, '100');
615 this._suggestionBuilder.addItem(FilterType.LargerThan, '10k');
616 this._suggestionBuilder.addItem(FilterType.LargerThan, '1M');
Blink Reformat4c46d092018-04-07 15:32:37617 this._textFilterUI.setSuggestionProvider(this._suggestionBuilder.completions.bind(this._suggestionBuilder));
618 }
619
620 /**
621 * @param {!Common.Event} event
622 */
623 _filterChanged(event) {
624 this.removeAllNodeHighlights();
625 this._parseFilterQuery(this._textFilterUI.value());
626 this._filterRequests();
Blink Reformat4c46d092018-04-07 15:32:37627 }
628
629 _showRecordingHint() {
630 this._hideRecordingHint();
631 this._recordingHint = this.element.createChild('div', 'network-status-pane fill');
632 const hintText = this._recordingHint.createChild('div', 'recording-hint');
Joey Arhar0585e6f2018-10-30 23:11:18633
634 let reloadShortcutNode = null;
635 const reloadShortcutDescriptor = UI.shortcutRegistry.shortcutDescriptorsForAction('inspector_main.reload')[0];
636 if (reloadShortcutDescriptor) {
637 reloadShortcutNode = this._recordingHint.createChild('b');
638 reloadShortcutNode.textContent = reloadShortcutDescriptor.name;
639 }
Blink Reformat4c46d092018-04-07 15:32:37640
641 if (this._recording) {
642 const recordingText = hintText.createChild('span');
643 recordingText.textContent = Common.UIString('Recording network activity\u2026');
Joey Arhar0585e6f2018-10-30 23:11:18644 if (reloadShortcutNode) {
645 hintText.createChild('br');
646 hintText.appendChild(
647 UI.formatLocalized('Perform a request or hit %s to record the reload.', [reloadShortcutNode]));
648 }
Blink Reformat4c46d092018-04-07 15:32:37649 } else {
650 const recordNode = hintText.createChild('b');
651 recordNode.textContent = UI.shortcutRegistry.shortcutTitleForAction('network.toggle-recording');
Joey Arhar0585e6f2018-10-30 23:11:18652 if (reloadShortcutNode) {
653 hintText.appendChild(UI.formatLocalized(
654 'Record (%s) or reload (%s) to display network activity.', [recordNode, reloadShortcutNode]));
655 } else {
656 hintText.appendChild(UI.formatLocalized('Record (%s) to display network activity.', [recordNode]));
657 }
Blink Reformat4c46d092018-04-07 15:32:37658 }
Kayce Basques5444c1b2019-02-15 20:32:53659 hintText.createChild('br');
660 hintText.appendChild(UI.XLink.create(
661 'https://developers.google.com/web/tools/chrome-devtools/network/?utm_source=devtools&utm_campaign=2019Q1',
662 'Learn more'));
Amanda Baker6761aae2019-11-05 18:59:11663
664 this._setHidden(true);
Brandon Goddardc992d522020-01-08 21:44:57665 this._dataGrid.updateGridAccessibleName('');
Blink Reformat4c46d092018-04-07 15:32:37666 }
667
668 _hideRecordingHint() {
Amanda Baker6761aae2019-11-05 18:59:11669 this._setHidden(false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34670 if (this._recordingHint) {
Blink Reformat4c46d092018-04-07 15:32:37671 this._recordingHint.remove();
Tim van der Lippe1d6e57a2019-09-30 11:55:34672 }
Brandon Goddardc992d522020-01-08 21:44:57673 this._dataGrid.updateGridAccessibleName(ls`Network Data Available`);
Blink Reformat4c46d092018-04-07 15:32:37674 this._recordingHint = null;
675 }
676
677 /**
Amanda Baker6761aae2019-11-05 18:59:11678 * @param {boolean} value
679 */
680 _setHidden(value) {
681 this._columns.setHidden(value);
682 UI.ARIAUtils.setHidden(this._summaryToolbar.element, value);
683 }
684
685 /**
Blink Reformat4c46d092018-04-07 15:32:37686 * @override
687 * @return {!Array.<!Element>}
688 */
689 elementsToRestoreScrollPositionsFor() {
690 if (!this._dataGrid) // Not initialized yet.
Tim van der Lippe1d6e57a2019-09-30 11:55:34691 {
Blink Reformat4c46d092018-04-07 15:32:37692 return [];
Tim van der Lippe1d6e57a2019-09-30 11:55:34693 }
Blink Reformat4c46d092018-04-07 15:32:37694 return [this._dataGrid.scrollContainer];
695 }
696
697 columnExtensionResolved() {
698 this._invalidateAllItems(true);
699 }
700
701 _setupDataGrid() {
702 this._dataGrid.setRowContextMenuCallback((contextMenu, node) => {
703 const request = node.request();
Tim van der Lippe1d6e57a2019-09-30 11:55:34704 if (request) {
Blink Reformat4c46d092018-04-07 15:32:37705 this.handleContextMenuForRequest(contextMenu, request);
Tim van der Lippe1d6e57a2019-09-30 11:55:34706 }
Blink Reformat4c46d092018-04-07 15:32:37707 });
708 this._dataGrid.setStickToBottom(true);
709 this._dataGrid.setName('networkLog');
710 this._dataGrid.setResizeMethod(DataGrid.DataGrid.ResizeMethod.Last);
711 this._dataGrid.element.classList.add('network-log-grid');
712 this._dataGrid.element.addEventListener('mousedown', this._dataGridMouseDown.bind(this), true);
713 this._dataGrid.element.addEventListener('mousemove', this._dataGridMouseMove.bind(this), true);
714 this._dataGrid.element.addEventListener('mouseleave', () => this._setHoveredNode(null), true);
Brandon Goddard88d885a2019-10-31 16:11:05715 this._dataGrid.element.addEventListener('keydown', event => {
716 if (isEnterOrSpaceKey(event)) {
Paul Lewis56509652019-12-06 12:51:58717 this.dispatchEventToListeners(Events.RequestActivated, /* showPanel */ true);
Brandon Goddard88d885a2019-10-31 16:11:05718 event.consume(true);
719 }
720 });
721 this._dataGrid.element.addEventListener('focus', this.updateNodeBackground.bind(this), true);
722 this._dataGrid.element.addEventListener('blur', this.updateNodeBackground.bind(this), true);
Blink Reformat4c46d092018-04-07 15:32:37723 return this._dataGrid;
724 }
725
726 /**
727 * @param {!Event} event
728 */
729 _dataGridMouseMove(event) {
730 const node = (this._dataGrid.dataGridNodeFromNode(/** @type {!Node} */ (event.target)));
731 const highlightInitiatorChain = event.shiftKey;
732 this._setHoveredNode(node, highlightInitiatorChain);
733 }
734
735 /**
736 * @return {?Network.NetworkNode}
737 */
738 hoveredNode() {
739 return this._hoveredNode;
740 }
741
742 /**
743 * @param {?Network.NetworkNode} node
744 * @param {boolean=} highlightInitiatorChain
745 */
746 _setHoveredNode(node, highlightInitiatorChain) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34747 if (this._hoveredNode) {
Blink Reformat4c46d092018-04-07 15:32:37748 this._hoveredNode.setHovered(false, false);
Tim van der Lippe1d6e57a2019-09-30 11:55:34749 }
Blink Reformat4c46d092018-04-07 15:32:37750 this._hoveredNode = node;
Tim van der Lippe1d6e57a2019-09-30 11:55:34751 if (this._hoveredNode) {
Blink Reformat4c46d092018-04-07 15:32:37752 this._hoveredNode.setHovered(true, !!highlightInitiatorChain);
Tim van der Lippe1d6e57a2019-09-30 11:55:34753 }
Blink Reformat4c46d092018-04-07 15:32:37754 }
755
756 /**
757 * @param {!Event} event
758 */
759 _dataGridMouseDown(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34760 if (!this._dataGrid.selectedNode && event.button) {
Blink Reformat4c46d092018-04-07 15:32:37761 event.consume();
Tim van der Lippe1d6e57a2019-09-30 11:55:34762 }
Blink Reformat4c46d092018-04-07 15:32:37763 }
764
765 _updateSummaryBar() {
766 this._hideRecordingHint();
767
768 let transferSize = 0;
Dan Beam87466b52018-12-01 18:41:20769 let resourceSize = 0;
Blink Reformat4c46d092018-04-07 15:32:37770 let selectedNodeNumber = 0;
771 let selectedTransferSize = 0;
Dan Beam87466b52018-12-01 18:41:20772 let selectedResourceSize = 0;
Blink Reformat4c46d092018-04-07 15:32:37773 let baseTime = -1;
774 let maxTime = -1;
775
776 let nodeCount = 0;
Pavel Feldman18d13562018-07-31 03:31:18777 for (const request of SDK.networkLog.requests()) {
Paul Lewis56509652019-12-06 12:51:58778 const node = request[_networkNodeSymbol];
Tim van der Lippe1d6e57a2019-09-30 11:55:34779 if (!node) {
Blink Reformat4c46d092018-04-07 15:32:37780 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34781 }
Blink Reformat4c46d092018-04-07 15:32:37782 nodeCount++;
783 const requestTransferSize = request.transferSize;
784 transferSize += requestTransferSize;
Dan Beam87466b52018-12-01 18:41:20785 const requestResourceSize = request.resourceSize;
786 resourceSize += requestResourceSize;
Paul Lewis56509652019-12-06 12:51:58787 if (!node[_isFilteredOutSymbol]) {
Blink Reformat4c46d092018-04-07 15:32:37788 selectedNodeNumber++;
789 selectedTransferSize += requestTransferSize;
Dan Beam87466b52018-12-01 18:41:20790 selectedResourceSize += requestResourceSize;
Blink Reformat4c46d092018-04-07 15:32:37791 }
792 const networkManager = SDK.NetworkManager.forRequest(request);
793 // TODO(allada) inspectedURL should be stored in PageLoad used instead of target so HAR requests can have an
794 // inspected url.
795 if (networkManager && request.url() === networkManager.target().inspectedURL() &&
Tim van der Lippe1d6e57a2019-09-30 11:55:34796 request.resourceType() === Common.resourceTypes.Document && !networkManager.target().parentTarget()) {
Blink Reformat4c46d092018-04-07 15:32:37797 baseTime = request.startTime;
Tim van der Lippe1d6e57a2019-09-30 11:55:34798 }
799 if (request.endTime > maxTime) {
Blink Reformat4c46d092018-04-07 15:32:37800 maxTime = request.endTime;
Tim van der Lippe1d6e57a2019-09-30 11:55:34801 }
Blink Reformat4c46d092018-04-07 15:32:37802 }
803
804 if (!nodeCount) {
805 this._showRecordingHint();
806 return;
807 }
808
Joey Arhara86c14e2019-03-12 03:20:50809 this._summaryToolbar.removeToolbarItems();
Blink Reformat4c46d092018-04-07 15:32:37810 /**
811 * @param {string} chunk
Joey Arhara86c14e2019-03-12 03:20:50812 * @param {string=} title
Blink Reformat4c46d092018-04-07 15:32:37813 * @return {!Element}
814 */
Joey Arhara86c14e2019-03-12 03:20:50815 const appendChunk = (chunk, title) => {
816 const toolbarText = new UI.ToolbarText(chunk);
817 toolbarText.setTitle(title ? title : chunk);
818 this._summaryToolbar.appendToolbarItem(toolbarText);
819 return toolbarText.element;
820 };
Blink Reformat4c46d092018-04-07 15:32:37821
822 if (selectedNodeNumber !== nodeCount) {
Joey Arhara86c14e2019-03-12 03:20:50823 appendChunk(ls`${selectedNodeNumber} / ${nodeCount} requests`);
824 this._summaryToolbar.appendSeparator();
825 appendChunk(
826 ls`${Number.bytesToString(selectedTransferSize)} / ${Number.bytesToString(transferSize)} transferred`,
Changhao Han9ec3f6e2019-11-12 18:43:25827 ls`${selectedTransferSize} B / ${transferSize} B transferred over network`);
Joey Arhara86c14e2019-03-12 03:20:50828 this._summaryToolbar.appendSeparator();
829 appendChunk(
830 ls`${Number.bytesToString(selectedResourceSize)} / ${Number.bytesToString(resourceSize)} resources`,
Changhao Han9ec3f6e2019-11-12 18:43:25831 ls`${selectedResourceSize} B / ${resourceSize} B resources loaded by the page`);
Blink Reformat4c46d092018-04-07 15:32:37832 } else {
Joey Arhara86c14e2019-03-12 03:20:50833 appendChunk(ls`${nodeCount} requests`);
834 this._summaryToolbar.appendSeparator();
Changhao Han9ec3f6e2019-11-12 18:43:25835 appendChunk(
836 ls`${Number.bytesToString(transferSize)} transferred`, ls`${transferSize} B transferred over network`);
Joey Arhara86c14e2019-03-12 03:20:50837 this._summaryToolbar.appendSeparator();
Changhao Han9ec3f6e2019-11-12 18:43:25838 appendChunk(
839 ls`${Number.bytesToString(resourceSize)} resources`, ls`${resourceSize} B resources loaded by the page`);
Blink Reformat4c46d092018-04-07 15:32:37840 }
Dan Beam87466b52018-12-01 18:41:20841
Blink Reformat4c46d092018-04-07 15:32:37842 if (baseTime !== -1 && maxTime !== -1) {
Joey Arhara86c14e2019-03-12 03:20:50843 this._summaryToolbar.appendSeparator();
844 appendChunk(ls`Finish: ${Number.secondsToString(maxTime - baseTime)}`);
Blink Reformat4c46d092018-04-07 15:32:37845 if (this._mainRequestDOMContentLoadedTime !== -1 && this._mainRequestDOMContentLoadedTime > baseTime) {
Joey Arhara86c14e2019-03-12 03:20:50846 this._summaryToolbar.appendSeparator();
Alexei Filippovfdcd8a62018-12-17 21:32:30847 const domContentLoadedText =
848 ls`DOMContentLoaded: ${Number.secondsToString(this._mainRequestDOMContentLoadedTime - baseTime)}`;
Paul Lewis56509652019-12-06 12:51:58849 appendChunk(domContentLoadedText).style.color = NetworkLogView.getDCLEventColor();
Blink Reformat4c46d092018-04-07 15:32:37850 }
851 if (this._mainRequestLoadTime !== -1) {
Joey Arhara86c14e2019-03-12 03:20:50852 this._summaryToolbar.appendSeparator();
Alexei Filippovfdcd8a62018-12-17 21:32:30853 const loadText = ls`Load: ${Number.secondsToString(this._mainRequestLoadTime - baseTime)}`;
Paul Lewis56509652019-12-06 12:51:58854 appendChunk(loadText).style.color = NetworkLogView.getLoadEventColor();
Blink Reformat4c46d092018-04-07 15:32:37855 }
856 }
Blink Reformat4c46d092018-04-07 15:32:37857 }
858
859 scheduleRefresh() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34860 if (this._needsRefresh) {
Blink Reformat4c46d092018-04-07 15:32:37861 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34862 }
Blink Reformat4c46d092018-04-07 15:32:37863
864 this._needsRefresh = true;
865
Tim van der Lippe1d6e57a2019-09-30 11:55:34866 if (this.isShowing() && !this._refreshRequestId) {
Blink Reformat4c46d092018-04-07 15:32:37867 this._refreshRequestId = this.element.window().requestAnimationFrame(this._refresh.bind(this));
Tim van der Lippe1d6e57a2019-09-30 11:55:34868 }
Blink Reformat4c46d092018-04-07 15:32:37869 }
870
871 /**
872 * @param {!Array<number>} times
873 */
874 addFilmStripFrames(times) {
875 this._columns.addEventDividers(times, 'network-frame-divider');
876 }
877
878 /**
879 * @param {number} time
880 */
881 selectFilmStripFrame(time) {
882 this._columns.selectFilmStripFrame(time);
883 }
884
885 clearFilmStripFrame() {
886 this._columns.clearFilmStripFrame();
887 }
888
889 _refreshIfNeeded() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34890 if (this._needsRefresh) {
Blink Reformat4c46d092018-04-07 15:32:37891 this._refresh();
Tim van der Lippe1d6e57a2019-09-30 11:55:34892 }
Blink Reformat4c46d092018-04-07 15:32:37893 }
894
895 /**
896 * @param {boolean=} deferUpdate
897 */
898 _invalidateAllItems(deferUpdate) {
Pavel Feldman18d13562018-07-31 03:31:18899 this._staleRequests = new Set(SDK.networkLog.requests());
Tim van der Lippe1d6e57a2019-09-30 11:55:34900 if (deferUpdate) {
Blink Reformat4c46d092018-04-07 15:32:37901 this.scheduleRefresh();
Tim van der Lippe1d6e57a2019-09-30 11:55:34902 } else {
Blink Reformat4c46d092018-04-07 15:32:37903 this._refresh();
Tim van der Lippe1d6e57a2019-09-30 11:55:34904 }
Blink Reformat4c46d092018-04-07 15:32:37905 }
906
907 /**
908 * @return {!Network.NetworkTimeCalculator}
909 */
910 timeCalculator() {
911 return this._timeCalculator;
912 }
913
914 /**
915 * @return {!Network.NetworkTimeCalculator}
916 */
917 calculator() {
918 return this._calculator;
919 }
920
921 /**
922 * @param {!Network.NetworkTimeCalculator} x
923 */
924 setCalculator(x) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34925 if (!x || this._calculator === x) {
Blink Reformat4c46d092018-04-07 15:32:37926 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34927 }
Blink Reformat4c46d092018-04-07 15:32:37928
929 if (this._calculator !== x) {
930 this._calculator = x;
931 this._columns.setCalculator(this._calculator);
932 }
933 this._calculator.reset();
934
Tim van der Lippe1d6e57a2019-09-30 11:55:34935 if (this._calculator.startAtZero) {
Blink Reformat4c46d092018-04-07 15:32:37936 this._columns.hideEventDividers();
Tim van der Lippe1d6e57a2019-09-30 11:55:34937 } else {
Blink Reformat4c46d092018-04-07 15:32:37938 this._columns.showEventDividers();
Tim van der Lippe1d6e57a2019-09-30 11:55:34939 }
Blink Reformat4c46d092018-04-07 15:32:37940
941 this._invalidateAllItems();
942 }
943
944 /**
945 * @param {!Common.Event} event
946 */
947 _loadEventFired(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34948 if (!this._recording) {
Blink Reformat4c46d092018-04-07 15:32:37949 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34950 }
Blink Reformat4c46d092018-04-07 15:32:37951
952 const time = /** @type {number} */ (event.data.loadTime);
953 if (time) {
954 this._mainRequestLoadTime = time;
Alexei Filippovfdcd8a62018-12-17 21:32:30955 this._columns.addEventDividers([time], 'network-load-divider');
Blink Reformat4c46d092018-04-07 15:32:37956 }
957 }
958
959 /**
960 * @param {!Common.Event} event
961 */
962 _domContentLoadedEventFired(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34963 if (!this._recording) {
Blink Reformat4c46d092018-04-07 15:32:37964 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34965 }
Blink Reformat4c46d092018-04-07 15:32:37966 const data = /** @type {number} */ (event.data);
967 if (data) {
968 this._mainRequestDOMContentLoadedTime = data;
Alexei Filippovfdcd8a62018-12-17 21:32:30969 this._columns.addEventDividers([data], 'network-dcl-divider');
Blink Reformat4c46d092018-04-07 15:32:37970 }
971 }
972
973 /**
974 * @override
975 */
976 wasShown() {
977 this._refreshIfNeeded();
978 this._columns.wasShown();
979 }
980
981 /**
982 * @override
983 */
984 willHide() {
985 this._columns.willHide();
986 }
987
988 /**
989 * @override
990 */
991 onResize() {
992 this._rowHeight = this._computeRowHeight();
993 }
994
995 /**
996 * @return {!Array<!Network.NetworkNode>}
997 */
998 flatNodesList() {
999 return this._dataGrid.rootNode().flatChildren();
1000 }
1001
Brandon Goddard88d885a2019-10-31 16:11:051002 updateNodeBackground() {
1003 if (this._dataGrid.selectedNode) {
1004 this._dataGrid.selectedNode.updateBackgroundColor();
1005 }
1006 }
1007
1008 /**
1009 * @param {boolean} isSelected
1010 */
1011 updateNodeSelectedClass(isSelected) {
1012 if (isSelected) {
1013 this.element.classList.remove('no-node-selected');
1014 } else {
1015 this.element.classList.add('no-node-selected');
1016 }
1017 }
1018
Blink Reformat4c46d092018-04-07 15:32:371019 stylesChanged() {
1020 this._columns.scheduleRefresh();
1021 }
1022
1023 _refresh() {
1024 this._needsRefresh = false;
1025
1026 if (this._refreshRequestId) {
1027 this.element.window().cancelAnimationFrame(this._refreshRequestId);
1028 this._refreshRequestId = null;
1029 }
1030
1031 this.removeAllNodeHighlights();
1032
1033 this._timeCalculator.updateBoundariesForEventTime(this._mainRequestLoadTime);
1034 this._durationCalculator.updateBoundariesForEventTime(this._mainRequestLoadTime);
1035 this._timeCalculator.updateBoundariesForEventTime(this._mainRequestDOMContentLoadedTime);
1036 this._durationCalculator.updateBoundariesForEventTime(this._mainRequestDOMContentLoadedTime);
1037
1038 /** @type {!Map<!Network.NetworkNode, !Network.NetworkNode>} */
1039 const nodesToInsert = new Map();
1040 /** @type {!Array<!Network.NetworkNode>} */
1041 const nodesToRefresh = [];
1042
1043 /** @type {!Set<!Network.NetworkRequestNode>} */
1044 const staleNodes = new Set();
1045
1046 // While creating nodes it may add more entries into _staleRequests because redirect request nodes update the parent
1047 // node so we loop until we have no more stale requests.
1048 while (this._staleRequests.size) {
1049 const request = this._staleRequests.firstValue();
1050 this._staleRequests.delete(request);
Paul Lewis56509652019-12-06 12:51:581051 let node = request[_networkNodeSymbol];
Tim van der Lippe1d6e57a2019-09-30 11:55:341052 if (!node) {
Blink Reformat4c46d092018-04-07 15:32:371053 node = this._createNodeForRequest(request);
Tim van der Lippe1d6e57a2019-09-30 11:55:341054 }
Blink Reformat4c46d092018-04-07 15:32:371055 staleNodes.add(node);
1056 }
1057
1058 for (const node of staleNodes) {
1059 const isFilteredOut = !this._applyFilter(node);
Tim van der Lippe1d6e57a2019-09-30 11:55:341060 if (isFilteredOut && node === this._hoveredNode) {
Blink Reformat4c46d092018-04-07 15:32:371061 this._setHoveredNode(null);
Tim van der Lippe1d6e57a2019-09-30 11:55:341062 }
Blink Reformat4c46d092018-04-07 15:32:371063
Tim van der Lippe1d6e57a2019-09-30 11:55:341064 if (!isFilteredOut) {
Blink Reformat4c46d092018-04-07 15:32:371065 nodesToRefresh.push(node);
Tim van der Lippe1d6e57a2019-09-30 11:55:341066 }
Blink Reformat4c46d092018-04-07 15:32:371067 const request = node.request();
1068 this._timeCalculator.updateBoundaries(request);
1069 this._durationCalculator.updateBoundaries(request);
1070 const newParent = this._parentNodeForInsert(node);
Paul Lewis56509652019-12-06 12:51:581071 if (node[_isFilteredOutSymbol] === isFilteredOut && node.parent === newParent) {
Blink Reformat4c46d092018-04-07 15:32:371072 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341073 }
Paul Lewis56509652019-12-06 12:51:581074 node[_isFilteredOutSymbol] = isFilteredOut;
Blink Reformat4c46d092018-04-07 15:32:371075 const removeFromParent = node.parent && (isFilteredOut || node.parent !== newParent);
1076 if (removeFromParent) {
1077 let parent = node.parent;
1078 parent.removeChild(node);
1079 while (parent && !parent.hasChildren() && parent.dataGrid && parent.dataGrid.rootNode() !== parent) {
1080 const grandparent = parent.parent;
1081 grandparent.removeChild(parent);
1082 parent = grandparent;
1083 }
1084 }
1085
Tim van der Lippe1d6e57a2019-09-30 11:55:341086 if (!newParent || isFilteredOut) {
Blink Reformat4c46d092018-04-07 15:32:371087 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341088 }
Blink Reformat4c46d092018-04-07 15:32:371089
1090 if (!newParent.dataGrid && !nodesToInsert.has(newParent)) {
1091 nodesToInsert.set(newParent, this._dataGrid.rootNode());
1092 nodesToRefresh.push(newParent);
1093 }
1094 nodesToInsert.set(node, newParent);
1095 }
1096
Tim van der Lippe1d6e57a2019-09-30 11:55:341097 for (const node of nodesToInsert.keys()) {
Blink Reformat4c46d092018-04-07 15:32:371098 nodesToInsert.get(node).appendChild(node);
Tim van der Lippe1d6e57a2019-09-30 11:55:341099 }
Blink Reformat4c46d092018-04-07 15:32:371100
Tim van der Lippe1d6e57a2019-09-30 11:55:341101 for (const node of nodesToRefresh) {
Blink Reformat4c46d092018-04-07 15:32:371102 node.refresh();
Tim van der Lippe1d6e57a2019-09-30 11:55:341103 }
Blink Reformat4c46d092018-04-07 15:32:371104
1105 this._updateSummaryBar();
1106
Tim van der Lippe1d6e57a2019-09-30 11:55:341107 if (nodesToInsert.size) {
Blink Reformat4c46d092018-04-07 15:32:371108 this._columns.sortByCurrentColumn();
Tim van der Lippe1d6e57a2019-09-30 11:55:341109 }
Blink Reformat4c46d092018-04-07 15:32:371110
1111 this._dataGrid.updateInstantly();
1112 this._didRefreshForTest();
1113 }
1114
1115 _didRefreshForTest() {
1116 }
1117
1118 /**
1119 * @param {!Network.NetworkRequestNode} node
1120 * @return {?Network.NetworkNode}
1121 */
1122 _parentNodeForInsert(node) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341123 if (!this._activeGroupLookup) {
Blink Reformat4c46d092018-04-07 15:32:371124 return this._dataGrid.rootNode();
Tim van der Lippe1d6e57a2019-09-30 11:55:341125 }
Blink Reformat4c46d092018-04-07 15:32:371126
1127 const groupNode = this._activeGroupLookup.groupNodeForRequest(node.request());
Tim van der Lippe1d6e57a2019-09-30 11:55:341128 if (!groupNode) {
Blink Reformat4c46d092018-04-07 15:32:371129 return this._dataGrid.rootNode();
Tim van der Lippe1d6e57a2019-09-30 11:55:341130 }
Blink Reformat4c46d092018-04-07 15:32:371131 return groupNode;
1132 }
1133
1134 _reset() {
Paul Lewis56509652019-12-06 12:51:581135 this.dispatchEventToListeners(Events.RequestActivated, /* showPanel */ false);
Blink Reformat4c46d092018-04-07 15:32:371136
1137 this._setHoveredNode(null);
1138 this._columns.reset();
1139
1140 this._timeFilter = null;
1141 this._calculator.reset();
1142
1143 this._timeCalculator.setWindow(null);
1144 this.linkifier.reset();
Blink Reformat4c46d092018-04-07 15:32:371145
Tim van der Lippe1d6e57a2019-09-30 11:55:341146 if (this._activeGroupLookup) {
Blink Reformat4c46d092018-04-07 15:32:371147 this._activeGroupLookup.reset();
Tim van der Lippe1d6e57a2019-09-30 11:55:341148 }
Blink Reformat4c46d092018-04-07 15:32:371149 this._staleRequests.clear();
1150 this._resetSuggestionBuilder();
1151
1152 this._mainRequestLoadTime = -1;
1153 this._mainRequestDOMContentLoadedTime = -1;
1154
1155 this._dataGrid.rootNode().removeChildren();
1156 this._updateSummaryBar();
1157 this._dataGrid.setStickToBottom(true);
1158 this.scheduleRefresh();
1159 }
1160
1161 /**
1162 * @param {string} filterString
1163 */
1164 setTextFilterValue(filterString) {
1165 this._textFilterUI.setValue(filterString);
1166 this._dataURLFilterUI.setChecked(false);
Jan Scheffler1ae7c9e2019-12-03 15:48:371167 this._onlyIssuesFilterUI.setChecked(false);
Blink Reformat4c46d092018-04-07 15:32:371168 this._resourceCategoryFilterUI.reset();
1169 }
1170
1171 /**
1172 * @param {!SDK.NetworkRequest} request
1173 */
1174 _createNodeForRequest(request) {
1175 const node = new Network.NetworkRequestNode(this, request);
Paul Lewis56509652019-12-06 12:51:581176 request[_networkNodeSymbol] = node;
1177 node[_isFilteredOutSymbol] = true;
Blink Reformat4c46d092018-04-07 15:32:371178
Tim van der Lippe1d6e57a2019-09-30 11:55:341179 for (let redirect = request.redirectSource(); redirect; redirect = redirect.redirectSource()) {
Blink Reformat4c46d092018-04-07 15:32:371180 this._refreshRequest(redirect);
Tim van der Lippe1d6e57a2019-09-30 11:55:341181 }
Blink Reformat4c46d092018-04-07 15:32:371182 return node;
1183 }
1184
1185 /**
1186 * @param {!Common.Event} event
1187 */
1188 _onRequestUpdated(event) {
1189 const request = /** @type {!SDK.NetworkRequest} */ (event.data);
1190 this._refreshRequest(request);
1191 }
1192
1193 /**
1194 * @param {!SDK.NetworkRequest} request
1195 */
1196 _refreshRequest(request) {
Paul Lewis56509652019-12-06 12:51:581197 NetworkLogView._subdomains(request.domain)
1198 .forEach(this._suggestionBuilder.addItem.bind(this._suggestionBuilder, FilterType.Domain));
1199 this._suggestionBuilder.addItem(FilterType.Method, request.requestMethod);
1200 this._suggestionBuilder.addItem(FilterType.MimeType, request.mimeType);
1201 this._suggestionBuilder.addItem(FilterType.Scheme, '' + request.scheme);
1202 this._suggestionBuilder.addItem(FilterType.StatusCode, '' + request.statusCode);
Blink Reformat4c46d092018-04-07 15:32:371203
1204 const priority = request.priority();
1205 if (priority) {
Paul Lewis56509652019-12-06 12:51:581206 this._suggestionBuilder.addItem(FilterType.Priority, PerfUI.uiLabelForNetworkPriority(priority));
Blink Reformat4c46d092018-04-07 15:32:371207 }
1208
1209 if (request.mixedContentType !== Protocol.Security.MixedContentType.None) {
Paul Lewis56509652019-12-06 12:51:581210 this._suggestionBuilder.addItem(FilterType.MixedContent, MixedContentFilterValues.All);
Blink Reformat4c46d092018-04-07 15:32:371211 }
1212
1213 if (request.mixedContentType === Protocol.Security.MixedContentType.OptionallyBlockable) {
Paul Lewis56509652019-12-06 12:51:581214 this._suggestionBuilder.addItem(FilterType.MixedContent, MixedContentFilterValues.Displayed);
Blink Reformat4c46d092018-04-07 15:32:371215 }
1216
1217 if (request.mixedContentType === Protocol.Security.MixedContentType.Blockable) {
Paul Lewis56509652019-12-06 12:51:581218 const suggestion =
1219 request.wasBlocked() ? MixedContentFilterValues.Blocked : MixedContentFilterValues.BlockOverridden;
1220 this._suggestionBuilder.addItem(FilterType.MixedContent, suggestion);
Blink Reformat4c46d092018-04-07 15:32:371221 }
1222
1223 const responseHeaders = request.responseHeaders;
Tim van der Lippe1d6e57a2019-09-30 11:55:341224 for (let i = 0, l = responseHeaders.length; i < l; ++i) {
Paul Lewis56509652019-12-06 12:51:581225 this._suggestionBuilder.addItem(FilterType.HasResponseHeader, responseHeaders[i].name);
Tim van der Lippe1d6e57a2019-09-30 11:55:341226 }
Jan Scheffler341eea52019-12-12 09:08:411227
1228 for (const cookie of request.responseCookies) {
Paul Lewis56509652019-12-06 12:51:581229 this._suggestionBuilder.addItem(FilterType.SetCookieDomain, cookie.domain());
1230 this._suggestionBuilder.addItem(FilterType.SetCookieName, cookie.name());
1231 this._suggestionBuilder.addItem(FilterType.SetCookieValue, cookie.value());
Blink Reformat4c46d092018-04-07 15:32:371232 }
1233
Jan Scheffler341eea52019-12-12 09:08:411234 for (const cookie of request.allCookiesIncludingBlockedOnes()) {
1235 this._suggestionBuilder.addItem(FilterType.CookieDomain, cookie.domain());
1236 this._suggestionBuilder.addItem(FilterType.CookieName, cookie.name());
1237 this._suggestionBuilder.addItem(FilterType.CookieValue, cookie.value());
1238 }
1239
Blink Reformat4c46d092018-04-07 15:32:371240 this._staleRequests.add(request);
1241 this.scheduleRefresh();
1242 }
1243
1244 /**
1245 * @return {number}
1246 */
1247 rowHeight() {
1248 return this._rowHeight;
1249 }
1250
1251 /**
1252 * @param {boolean} gridMode
1253 */
1254 switchViewMode(gridMode) {
1255 this._columns.switchViewMode(gridMode);
1256 }
1257
1258 /**
1259 * @param {!UI.ContextMenu} contextMenu
1260 * @param {!SDK.NetworkRequest} request
1261 */
1262 handleContextMenuForRequest(contextMenu, request) {
1263 contextMenu.appendApplicableItems(request);
1264 let copyMenu = contextMenu.clipboardSection().appendSubMenuItem(Common.UIString('Copy'));
1265 const footerSection = copyMenu.footerSection();
1266 if (request) {
1267 copyMenu.defaultSection().appendItem(
Tim van der Lippe50cfa9b2019-10-01 10:40:581268 UI.copyLinkAddressLabel(),
1269 Host.InspectorFrontendHost.copyText.bind(Host.InspectorFrontendHost, request.contentURL()));
Blink Reformat4c46d092018-04-07 15:32:371270 if (request.requestHeadersText()) {
1271 copyMenu.defaultSection().appendItem(
Paul Lewis56509652019-12-06 12:51:581272 Common.UIString('Copy request headers'), NetworkLogView._copyRequestHeaders.bind(null, request));
Blink Reformat4c46d092018-04-07 15:32:371273 }
1274
1275 if (request.responseHeadersText) {
1276 copyMenu.defaultSection().appendItem(
Paul Lewis56509652019-12-06 12:51:581277 Common.UIString('Copy response headers'), NetworkLogView._copyResponseHeaders.bind(null, request));
Blink Reformat4c46d092018-04-07 15:32:371278 }
1279
1280 if (request.finished) {
1281 copyMenu.defaultSection().appendItem(
Paul Lewis56509652019-12-06 12:51:581282 Common.UIString('Copy response'), NetworkLogView._copyResponse.bind(null, request));
Blink Reformat4c46d092018-04-07 15:32:371283 }
1284
Harley Libcf41f92018-09-10 18:01:131285 const disableIfBlob = request.isBlobRequest();
Blink Reformat4c46d092018-04-07 15:32:371286 if (Host.isWin()) {
1287 footerSection.appendItem(
Harley Libcf41f92018-09-10 18:01:131288 Common.UIString('Copy as PowerShell'), this._copyPowerShellCommand.bind(this, request), disableIfBlob);
Blink Reformat4c46d092018-04-07 15:32:371289 footerSection.appendItem(
Jan Scheffler7c50d1f2019-12-17 13:33:291290 Common.UIString('Copy as fetch'), this._copyFetchCall.bind(this, request, false), disableIfBlob);
1291 footerSection.appendItem(
1292 Common.UIString('Copy as Node.js fetch'), this._copyFetchCall.bind(this, request, true), disableIfBlob);
Blink Reformat4c46d092018-04-07 15:32:371293 footerSection.appendItem(
Harley Libcf41f92018-09-10 18:01:131294 Common.UIString('Copy as cURL (cmd)'), this._copyCurlCommand.bind(this, request, 'win'), disableIfBlob);
1295 footerSection.appendItem(
1296 Common.UIString('Copy as cURL (bash)'), this._copyCurlCommand.bind(this, request, 'unix'), disableIfBlob);
Blink Reformat4c46d092018-04-07 15:32:371297 footerSection.appendItem(Common.UIString('Copy all as PowerShell'), this._copyAllPowerShellCommand.bind(this));
Jan Scheffler7c50d1f2019-12-17 13:33:291298 footerSection.appendItem(Common.UIString('Copy all as fetch'), this._copyAllFetchCall.bind(this, false));
1299 footerSection.appendItem(Common.UIString('Copy all as Node.js fetch'), this._copyAllFetchCall.bind(this, true));
Blink Reformat4c46d092018-04-07 15:32:371300 footerSection.appendItem(Common.UIString('Copy all as cURL (cmd)'), this._copyAllCurlCommand.bind(this, 'win'));
1301 footerSection.appendItem(
1302 Common.UIString('Copy all as cURL (bash)'), this._copyAllCurlCommand.bind(this, 'unix'));
1303 } else {
Harley Libcf41f92018-09-10 18:01:131304 footerSection.appendItem(
Jan Scheffler7c50d1f2019-12-17 13:33:291305 Common.UIString('Copy as fetch'), this._copyFetchCall.bind(this, request, false), disableIfBlob);
1306 footerSection.appendItem(
1307 Common.UIString('Copy as Node.js fetch'), this._copyFetchCall.bind(this, request, true), disableIfBlob);
Harley Libcf41f92018-09-10 18:01:131308 footerSection.appendItem(
1309 Common.UIString('Copy as cURL'), this._copyCurlCommand.bind(this, request, 'unix'), disableIfBlob);
Jan Scheffler7c50d1f2019-12-17 13:33:291310 footerSection.appendItem(Common.UIString('Copy all as fetch'), this._copyAllFetchCall.bind(this, false));
1311 footerSection.appendItem(Common.UIString('Copy all as Node.js fetch'), this._copyAllFetchCall.bind(this, true));
Blink Reformat4c46d092018-04-07 15:32:371312 footerSection.appendItem(Common.UIString('Copy all as cURL'), this._copyAllCurlCommand.bind(this, 'unix'));
1313 }
1314 } else {
1315 copyMenu = contextMenu.clipboardSection().appendSubMenuItem(Common.UIString('Copy'));
1316 }
1317 footerSection.appendItem(Common.UIString('Copy all as HAR'), this._copyAll.bind(this));
1318
Joey Arhar0e1093c2019-05-21 00:34:221319 contextMenu.saveSection().appendItem(ls`Save all as HAR with content`, this.exportAll.bind(this));
Blink Reformat4c46d092018-04-07 15:32:371320
1321 contextMenu.editSection().appendItem(Common.UIString('Clear browser cache'), this._clearBrowserCache.bind(this));
1322 contextMenu.editSection().appendItem(
1323 Common.UIString('Clear browser cookies'), this._clearBrowserCookies.bind(this));
1324
1325 if (request) {
1326 const maxBlockedURLLength = 20;
1327 const manager = SDK.multitargetNetworkManager;
1328 let patterns = manager.blockedPatterns();
1329
Tim van der Lippeffa78622019-09-16 12:07:121330 /**
1331 * @param {string} url
1332 */
1333 function addBlockedURL(url) {
1334 patterns.push({enabled: true, url: url});
1335 manager.setBlockedPatterns(patterns);
1336 manager.setBlockingEnabled(true);
1337 UI.viewManager.showView('network.blocked-urls');
1338 }
1339
1340 /**
1341 * @param {string} url
1342 */
1343 function removeBlockedURL(url) {
1344 patterns = patterns.filter(pattern => pattern.url !== url);
1345 manager.setBlockedPatterns(patterns);
1346 UI.viewManager.showView('network.blocked-urls');
1347 }
1348
Blink Reformat4c46d092018-04-07 15:32:371349 const urlWithoutScheme = request.parsedURL.urlWithoutScheme();
1350 if (urlWithoutScheme && !patterns.find(pattern => pattern.url === urlWithoutScheme)) {
1351 contextMenu.debugSection().appendItem(
1352 Common.UIString('Block request URL'), addBlockedURL.bind(null, urlWithoutScheme));
1353 } else if (urlWithoutScheme) {
1354 const croppedURL = urlWithoutScheme.trimMiddle(maxBlockedURLLength);
1355 contextMenu.debugSection().appendItem(
1356 Common.UIString('Unblock %s', croppedURL), removeBlockedURL.bind(null, urlWithoutScheme));
1357 }
1358
1359 const domain = request.parsedURL.domain();
1360 if (domain && !patterns.find(pattern => pattern.url === domain)) {
1361 contextMenu.debugSection().appendItem(
1362 Common.UIString('Block request domain'), addBlockedURL.bind(null, domain));
1363 } else if (domain) {
1364 const croppedDomain = domain.trimMiddle(maxBlockedURLLength);
1365 contextMenu.debugSection().appendItem(
1366 Common.UIString('Unblock %s', croppedDomain), removeBlockedURL.bind(null, domain));
1367 }
1368
1369 if (SDK.NetworkManager.canReplayRequest(request)) {
1370 contextMenu.debugSection().appendItem(
1371 Common.UIString('Replay XHR'), SDK.NetworkManager.replayRequest.bind(null, request));
1372 }
Blink Reformat4c46d092018-04-07 15:32:371373 }
1374 }
1375
1376 _harRequests() {
Paul Lewis56509652019-12-06 12:51:581377 return SDK.networkLog.requests().filter(NetworkLogView.HTTPRequestsFilter).filter(request => {
Joey Arharb3d6de42019-04-23 21:26:171378 return request.finished ||
1379 (request.resourceType() === Common.resourceTypes.WebSocket && request.responseReceivedTime);
1380 });
Blink Reformat4c46d092018-04-07 15:32:371381 }
1382
1383 async _copyAll() {
Pavel Feldman18d13562018-07-31 03:31:181384 const harArchive = {log: await SDK.HARLog.build(this._harRequests())};
Tim van der Lippe50cfa9b2019-10-01 10:40:581385 Host.InspectorFrontendHost.copyText(JSON.stringify(harArchive, null, 2));
Blink Reformat4c46d092018-04-07 15:32:371386 }
1387
1388 /**
1389 * @param {!SDK.NetworkRequest} request
1390 * @param {string} platform
1391 */
1392 async _copyCurlCommand(request, platform) {
1393 const command = await this._generateCurlCommand(request, platform);
Tim van der Lippe50cfa9b2019-10-01 10:40:581394 Host.InspectorFrontendHost.copyText(command);
Blink Reformat4c46d092018-04-07 15:32:371395 }
1396
1397 /**
1398 * @param {string} platform
1399 */
1400 async _copyAllCurlCommand(platform) {
Harley Libcf41f92018-09-10 18:01:131401 const commands = await this._generateAllCurlCommand(SDK.networkLog.requests(), platform);
Tim van der Lippe50cfa9b2019-10-01 10:40:581402 Host.InspectorFrontendHost.copyText(commands);
Blink Reformat4c46d092018-04-07 15:32:371403 }
1404
1405 /**
1406 * @param {!SDK.NetworkRequest} request
Jan Scheffler7c50d1f2019-12-17 13:33:291407 * @param {boolean} includeCookies
Blink Reformat4c46d092018-04-07 15:32:371408 */
Jan Scheffler7c50d1f2019-12-17 13:33:291409 async _copyFetchCall(request, includeCookies) {
1410 const command = await this._generateFetchCall(request, includeCookies);
Tim van der Lippe50cfa9b2019-10-01 10:40:581411 Host.InspectorFrontendHost.copyText(command);
Blink Reformat4c46d092018-04-07 15:32:371412 }
1413
Jan Scheffler7c50d1f2019-12-17 13:33:291414 /**
1415 * @param {boolean} includeCookies
1416 */
1417 async _copyAllFetchCall(includeCookies) {
1418 const commands = await this._generateAllFetchCall(SDK.networkLog.requests(), includeCookies);
Tim van der Lippe50cfa9b2019-10-01 10:40:581419 Host.InspectorFrontendHost.copyText(commands);
Blink Reformat4c46d092018-04-07 15:32:371420 }
1421
1422 /**
1423 * @param {!SDK.NetworkRequest} request
1424 */
1425 async _copyPowerShellCommand(request) {
1426 const command = await this._generatePowerShellCommand(request);
Tim van der Lippe50cfa9b2019-10-01 10:40:581427 Host.InspectorFrontendHost.copyText(command);
Blink Reformat4c46d092018-04-07 15:32:371428 }
1429
1430 async _copyAllPowerShellCommand() {
Harley Li5a470e92019-09-26 21:38:351431 const commands = await this._generateAllPowerShellCommand(SDK.networkLog.requests());
Tim van der Lippe50cfa9b2019-10-01 10:40:581432 Host.InspectorFrontendHost.copyText(commands);
Blink Reformat4c46d092018-04-07 15:32:371433 }
1434
Joey Arhar0e1093c2019-05-21 00:34:221435 async exportAll() {
Blink Reformat4c46d092018-04-07 15:32:371436 const url = SDK.targetManager.mainTarget().inspectedURL();
Peter Marshall3e4e5692019-12-09 16:48:041437 const parsedURL = Common.ParsedURL.fromString(url);
Blink Reformat4c46d092018-04-07 15:32:371438 const filename = parsedURL ? parsedURL.host : 'network-log';
1439 const stream = new Bindings.FileOutputStream();
1440
Tim van der Lippe1d6e57a2019-09-30 11:55:341441 if (!await stream.open(filename + '.har')) {
Blink Reformat4c46d092018-04-07 15:32:371442 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:341443 }
Blink Reformat4c46d092018-04-07 15:32:371444
1445 const progressIndicator = new UI.ProgressIndicator();
1446 this._progressBarContainer.appendChild(progressIndicator.element);
1447 await Network.HARWriter.write(stream, this._harRequests(), progressIndicator);
1448 progressIndicator.done();
1449 stream.close();
1450 }
1451
1452 _clearBrowserCache() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341453 if (confirm(Common.UIString('Are you sure you want to clear browser cache?'))) {
Blink Reformat4c46d092018-04-07 15:32:371454 SDK.multitargetNetworkManager.clearBrowserCache();
Tim van der Lippe1d6e57a2019-09-30 11:55:341455 }
Blink Reformat4c46d092018-04-07 15:32:371456 }
1457
1458 _clearBrowserCookies() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341459 if (confirm(Common.UIString('Are you sure you want to clear browser cookies?'))) {
Blink Reformat4c46d092018-04-07 15:32:371460 SDK.multitargetNetworkManager.clearBrowserCookies();
Tim van der Lippe1d6e57a2019-09-30 11:55:341461 }
Blink Reformat4c46d092018-04-07 15:32:371462 }
1463
1464 _removeAllHighlights() {
1465 this.removeAllNodeHighlights();
Tim van der Lippe1d6e57a2019-09-30 11:55:341466 for (let i = 0; i < this._highlightedSubstringChanges.length; ++i) {
Blink Reformat4c46d092018-04-07 15:32:371467 UI.revertDomChanges(this._highlightedSubstringChanges[i]);
Tim van der Lippe1d6e57a2019-09-30 11:55:341468 }
Blink Reformat4c46d092018-04-07 15:32:371469 this._highlightedSubstringChanges = [];
1470 }
1471
1472 /**
1473 * @param {!Network.NetworkRequestNode} node
1474 * @return {boolean}
1475 */
1476 _applyFilter(node) {
1477 const request = node.request();
Tim van der Lippe1d6e57a2019-09-30 11:55:341478 if (this._timeFilter && !this._timeFilter(request)) {
Blink Reformat4c46d092018-04-07 15:32:371479 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341480 }
Blink Reformat4c46d092018-04-07 15:32:371481 const categoryName = request.resourceType().category().title;
Tim van der Lippe1d6e57a2019-09-30 11:55:341482 if (!this._resourceCategoryFilterUI.accept(categoryName)) {
Blink Reformat4c46d092018-04-07 15:32:371483 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341484 }
1485 if (this._dataURLFilterUI.checked() && (request.parsedURL.isDataURL() || request.parsedURL.isBlobURL())) {
Blink Reformat4c46d092018-04-07 15:32:371486 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341487 }
Jan Scheffler1ae7c9e2019-12-03 15:48:371488 if (this._onlyIssuesFilterUI.checked() && !SDK.IssuesModel.hasIssues(request)) {
1489 return false;
1490 }
Tim van der Lippe1d6e57a2019-09-30 11:55:341491 if (request.statusText === 'Service Worker Fallback Required') {
Blink Reformat4c46d092018-04-07 15:32:371492 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341493 }
Blink Reformat4c46d092018-04-07 15:32:371494 for (let i = 0; i < this._filters.length; ++i) {
Tim van der Lippe1d6e57a2019-09-30 11:55:341495 if (!this._filters[i](request)) {
Blink Reformat4c46d092018-04-07 15:32:371496 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:341497 }
Blink Reformat4c46d092018-04-07 15:32:371498 }
1499 return true;
1500 }
1501
1502 /**
1503 * @param {string} query
1504 */
1505 _parseFilterQuery(query) {
1506 const descriptors = this._filterParser.parse(query);
1507 this._filters = descriptors.map(descriptor => {
1508 const key = descriptor.key;
1509 const text = descriptor.text || '';
1510 const regex = descriptor.regex;
1511 let filter;
1512 if (key) {
1513 const defaultText = (key + ':' + text).escapeForRegExp();
Paul Lewis56509652019-12-06 12:51:581514 filter = this._createSpecialFilter(/** @type {!FilterType} */ (key), text) ||
1515 NetworkLogView._requestPathFilter.bind(null, new RegExp(defaultText, 'i'));
Blink Reformat4c46d092018-04-07 15:32:371516 } else if (descriptor.regex) {
Paul Lewis56509652019-12-06 12:51:581517 filter = NetworkLogView._requestPathFilter.bind(null, /** @type {!RegExp} */ (regex));
Blink Reformat4c46d092018-04-07 15:32:371518 } else {
Paul Lewis56509652019-12-06 12:51:581519 filter = NetworkLogView._requestPathFilter.bind(null, new RegExp(text.escapeForRegExp(), 'i'));
Blink Reformat4c46d092018-04-07 15:32:371520 }
Paul Lewis56509652019-12-06 12:51:581521 return descriptor.negative ? NetworkLogView._negativeFilter.bind(null, filter) : filter;
Blink Reformat4c46d092018-04-07 15:32:371522 });
1523 }
1524
1525 /**
Paul Lewis56509652019-12-06 12:51:581526 * @param {!FilterType} type
Blink Reformat4c46d092018-04-07 15:32:371527 * @param {string} value
1528 * @return {?Network.NetworkLogView.Filter}
1529 */
1530 _createSpecialFilter(type, value) {
1531 switch (type) {
Paul Lewis56509652019-12-06 12:51:581532 case FilterType.Domain:
1533 return NetworkLogView._createRequestDomainFilter(value);
Blink Reformat4c46d092018-04-07 15:32:371534
Paul Lewis56509652019-12-06 12:51:581535 case FilterType.HasResponseHeader:
1536 return NetworkLogView._requestResponseHeaderFilter.bind(null, value);
Blink Reformat4c46d092018-04-07 15:32:371537
Paul Lewis56509652019-12-06 12:51:581538 case FilterType.Is:
1539 if (value.toLowerCase() === IsFilterType.Running) {
1540 return NetworkLogView._runningRequestFilter;
Tim van der Lippe1d6e57a2019-09-30 11:55:341541 }
Paul Lewis56509652019-12-06 12:51:581542 if (value.toLowerCase() === IsFilterType.FromCache) {
1543 return NetworkLogView._fromCacheRequestFilter;
Tim van der Lippe1d6e57a2019-09-30 11:55:341544 }
Paul Lewis56509652019-12-06 12:51:581545 if (value.toLowerCase() === IsFilterType.ServiceWorkerIntercepted) {
1546 return NetworkLogView._interceptedByServiceWorkerFilter;
Tim van der Lippe1d6e57a2019-09-30 11:55:341547 }
Paul Lewis56509652019-12-06 12:51:581548 if (value.toLowerCase() === IsFilterType.ServiceWorkerInitiated) {
1549 return NetworkLogView._initiatedByServiceWorkerFilter;
Tim van der Lippe1d6e57a2019-09-30 11:55:341550 }
Blink Reformat4c46d092018-04-07 15:32:371551 break;
1552
Paul Lewis56509652019-12-06 12:51:581553 case FilterType.LargerThan:
Blink Reformat4c46d092018-04-07 15:32:371554 return this._createSizeFilter(value.toLowerCase());
1555
Paul Lewis56509652019-12-06 12:51:581556 case FilterType.Method:
1557 return NetworkLogView._requestMethodFilter.bind(null, value);
Blink Reformat4c46d092018-04-07 15:32:371558
Paul Lewis56509652019-12-06 12:51:581559 case FilterType.MimeType:
1560 return NetworkLogView._requestMimeTypeFilter.bind(null, value);
Blink Reformat4c46d092018-04-07 15:32:371561
Paul Lewis56509652019-12-06 12:51:581562 case FilterType.MixedContent:
1563 return NetworkLogView._requestMixedContentFilter.bind(null, /** @type {!MixedContentFilterValues} */ (value));
Blink Reformat4c46d092018-04-07 15:32:371564
Paul Lewis56509652019-12-06 12:51:581565 case FilterType.Scheme:
1566 return NetworkLogView._requestSchemeFilter.bind(null, value);
Blink Reformat4c46d092018-04-07 15:32:371567
Paul Lewis56509652019-12-06 12:51:581568 case FilterType.SetCookieDomain:
1569 return NetworkLogView._requestSetCookieDomainFilter.bind(null, value);
Blink Reformat4c46d092018-04-07 15:32:371570
Paul Lewis56509652019-12-06 12:51:581571 case FilterType.SetCookieName:
1572 return NetworkLogView._requestSetCookieNameFilter.bind(null, value);
Blink Reformat4c46d092018-04-07 15:32:371573
Paul Lewis56509652019-12-06 12:51:581574 case FilterType.SetCookieValue:
1575 return NetworkLogView._requestSetCookieValueFilter.bind(null, value);
Blink Reformat4c46d092018-04-07 15:32:371576
Jan Scheffler341eea52019-12-12 09:08:411577 case FilterType.CookieDomain:
1578 return NetworkLogView._requestCookieDomainFilter.bind(null, value);
1579
1580 case FilterType.CookieName:
1581 return NetworkLogView._requestCookieNameFilter.bind(null, value);
1582
1583 case FilterType.CookieValue:
1584 return NetworkLogView._requestCookieValueFilter.bind(null, value);
1585
Paul Lewis56509652019-12-06 12:51:581586 case FilterType.Priority:
1587 return NetworkLogView._requestPriorityFilter.bind(null, PerfUI.uiLabelToNetworkPriority(value));
Blink Reformat4c46d092018-04-07 15:32:371588
Paul Lewis56509652019-12-06 12:51:581589 case FilterType.StatusCode:
1590 return NetworkLogView._statusCodeFilter.bind(null, value);
Blink Reformat4c46d092018-04-07 15:32:371591 }
1592 return null;
1593 }
1594
1595 /**
1596 * @param {string} value
1597 * @return {?Network.NetworkLogView.Filter}
1598 */
1599 _createSizeFilter(value) {
1600 let multiplier = 1;
1601 if (value.endsWith('k')) {
1602 multiplier = 1024;
1603 value = value.substring(0, value.length - 1);
1604 } else if (value.endsWith('m')) {
1605 multiplier = 1024 * 1024;
1606 value = value.substring(0, value.length - 1);
1607 }
1608 const quantity = Number(value);
Tim van der Lippe1d6e57a2019-09-30 11:55:341609 if (isNaN(quantity)) {
Blink Reformat4c46d092018-04-07 15:32:371610 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341611 }
Paul Lewis56509652019-12-06 12:51:581612 return NetworkLogView._requestSizeLargerThanFilter.bind(null, quantity * multiplier);
Blink Reformat4c46d092018-04-07 15:32:371613 }
1614
1615 _filterRequests() {
1616 this._removeAllHighlights();
1617 this._invalidateAllItems();
1618 }
1619
1620 /**
1621 * @param {!SDK.NetworkRequest} request
1622 * @return {?Network.NetworkRequestNode}
1623 */
1624 _reveal(request) {
1625 this.removeAllNodeHighlights();
Paul Lewis56509652019-12-06 12:51:581626 const node = request[_networkNodeSymbol];
Tim van der Lippe1d6e57a2019-09-30 11:55:341627 if (!node || !node.dataGrid) {
Blink Reformat4c46d092018-04-07 15:32:371628 return null;
Tim van der Lippe1d6e57a2019-09-30 11:55:341629 }
Blink Reformat4c46d092018-04-07 15:32:371630 node.reveal();
1631 return node;
1632 }
1633
1634 /**
1635 * @param {!SDK.NetworkRequest} request
1636 */
1637 revealAndHighlightRequest(request) {
1638 const node = this._reveal(request);
Tim van der Lippe1d6e57a2019-09-30 11:55:341639 if (node) {
Blink Reformat4c46d092018-04-07 15:32:371640 this._highlightNode(node);
Tim van der Lippe1d6e57a2019-09-30 11:55:341641 }
Blink Reformat4c46d092018-04-07 15:32:371642 }
1643
1644 /**
1645 * @param {!SDK.NetworkRequest} request
1646 */
1647 selectRequest(request) {
Eugene Ostroukhovb600f662018-05-09 00:18:141648 this.setTextFilterValue('');
Blink Reformat4c46d092018-04-07 15:32:371649 const node = this._reveal(request);
Tim van der Lippe1d6e57a2019-09-30 11:55:341650 if (node) {
Blink Reformat4c46d092018-04-07 15:32:371651 node.select();
Tim van der Lippe1d6e57a2019-09-30 11:55:341652 }
Blink Reformat4c46d092018-04-07 15:32:371653 }
1654
1655 removeAllNodeHighlights() {
1656 if (this._highlightedNode) {
1657 this._highlightedNode.element().classList.remove('highlighted-row');
1658 this._highlightedNode = null;
1659 }
1660 }
1661
1662 /**
1663 * @param {!Network.NetworkRequestNode} node
1664 */
1665 _highlightNode(node) {
1666 UI.runCSSAnimationOnce(node.element(), 'highlighted-row');
1667 this._highlightedNode = node;
1668 }
1669
1670 /**
Harley Libcf41f92018-09-10 18:01:131671 * @param {!Array<!SDK.NetworkRequest>} requests
1672 * @return {!Array<!SDK.NetworkRequest>}
1673 */
1674 _filterOutBlobRequests(requests) {
1675 return requests.filter(request => !request.isBlobRequest());
1676 }
1677
1678 /**
Blink Reformat4c46d092018-04-07 15:32:371679 * @param {!SDK.NetworkRequest} request
Jan Scheffler7c50d1f2019-12-17 13:33:291680 * @param {boolean} includeCookies
Blink Reformat4c46d092018-04-07 15:32:371681 * @return {!Promise<string>}
1682 */
Jan Scheffler7c50d1f2019-12-17 13:33:291683 async _generateFetchCall(request, includeCookies) {
Blink Reformat4c46d092018-04-07 15:32:371684 const ignoredHeaders = {
1685 // Internal headers
1686 'method': 1,
1687 'path': 1,
1688 'scheme': 1,
1689 'version': 1,
1690
1691 // Unsafe headers
1692 // Keep this list synchronized with src/net/http/http_util.cc
1693 'accept-charset': 1,
1694 'accept-encoding': 1,
1695 'access-control-request-headers': 1,
1696 'access-control-request-method': 1,
1697 'connection': 1,
1698 'content-length': 1,
1699 'cookie': 1,
1700 'cookie2': 1,
1701 'date': 1,
1702 'dnt': 1,
1703 'expect': 1,
1704 'host': 1,
1705 'keep-alive': 1,
1706 'origin': 1,
1707 'referer': 1,
1708 'te': 1,
1709 'trailer': 1,
1710 'transfer-encoding': 1,
1711 'upgrade': 1,
1712 'via': 1,
1713 // TODO(phistuck) - remove this once crbug.com/571722 is fixed.
1714 'user-agent': 1
1715 };
1716
1717 const credentialHeaders = {'cookie': 1, 'authorization': 1};
1718
1719 const url = JSON.stringify(request.url());
1720
1721 const requestHeaders = request.requestHeaders();
1722 const headerData = requestHeaders.reduce((result, header) => {
1723 const name = header.name;
1724
Tim van der Lippe1d6e57a2019-09-30 11:55:341725 if (!ignoredHeaders[name.toLowerCase()] && !name.includes(':')) {
Blink Reformat4c46d092018-04-07 15:32:371726 result.append(name, header.value);
Tim van der Lippe1d6e57a2019-09-30 11:55:341727 }
Blink Reformat4c46d092018-04-07 15:32:371728
1729 return result;
1730 }, new Headers());
1731
1732 const headers = {};
Tim van der Lippe1d6e57a2019-09-30 11:55:341733 for (const headerArray of headerData) {
PhistucK6ed0a3e2018-08-04 06:28:411734 headers[headerArray[0]] = headerArray[1];
Tim van der Lippe1d6e57a2019-09-30 11:55:341735 }
Blink Reformat4c46d092018-04-07 15:32:371736
1737 const credentials =
Jan Scheffler341eea52019-12-12 09:08:411738 request.requestCookies.length || requestHeaders.some(({name}) => credentialHeaders[name.toLowerCase()]) ?
1739 'include' :
1740 'omit';
Blink Reformat4c46d092018-04-07 15:32:371741
1742 const referrerHeader = requestHeaders.find(({name}) => name.toLowerCase() === 'referer');
1743
1744 const referrer = referrerHeader ? referrerHeader.value : void 0;
1745
1746 const referrerPolicy = request.referrerPolicy() || void 0;
1747
1748 const requestBody = await request.requestFormData();
1749
1750 const fetchOptions = {
PhistucK6ed0a3e2018-08-04 06:28:411751 headers: Object.keys(headers).length ? headers : void 0,
Blink Reformat4c46d092018-04-07 15:32:371752 referrer,
1753 referrerPolicy,
1754 body: requestBody,
1755 method: request.requestMethod,
1756 mode: 'cors'
1757 };
1758
Jan Scheffler7c50d1f2019-12-17 13:33:291759 if (includeCookies) {
1760 const cookieHeader = requestHeaders.find(header => header.name.toLowerCase() === 'cookie');
1761 if (cookieHeader) {
1762 fetchOptions.headers = {
1763 ...headers,
1764 'cookie': cookieHeader.value,
1765 };
1766 }
1767 } else {
1768 fetchOptions.credentials = credentials;
1769 }
1770
Jan Scheffler172d5212020-01-02 14:42:561771 const options = JSON.stringify(fetchOptions, null, 2);
Blink Reformat4c46d092018-04-07 15:32:371772 return `fetch(${url}, ${options});`;
1773 }
1774
1775 /**
Harley Libcf41f92018-09-10 18:01:131776 * @param {!Array<!SDK.NetworkRequest>} requests
Jan Scheffler7c50d1f2019-12-17 13:33:291777 * @param {boolean} includeCookies
Harley Libcf41f92018-09-10 18:01:131778 * @return {!Promise<string>}
1779 */
Jan Scheffler7c50d1f2019-12-17 13:33:291780 async _generateAllFetchCall(requests, includeCookies) {
Harley Libcf41f92018-09-10 18:01:131781 const nonBlobRequests = this._filterOutBlobRequests(requests);
Jan Scheffler7c50d1f2019-12-17 13:33:291782 const commands =
1783 await Promise.all(nonBlobRequests.map(request => this._generateFetchCall(request, includeCookies)));
Harley Libcf41f92018-09-10 18:01:131784 return commands.join(' ;\n');
1785 }
1786
1787 /**
Blink Reformat4c46d092018-04-07 15:32:371788 * @param {!SDK.NetworkRequest} request
1789 * @param {string} platform
1790 * @return {!Promise<string>}
1791 */
1792 async _generateCurlCommand(request, platform) {
Jan Scheffler172d5212020-01-02 14:42:561793 let command = [];
Eric Lawrence7a7b3682019-10-17 23:06:361794 // Most of these headers are derived from the URL and are automatically added by cURL.
1795 // The |Accept-Encoding| header is ignored to prevent decompression errors. crbug.com/1015321
1796 const ignoredHeaders = {'accept-encoding': 1, 'host': 1, 'method': 1, 'path': 1, 'scheme': 1, 'version': 1};
Blink Reformat4c46d092018-04-07 15:32:371797
1798 function escapeStringWin(str) {
1799 /* If there are no new line characters do not escape the " characters
1800 since it only uglifies the command.
1801
1802 Because cmd.exe parser and MS Crt arguments parsers use some of the
1803 same escape characters, they can interact with each other in
1804 horrible ways, the order of operations is critical.
1805
1806 Replace \ with \\ first because it is an escape character for certain
1807 conditions in both parsers.
1808
1809 Replace all " with \" to ensure the first parser does not remove it.
1810
1811 Then escape all characters we are not sure about with ^ to ensure it
1812 gets to MS Crt parser safely.
1813
1814 The % character is special because MS Crt parser will try and look for
1815 ENV variables and fill them in it's place. We cannot escape them with %
1816 and cannot escape them with ^ (because it's cmd.exe's escape not MS Crt
1817 parser); So we can get cmd.exe parser to escape the character after it,
1818 if it is followed by a valid beginning character of an ENV variable.
1819 This ensures we do not try and double escape another ^ if it was placed
1820 by the previous replace.
1821
1822 Lastly we replace new lines with ^ and TWO new lines because the first
1823 new line is there to enact the escape command the second is the character
1824 to escape (in this case new line).
1825 */
1826 const encapsChars = /[\r\n]/.test(str) ? '^"' : '"';
1827 return encapsChars +
1828 str.replace(/\\/g, '\\\\')
1829 .replace(/"/g, '\\"')
1830 .replace(/[^a-zA-Z0-9\s_\-:=+~'\/.',?;()*`]/g, '^$&')
1831 .replace(/%(?=[a-zA-Z0-9_])/g, '%^')
1832 .replace(/\r\n|[\n\r]/g, '^\n\n') +
1833 encapsChars;
1834 }
1835
1836 /**
1837 * @param {string} str
1838 * @return {string}
1839 */
1840 function escapeStringPosix(str) {
1841 /**
1842 * @param {string} x
1843 * @return {string}
1844 */
1845 function escapeCharacter(x) {
Erik Luoaa676752018-08-21 05:52:221846 const code = x.charCodeAt(0);
Joey Arhar2d21f712019-05-20 21:07:121847 let hexString = code.toString(16);
1848 // Zero pad to four digits to comply with ANSI-C Quoting:
1849 // http://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html
Tim van der Lippe1d6e57a2019-09-30 11:55:341850 while (hexString.length < 4) {
Joey Arhar2d21f712019-05-20 21:07:121851 hexString = '0' + hexString;
Tim van der Lippe1d6e57a2019-09-30 11:55:341852 }
Joey Arhar2d21f712019-05-20 21:07:121853
1854 return '\\u' + hexString;
Blink Reformat4c46d092018-04-07 15:32:371855 }
1856
Joey Arhar512e3742019-01-25 21:33:541857 if (/[\u0000-\u001f\u007f-\u009f!]|\'/.test(str)) {
Blink Reformat4c46d092018-04-07 15:32:371858 // Use ANSI-C quoting syntax.
1859 return '$\'' +
1860 str.replace(/\\/g, '\\\\')
1861 .replace(/\'/g, '\\\'')
1862 .replace(/\n/g, '\\n')
1863 .replace(/\r/g, '\\r')
Joey Arhar512e3742019-01-25 21:33:541864 .replace(/[\u0000-\u001f\u007f-\u009f!]/g, escapeCharacter) +
Blink Reformat4c46d092018-04-07 15:32:371865 '\'';
1866 } else {
1867 // Use single quote syntax.
1868 return '\'' + str + '\'';
1869 }
1870 }
1871
1872 // cURL command expected to run on the same platform that DevTools run
1873 // (it may be different from the inspected page platform).
1874 const escapeString = platform === 'win' ? escapeStringWin : escapeStringPosix;
1875
1876 command.push(escapeString(request.url()).replace(/[[{}\]]/g, '\\$&'));
1877
1878 let inferredMethod = 'GET';
1879 const data = [];
1880 const requestContentType = request.requestContentType();
1881 const formData = await request.requestFormData();
1882 if (requestContentType && requestContentType.startsWith('application/x-www-form-urlencoded') && formData) {
Jan Scheffler172d5212020-01-02 14:42:561883 data.push('--data ' + escapeString(formData));
Blink Reformat4c46d092018-04-07 15:32:371884 ignoredHeaders['content-length'] = true;
1885 inferredMethod = 'POST';
1886 } else if (formData) {
Jan Scheffler172d5212020-01-02 14:42:561887 data.push('--data-binary ' + escapeString(formData));
Blink Reformat4c46d092018-04-07 15:32:371888 ignoredHeaders['content-length'] = true;
1889 inferredMethod = 'POST';
1890 }
1891
1892 if (request.requestMethod !== inferredMethod) {
Jan Schefflera4e536a2020-01-09 08:51:291893 command.push('-X ' + escapeString(request.requestMethod));
Blink Reformat4c46d092018-04-07 15:32:371894 }
1895
1896 const requestHeaders = request.requestHeaders();
1897 for (let i = 0; i < requestHeaders.length; i++) {
1898 const header = requestHeaders[i];
1899 const name = header.name.replace(/^:/, ''); // Translate SPDY v3 headers to HTTP headers.
Tim van der Lippe1d6e57a2019-09-30 11:55:341900 if (name.toLowerCase() in ignoredHeaders) {
Blink Reformat4c46d092018-04-07 15:32:371901 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341902 }
Jan Scheffler172d5212020-01-02 14:42:561903 command.push('-H ' + escapeString(name + ': ' + header.value));
Blink Reformat4c46d092018-04-07 15:32:371904 }
1905 command = command.concat(data);
1906 command.push('--compressed');
1907
Tim van der Lippe1d6e57a2019-09-30 11:55:341908 if (request.securityState() === Protocol.Security.SecurityState.Insecure) {
Blink Reformat4c46d092018-04-07 15:32:371909 command.push('--insecure');
Tim van der Lippe1d6e57a2019-09-30 11:55:341910 }
Jan Scheffler172d5212020-01-02 14:42:561911 return 'curl ' + command.join(command.length >= 3 ? (platform === 'win' ? ' ^\n ' : ' \\\n ') : ' ');
Blink Reformat4c46d092018-04-07 15:32:371912 }
1913
1914 /**
Harley Libcf41f92018-09-10 18:01:131915 * @param {!Array<!SDK.NetworkRequest>} requests
1916 * @param {string} platform
1917 * @return {!Promise<string>}
1918 */
1919 async _generateAllCurlCommand(requests, platform) {
1920 const nonBlobRequests = this._filterOutBlobRequests(requests);
1921 const commands = await Promise.all(nonBlobRequests.map(request => this._generateCurlCommand(request, platform)));
Tim van der Lippe1d6e57a2019-09-30 11:55:341922 if (platform === 'win') {
Harley Libcf41f92018-09-10 18:01:131923 return commands.join(' &\r\n');
Tim van der Lippe1d6e57a2019-09-30 11:55:341924 } else {
Harley Libcf41f92018-09-10 18:01:131925 return commands.join(' ;\n');
Tim van der Lippe1d6e57a2019-09-30 11:55:341926 }
Harley Libcf41f92018-09-10 18:01:131927 }
1928
1929 /**
Blink Reformat4c46d092018-04-07 15:32:371930 * @param {!SDK.NetworkRequest} request
1931 * @return {!Promise<string>}
1932 */
1933 async _generatePowerShellCommand(request) {
Jan Scheffler172d5212020-01-02 14:42:561934 const command = [];
Blink Reformat4c46d092018-04-07 15:32:371935 const ignoredHeaders =
1936 new Set(['host', 'connection', 'proxy-connection', 'content-length', 'expect', 'range', 'content-type']);
1937
1938 /**
1939 * @param {string} str
1940 * @return {string}
1941 */
1942 function escapeString(str) {
1943 return '"' +
1944 str.replace(/[`\$"]/g, '`$&').replace(/[^\x20-\x7E]/g, char => '$([char]' + char.charCodeAt(0) + ')') + '"';
1945 }
1946
Jan Scheffler172d5212020-01-02 14:42:561947 command.push('-Uri ' + escapeString(request.url()));
Blink Reformat4c46d092018-04-07 15:32:371948
1949 if (request.requestMethod !== 'GET') {
Jan Scheffler172d5212020-01-02 14:42:561950 command.push('-Method ' + escapeString(request.requestMethod));
Blink Reformat4c46d092018-04-07 15:32:371951 }
1952
1953 const requestHeaders = request.requestHeaders();
1954 const headerNameValuePairs = [];
1955 for (const header of requestHeaders) {
1956 const name = header.name.replace(/^:/, ''); // Translate h2 headers to HTTP headers.
Tim van der Lippe1d6e57a2019-09-30 11:55:341957 if (ignoredHeaders.has(name.toLowerCase())) {
Blink Reformat4c46d092018-04-07 15:32:371958 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:341959 }
Blink Reformat4c46d092018-04-07 15:32:371960 headerNameValuePairs.push(escapeString(name) + '=' + escapeString(header.value));
1961 }
1962 if (headerNameValuePairs.length) {
Jan Scheffler172d5212020-01-02 14:42:561963 command.push('-Headers @{\n' + headerNameValuePairs.join('\n ') + '\n}');
Blink Reformat4c46d092018-04-07 15:32:371964 }
1965
1966 const contentTypeHeader = requestHeaders.find(({name}) => name.toLowerCase() === 'content-type');
1967 if (contentTypeHeader) {
Jan Scheffler172d5212020-01-02 14:42:561968 command.push('-ContentType ' + escapeString(contentTypeHeader.value));
Blink Reformat4c46d092018-04-07 15:32:371969 }
1970
1971 const formData = await request.requestFormData();
1972 if (formData) {
Blink Reformat4c46d092018-04-07 15:32:371973 const body = escapeString(formData);
Tim van der Lippe1d6e57a2019-09-30 11:55:341974 if (/[^\x20-\x7E]/.test(formData)) {
Jan Scheffler172d5212020-01-02 14:42:561975 command.push('-Body ([System.Text.Encoding]::UTF8.GetBytes(' + body + '))');
Tim van der Lippe1d6e57a2019-09-30 11:55:341976 } else {
Jan Scheffler172d5212020-01-02 14:42:561977 command.push('-Body ' + body);
Tim van der Lippe1d6e57a2019-09-30 11:55:341978 }
Blink Reformat4c46d092018-04-07 15:32:371979 }
1980
Jan Scheffler172d5212020-01-02 14:42:561981 return 'Invoke-WebRequest ' + command.join(command.length >= 3 ? ' `\n' : ' ');
Blink Reformat4c46d092018-04-07 15:32:371982 }
Harley Libcf41f92018-09-10 18:01:131983
1984 /**
1985 * @param {!Array<!SDK.NetworkRequest>} requests
1986 * @return {!Promise<string>}
1987 */
1988 async _generateAllPowerShellCommand(requests) {
1989 const nonBlobRequests = this._filterOutBlobRequests(requests);
1990 const commands = await Promise.all(nonBlobRequests.map(request => this._generatePowerShellCommand(request)));
1991 return commands.join(';\r\n');
1992 }
Joey Arhara86c14e2019-03-12 03:20:501993
1994 /**
1995 * @return {string}
1996 */
1997 static getDCLEventColor() {
Tim van der Lippe1d6e57a2019-09-30 11:55:341998 if (UI.themeSupport.themeName() === 'dark') {
Joey Arhara86c14e2019-03-12 03:20:501999 return '#03A9F4';
Tim van der Lippe1d6e57a2019-09-30 11:55:342000 }
Joey Arhara86c14e2019-03-12 03:20:502001 return '#0867CB';
2002 }
2003
2004 /**
2005 * @return {string}
2006 */
2007 static getLoadEventColor() {
2008 return UI.themeSupport.patchColorText('#B31412', UI.ThemeSupport.ColorUsage.Foreground);
2009 }
Paul Lewis56509652019-12-06 12:51:582010}
Blink Reformat4c46d092018-04-07 15:32:372011
Paul Lewis56509652019-12-06 12:51:582012export const _isFilteredOutSymbol = Symbol('isFilteredOut');
2013export const _networkNodeSymbol = Symbol('NetworkNode');
Blink Reformat4c46d092018-04-07 15:32:372014
Paul Lewis56509652019-12-06 12:51:582015export const HTTPSchemas = {
Blink Reformat4c46d092018-04-07 15:32:372016 'http': true,
2017 'https': true,
2018 'ws': true,
2019 'wss': true
2020};
2021
2022/** @enum {symbol} */
Paul Lewis56509652019-12-06 12:51:582023export const Events = {
Brandon Goddard88d885a2019-10-31 16:11:052024 RequestSelected: Symbol('RequestSelected'),
2025 RequestActivated: Symbol('RequestActivated')
Blink Reformat4c46d092018-04-07 15:32:372026};
2027
2028/** @enum {string} */
Paul Lewis56509652019-12-06 12:51:582029export const FilterType = {
Blink Reformat4c46d092018-04-07 15:32:372030 Domain: 'domain',
2031 HasResponseHeader: 'has-response-header',
2032 Is: 'is',
2033 LargerThan: 'larger-than',
2034 Method: 'method',
2035 MimeType: 'mime-type',
2036 MixedContent: 'mixed-content',
2037 Priority: 'priority',
2038 Scheme: 'scheme',
2039 SetCookieDomain: 'set-cookie-domain',
2040 SetCookieName: 'set-cookie-name',
2041 SetCookieValue: 'set-cookie-value',
Jan Scheffler341eea52019-12-12 09:08:412042 CookieDomain: 'cookie-domain',
2043 CookieName: 'cookie-name',
2044 CookieValue: 'cookie-value',
Blink Reformat4c46d092018-04-07 15:32:372045 StatusCode: 'status-code'
2046};
2047
2048/** @enum {string} */
Paul Lewis56509652019-12-06 12:51:582049export const MixedContentFilterValues = {
Blink Reformat4c46d092018-04-07 15:32:372050 All: 'all',
2051 Displayed: 'displayed',
2052 Blocked: 'blocked',
2053 BlockOverridden: 'block-overridden'
2054};
2055
2056/** @enum {string} */
Paul Lewis56509652019-12-06 12:51:582057export const IsFilterType = {
Blink Reformat4c46d092018-04-07 15:32:372058 Running: 'running',
Joey Arhard183e7e2019-02-28 03:37:052059 FromCache: 'from-cache',
2060 ServiceWorkerIntercepted: 'service-worker-intercepted',
2061 ServiceWorkerInitiated: 'service-worker-initiated'
Blink Reformat4c46d092018-04-07 15:32:372062};
2063
2064/** @type {!Array<string>} */
Paul Lewis56509652019-12-06 12:51:582065export const _searchKeys = Object.keys(FilterType).map(key => FilterType[key]);
Blink Reformat4c46d092018-04-07 15:32:372066
2067/**
2068 * @interface
2069 */
Paul Lewis56509652019-12-06 12:51:582070export class GroupLookupInterface {
Blink Reformat4c46d092018-04-07 15:32:372071 /**
2072 * @param {!SDK.NetworkRequest} request
2073 * @return {?Network.NetworkGroupNode}
2074 */
Paul Lewis56509652019-12-06 12:51:582075 groupNodeForRequest(request) {
2076 }
Blink Reformat4c46d092018-04-07 15:32:372077
Paul Lewis56509652019-12-06 12:51:582078 reset() {
2079 }
2080}
2081
2082/* Legacy exported object */
2083self.Network = self.Network || {};
2084
2085/* Legacy exported object */
2086Network = Network || {};
2087
2088/**
2089 * @constructor
2090 */
2091Network.NetworkLogView = NetworkLogView;
2092
2093/** @typedef {function(!SDK.NetworkRequest): boolean} */
2094Network.NetworkLogView.Filter;
2095
2096Network.NetworkLogView._isFilteredOutSymbol = _isFilteredOutSymbol;
2097Network.NetworkLogView._networkNodeSymbol = _networkNodeSymbol;
2098Network.NetworkLogView.HTTPSchemas = HTTPSchemas;
2099
2100/** @enum {symbol} */
2101Network.NetworkLogView.Events = Events;
2102
2103/** @enum {string} */
2104Network.NetworkLogView.FilterType = FilterType;
2105
2106/** @enum {string} */
2107Network.NetworkLogView.MixedContentFilterValues = MixedContentFilterValues;
2108
2109/** @enum {string} */
2110Network.NetworkLogView.IsFilterType = IsFilterType;
2111
2112/** @type {!Array<string>} */
2113Network.NetworkLogView._searchKeys = _searchKeys;
2114
2115/**
2116 * @interface
2117 */
2118Network.GroupLookupInterface = GroupLookupInterface;