Best JavaScript code snippet using playwright-internal
NetworkManager.js
Source:NetworkManager.js  
1/*2 * Copyright (C) 2011 Google Inc. All rights reserved.3 *4 * Redistribution and use in source and binary forms, with or without5 * modification, are permitted provided that the following conditions are6 * met:7 *8 *     * Redistributions of source code must retain the above copyright9 * notice, this list of conditions and the following disclaimer.10 *     * Redistributions in binary form must reproduce the above11 * copyright notice, this list of conditions and the following disclaimer12 * in the documentation and/or other materials provided with the13 * distribution.14 *     * Neither the name of Google Inc. nor the names of its15 * contributors may be used to endorse or promote products derived from16 * this software without specific prior written permission.17 *18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.29 */30/**31 * @unrestricted32 */33SDK.NetworkManager = class extends SDK.SDKModel {34  /**35   * @param {!SDK.Target} target36   */37  constructor(target) {38    super(target);39    this._dispatcher = new SDK.NetworkDispatcher(this);40    this._networkAgent = target.networkAgent();41    target.registerNetworkDispatcher(this._dispatcher);42    if (Common.moduleSetting('cacheDisabled').get())43      this._networkAgent.setCacheDisabled(true);44    // Limit buffer when talking to a remote device.45    if (Runtime.queryParam('remoteFrontend') || Runtime.queryParam('ws'))46      this._networkAgent.enable(10000000, 5000000);47    else48      this._networkAgent.enable();49    this._bypassServiceWorkerSetting = Common.settings.createSetting('bypassServiceWorker', false);50    if (this._bypassServiceWorkerSetting.get())51      this._bypassServiceWorkerChanged();52    this._bypassServiceWorkerSetting.addChangeListener(this._bypassServiceWorkerChanged, this);53    Common.moduleSetting('cacheDisabled').addChangeListener(this._cacheDisabledSettingChanged, this);54  }55  /**56   * @param {!SDK.NetworkRequest} request57   * @return {?SDK.NetworkManager}58   */59  static forRequest(request) {60    return request[SDK.NetworkManager._networkManagerForRequestSymbol];61  }62  /**63   * @param {!SDK.NetworkRequest} request64   * @return {boolean}65   */66  static canReplayRequest(request) {67    return !!request[SDK.NetworkManager._networkManagerForRequestSymbol] &&68        request.resourceType() === Common.resourceTypes.XHR;69  }70  /**71   * @param {!SDK.NetworkRequest} request72   */73  static replayRequest(request) {74    var manager = request[SDK.NetworkManager._networkManagerForRequestSymbol];75    if (!manager)76      return;77    manager._networkAgent.replayXHR(request.requestId());78  }79  /**80   * @param {!SDK.NetworkRequest} request81   * @param {string} query82   * @param {boolean} caseSensitive83   * @param {boolean} isRegex84   * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}85   */86  static async searchInRequest(request, query, caseSensitive, isRegex) {87    var manager = SDK.NetworkManager.forRequest(request);88    if (!manager)89      return [];90    var response = await manager._networkAgent.invoke_searchInResponseBody(91        {requestId: request.requestId(), query: query, caseSensitive: caseSensitive, isRegex: isRegex});92    return response.result || [];93  }94  /**95   * @param {!SDK.NetworkRequest} request96   * @return {!Promise<!SDK.NetworkRequest.ContentData>}97   */98  static async requestContentData(request) {99    if (request.resourceType() === Common.resourceTypes.WebSocket)100      return {error: 'Content for WebSockets is currently not supported', content: null, encoded: false};101    if (!request.finished)102      await request.once(SDK.NetworkRequest.Events.FinishedLoading);103    var manager = SDK.NetworkManager.forRequest(request);104    if (!manager)105      return {error: 'No network manager for request', content: null, encoded: false};106    var response = await manager._networkAgent.invoke_getResponseBody({requestId: request.requestId()});107    var error = response[Protocol.Error] || null;108    return {error: error, content: error ? null : response.body, encoded: response.base64Encoded};109  }110  /**111   * @param {!SDK.NetworkManager.Conditions} conditions112   * @return {!Protocol.Network.ConnectionType}113   * TODO(allada): this belongs to NetworkConditionsSelector, which should hardcode/guess it.114   */115  static _connectionType(conditions) {116    if (!conditions.download && !conditions.upload)117      return Protocol.Network.ConnectionType.None;118    var types = SDK.NetworkManager._connectionTypes;119    if (!types) {120      SDK.NetworkManager._connectionTypes = [];121      types = SDK.NetworkManager._connectionTypes;122      types.push(['2g', Protocol.Network.ConnectionType.Cellular2g]);123      types.push(['3g', Protocol.Network.ConnectionType.Cellular3g]);124      types.push(['4g', Protocol.Network.ConnectionType.Cellular4g]);125      types.push(['bluetooth', Protocol.Network.ConnectionType.Bluetooth]);126      types.push(['wifi', Protocol.Network.ConnectionType.Wifi]);127      types.push(['wimax', Protocol.Network.ConnectionType.Wimax]);128    }129    for (var type of types) {130      if (conditions.title.toLowerCase().indexOf(type[0]) !== -1)131        return type[1];132    }133    return Protocol.Network.ConnectionType.Other;134  }135  /**136   * @param {!Object} headers137   * @return {!Object<string, string>}138   */139  static lowercaseHeaders(headers) {140    var newHeaders = {};141    for (var headerName in headers)142      newHeaders[headerName.toLowerCase()] = headers[headerName];143    return newHeaders;144  }145  /**146   * @param {string} url147   * @return {!SDK.NetworkRequest}148   */149  inflightRequestForURL(url) {150    return this._dispatcher._inflightRequestsByURL[url];151  }152  /**153   * @param {!Common.Event} event154   */155  _cacheDisabledSettingChanged(event) {156    var enabled = /** @type {boolean} */ (event.data);157    this._networkAgent.setCacheDisabled(enabled);158  }159  /**160   * @override161   */162  dispose() {163    Common.moduleSetting('cacheDisabled').removeChangeListener(this._cacheDisabledSettingChanged, this);164  }165  _bypassServiceWorkerChanged() {166    this._networkAgent.setBypassServiceWorker(this._bypassServiceWorkerSetting.get());167  }168};169SDK.SDKModel.register(SDK.NetworkManager, SDK.Target.Capability.Network, true);170/** @enum {symbol} */171SDK.NetworkManager.Events = {172  RequestStarted: Symbol('RequestStarted'),173  RequestUpdated: Symbol('RequestUpdated'),174  RequestFinished: Symbol('RequestFinished'),175  RequestUpdateDropped: Symbol('RequestUpdateDropped'),176  ResponseReceived: Symbol('ResponseReceived'),177  MessageGenerated: Symbol('MessageGenerated'),178  RequestRedirected: Symbol('RequestRedirected'),179};180/** @typedef {{message: string, requestId: string, warning: boolean}} */181SDK.NetworkManager.Message;182SDK.NetworkManager._MIMETypes = {183  'text/html': {'document': true},184  'text/xml': {'document': true},185  'text/plain': {'document': true},186  'application/xhtml+xml': {'document': true},187  'image/svg+xml': {'document': true},188  'text/css': {'stylesheet': true},189  'text/xsl': {'stylesheet': true},190  'text/vtt': {'texttrack': true},191};192/**193 * @typedef {{194 *   download: number,195 *   upload: number,196 *   latency: number,197 *   title: string,198 * }}199 **/200SDK.NetworkManager.Conditions;201/** @type {!SDK.NetworkManager.Conditions} */202SDK.NetworkManager.NoThrottlingConditions = {203  title: Common.UIString('Online'),204  download: -1,205  upload: -1,206  latency: 0207};208/** @type {!SDK.NetworkManager.Conditions} */209SDK.NetworkManager.OfflineConditions = {210  title: Common.UIString('Offline'),211  download: 0,212  upload: 0,213  latency: 0,214};215/** @type {!SDK.NetworkManager.Conditions} */216SDK.NetworkManager.Slow3GConditions = {217  title: Common.UIString('Slow 3G'),218  download: 500 * 1024 / 8 * .8,219  upload: 500 * 1024 / 8 * .8,220  latency: 400 * 5,221};222/** @type {!SDK.NetworkManager.Conditions} */223SDK.NetworkManager.Fast3GConditions = {224  title: Common.UIString('Fast 3G'),225  download: 1.6 * 1024 * 1024 / 8 * .9,226  upload: 750 * 1024 / 8 * .9,227  latency: 150 * 3.75,228};229/** @typedef {{url: string, enabled: boolean}} */230SDK.NetworkManager.BlockedPattern;231SDK.NetworkManager._networkManagerForRequestSymbol = Symbol('NetworkManager');232/**233 * @implements {Protocol.NetworkDispatcher}234 * @unrestricted235 */236SDK.NetworkDispatcher = class {237  /**238   * @param {!SDK.NetworkManager} manager239   */240  constructor(manager) {241    this._manager = manager;242    /** @type {!Object<!Protocol.Network.RequestId, !SDK.NetworkRequest>} */243    this._inflightRequestsById = {};244    /** @type {!Object<string, !SDK.NetworkRequest>} */245    this._inflightRequestsByURL = {};246  }247  /**248   * @param {!Protocol.Network.Headers} headersMap249   * @return {!Array.<!SDK.NetworkRequest.NameValue>}250   */251  _headersMapToHeadersArray(headersMap) {252    var result = [];253    for (var name in headersMap) {254      var values = headersMap[name].split('\n');255      for (var i = 0; i < values.length; ++i)256        result.push({name: name, value: values[i]});257    }258    return result;259  }260  /**261   * @param {!SDK.NetworkRequest} networkRequest262   * @param {!Protocol.Network.Request} request263   */264  _updateNetworkRequestWithRequest(networkRequest, request) {265    networkRequest.requestMethod = request.method;266    networkRequest.setRequestHeaders(this._headersMapToHeadersArray(request.headers));267    networkRequest.requestFormData = request.postData;268    networkRequest.setInitialPriority(request.initialPriority);269    networkRequest.mixedContentType = request.mixedContentType || Protocol.Security.MixedContentType.None;270    networkRequest.setReferrerPolicy(request.referrerPolicy);271  }272  /**273   * @param {!SDK.NetworkRequest} networkRequest274   * @param {!Protocol.Network.Response=} response275   */276  _updateNetworkRequestWithResponse(networkRequest, response) {277    if (response.url && networkRequest.url() !== response.url)278      networkRequest.setUrl(response.url);279    networkRequest.mimeType = response.mimeType;280    networkRequest.statusCode = response.status;281    networkRequest.statusText = response.statusText;282    networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);283    if (response.encodedDataLength >= 0)284      networkRequest.setTransferSize(response.encodedDataLength);285    if (response.headersText)286      networkRequest.responseHeadersText = response.headersText;287    if (response.requestHeaders) {288      networkRequest.setRequestHeaders(this._headersMapToHeadersArray(response.requestHeaders));289      networkRequest.setRequestHeadersText(response.requestHeadersText || '');290    }291    networkRequest.connectionReused = response.connectionReused;292    networkRequest.connectionId = String(response.connectionId);293    if (response.remoteIPAddress)294      networkRequest.setRemoteAddress(response.remoteIPAddress, response.remotePort || -1);295    if (response.fromServiceWorker)296      networkRequest.fetchedViaServiceWorker = true;297    if (response.fromDiskCache)298      networkRequest.setFromDiskCache();299    networkRequest.timing = response.timing;300    networkRequest.protocol = response.protocol;301    networkRequest.setSecurityState(response.securityState);302    if (!this._mimeTypeIsConsistentWithType(networkRequest)) {303      var message = Common.UIString(304          'Resource interpreted as %s but transferred with MIME type %s: "%s".', networkRequest.resourceType().title(),305          networkRequest.mimeType, networkRequest.url());306      this._manager.dispatchEventToListeners(307          SDK.NetworkManager.Events.MessageGenerated,308          {message: message, requestId: networkRequest.requestId(), warning: true});309    }310    if (response.securityDetails)311      networkRequest.setSecurityDetails(response.securityDetails);312  }313  /**314   * @param {!SDK.NetworkRequest} networkRequest315   * @return {boolean}316   */317  _mimeTypeIsConsistentWithType(networkRequest) {318    // If status is an error, content is likely to be of an inconsistent type,319    // as it's going to be an error message. We do not want to emit a warning320    // for this, though, as this will already be reported as resource loading failure.321    // Also, if a URL like http://localhost/wiki/load.php?debug=true&lang=en produces text/css and gets reloaded,322    // it is 304 Not Modified and its guessed mime-type is text/php, which is wrong.323    // Don't check for mime-types in 304-resources.324    if (networkRequest.hasErrorStatusCode() || networkRequest.statusCode === 304 || networkRequest.statusCode === 204)325      return true;326    var resourceType = networkRequest.resourceType();327    if (resourceType !== Common.resourceTypes.Stylesheet && resourceType !== Common.resourceTypes.Document &&328        resourceType !== Common.resourceTypes.TextTrack)329      return true;330    if (!networkRequest.mimeType)331      return true;  // Might be not known for cached resources with null responses.332    if (networkRequest.mimeType in SDK.NetworkManager._MIMETypes)333      return resourceType.name() in SDK.NetworkManager._MIMETypes[networkRequest.mimeType];334    return false;335  }336  /**337   * @override338   * @param {!Protocol.Network.RequestId} requestId339   * @param {!Protocol.Network.ResourcePriority} newPriority340   * @param {!Protocol.Network.MonotonicTime} timestamp341   */342  resourceChangedPriority(requestId, newPriority, timestamp) {343    var networkRequest = this._inflightRequestsById[requestId];344    if (networkRequest)345      networkRequest.setPriority(newPriority);346  }347  /**348   * @override349   * @param {!Protocol.Network.RequestId} requestId350   * @param {!Protocol.Network.LoaderId} loaderId351   * @param {string} documentURL352   * @param {!Protocol.Network.Request} request353   * @param {!Protocol.Network.MonotonicTime} time354   * @param {!Protocol.Network.TimeSinceEpoch} wallTime355   * @param {!Protocol.Network.Initiator} initiator356   * @param {!Protocol.Network.Response=} redirectResponse357   * @param {!Protocol.Page.ResourceType=} resourceType358   * @param {!Protocol.Page.FrameId=} frameId359   */360  requestWillBeSent(361      requestId, loaderId, documentURL, request, time, wallTime, initiator, redirectResponse, resourceType, frameId) {362    var networkRequest = this._inflightRequestsById[requestId];363    if (networkRequest) {364      // FIXME: move this check to the backend.365      if (!redirectResponse)366        return;367      this.responseReceived(requestId, loaderId, time, Protocol.Page.ResourceType.Other, redirectResponse, frameId);368      networkRequest = this._appendRedirect(requestId, time, request.url);369      this._manager.dispatchEventToListeners(SDK.NetworkManager.Events.RequestRedirected, networkRequest);370    } else {371      networkRequest =372          this._createNetworkRequest(requestId, frameId || '', loaderId, request.url, documentURL, initiator);373    }374    networkRequest.hasNetworkData = true;375    this._updateNetworkRequestWithRequest(networkRequest, request);376    networkRequest.setIssueTime(time, wallTime);377    networkRequest.setResourceType(378        resourceType ? Common.resourceTypes[resourceType] : Protocol.Page.ResourceType.Other);379    this._startNetworkRequest(networkRequest);380  }381  /**382   * @override383   * @param {!Protocol.Network.RequestId} requestId384   */385  requestServedFromCache(requestId) {386    var networkRequest = this._inflightRequestsById[requestId];387    if (!networkRequest)388      return;389    networkRequest.setFromMemoryCache();390  }391  /**392   * @override393   * @param {!Protocol.Network.RequestId} requestId394   * @param {!Protocol.Network.LoaderId} loaderId395   * @param {!Protocol.Network.MonotonicTime} time396   * @param {!Protocol.Page.ResourceType} resourceType397   * @param {!Protocol.Network.Response} response398   * @param {!Protocol.Page.FrameId=} frameId399   */400  responseReceived(requestId, loaderId, time, resourceType, response, frameId) {401    var networkRequest = this._inflightRequestsById[requestId];402    var lowercaseHeaders = SDK.NetworkManager.lowercaseHeaders(response.headers);403    if (!networkRequest) {404      // We missed the requestWillBeSent.405      var eventData = {};406      eventData.url = response.url;407      eventData.frameId = frameId || '';408      eventData.loaderId = loaderId;409      eventData.resourceType = resourceType;410      eventData.mimeType = response.mimeType;411      var lastModifiedHeader = lowercaseHeaders['last-modified'];412      eventData.lastModified = lastModifiedHeader ? new Date(lastModifiedHeader) : null;413      this._manager.dispatchEventToListeners(SDK.NetworkManager.Events.RequestUpdateDropped, eventData);414      return;415    }416    networkRequest.responseReceivedTime = time;417    networkRequest.setResourceType(Common.resourceTypes[resourceType]);418    // net::ParsedCookie::kMaxCookieSize = 4096 (net/cookies/parsed_cookie.h)419    if ('set-cookie' in lowercaseHeaders && lowercaseHeaders['set-cookie'].length > 4096) {420      var message = Common.UIString(421          'Set-Cookie header is ignored in response from url: %s. Cookie length should be less than or equal to 4096 characters.',422          response.url);423      this._manager.dispatchEventToListeners(424          SDK.NetworkManager.Events.MessageGenerated, {message: message, requestId: requestId, warning: true});425    }426    this._updateNetworkRequestWithResponse(networkRequest, response);427    this._updateNetworkRequest(networkRequest);428    this._manager.dispatchEventToListeners(SDK.NetworkManager.Events.ResponseReceived, networkRequest);429  }430  /**431   * @override432   * @param {!Protocol.Network.RequestId} requestId433   * @param {!Protocol.Network.MonotonicTime} time434   * @param {number} dataLength435   * @param {number} encodedDataLength436   */437  dataReceived(requestId, time, dataLength, encodedDataLength) {438    var networkRequest = this._inflightRequestsById[requestId];439    if (!networkRequest)440      return;441    networkRequest.resourceSize += dataLength;442    if (encodedDataLength !== -1)443      networkRequest.increaseTransferSize(encodedDataLength);444    networkRequest.endTime = time;445    this._updateNetworkRequest(networkRequest);446  }447  /**448   * @override449   * @param {!Protocol.Network.RequestId} requestId450   * @param {!Protocol.Network.MonotonicTime} finishTime451   * @param {number} encodedDataLength452   * @param {boolean=} blockedCrossSiteDocument453   */454  loadingFinished(requestId, finishTime, encodedDataLength, blockedCrossSiteDocument) {455    var networkRequest = this._inflightRequestsById[requestId];456    if (!networkRequest)457      return;458    this._finishNetworkRequest(networkRequest, finishTime, encodedDataLength, blockedCrossSiteDocument);459  }460  /**461   * @override462   * @param {!Protocol.Network.RequestId} requestId463   * @param {!Protocol.Network.MonotonicTime} time464   * @param {!Protocol.Page.ResourceType} resourceType465   * @param {string} localizedDescription466   * @param {boolean=} canceled467   * @param {!Protocol.Network.BlockedReason=} blockedReason468   */469  loadingFailed(requestId, time, resourceType, localizedDescription, canceled, blockedReason) {470    var networkRequest = this._inflightRequestsById[requestId];471    if (!networkRequest)472      return;473    networkRequest.failed = true;474    networkRequest.setResourceType(Common.resourceTypes[resourceType]);475    networkRequest.canceled = !!canceled;476    if (blockedReason) {477      networkRequest.setBlockedReason(blockedReason);478      if (blockedReason === Protocol.Network.BlockedReason.Inspector) {479        var message = Common.UIString('Request was blocked by DevTools: "%s".', networkRequest.url());480        this._manager.dispatchEventToListeners(481            SDK.NetworkManager.Events.MessageGenerated, {message: message, requestId: requestId, warning: true});482      }483    }484    networkRequest.localizedFailDescription = localizedDescription;485    this._finishNetworkRequest(networkRequest, time, -1);486  }487  /**488   * @override489   * @param {!Protocol.Network.RequestId} requestId490   * @param {string} requestURL491   * @param {!Protocol.Network.Initiator=} initiator492   */493  webSocketCreated(requestId, requestURL, initiator) {494    var networkRequest = new SDK.NetworkRequest(requestId, requestURL, '', '', '', initiator || null);495    networkRequest[SDK.NetworkManager._networkManagerForRequestSymbol] = this._manager;496    networkRequest.setResourceType(Common.resourceTypes.WebSocket);497    this._startNetworkRequest(networkRequest);498  }499  /**500   * @override501   * @param {!Protocol.Network.RequestId} requestId502   * @param {!Protocol.Network.MonotonicTime} time503   * @param {!Protocol.Network.TimeSinceEpoch} wallTime504   * @param {!Protocol.Network.WebSocketRequest} request505   */506  webSocketWillSendHandshakeRequest(requestId, time, wallTime, request) {507    var networkRequest = this._inflightRequestsById[requestId];508    if (!networkRequest)509      return;510    networkRequest.requestMethod = 'GET';511    networkRequest.setRequestHeaders(this._headersMapToHeadersArray(request.headers));512    networkRequest.setIssueTime(time, wallTime);513    this._updateNetworkRequest(networkRequest);514  }515  /**516   * @override517   * @param {!Protocol.Network.RequestId} requestId518   * @param {!Protocol.Network.MonotonicTime} time519   * @param {!Protocol.Network.WebSocketResponse} response520   */521  webSocketHandshakeResponseReceived(requestId, time, response) {522    var networkRequest = this._inflightRequestsById[requestId];523    if (!networkRequest)524      return;525    networkRequest.statusCode = response.status;526    networkRequest.statusText = response.statusText;527    networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);528    networkRequest.responseHeadersText = response.headersText || '';529    if (response.requestHeaders)530      networkRequest.setRequestHeaders(this._headersMapToHeadersArray(response.requestHeaders));531    if (response.requestHeadersText)532      networkRequest.setRequestHeadersText(response.requestHeadersText);533    networkRequest.responseReceivedTime = time;534    networkRequest.protocol = 'websocket';535    this._updateNetworkRequest(networkRequest);536  }537  /**538   * @override539   * @param {!Protocol.Network.RequestId} requestId540   * @param {!Protocol.Network.MonotonicTime} time541   * @param {!Protocol.Network.WebSocketFrame} response542   */543  webSocketFrameReceived(requestId, time, response) {544    var networkRequest = this._inflightRequestsById[requestId];545    if (!networkRequest)546      return;547    networkRequest.addFrame(response, time, false);548    networkRequest.responseReceivedTime = time;549    this._updateNetworkRequest(networkRequest);550  }551  /**552   * @override553   * @param {!Protocol.Network.RequestId} requestId554   * @param {!Protocol.Network.MonotonicTime} time555   * @param {!Protocol.Network.WebSocketFrame} response556   */557  webSocketFrameSent(requestId, time, response) {558    var networkRequest = this._inflightRequestsById[requestId];559    if (!networkRequest)560      return;561    networkRequest.addFrame(response, time, true);562    networkRequest.responseReceivedTime = time;563    this._updateNetworkRequest(networkRequest);564  }565  /**566   * @override567   * @param {!Protocol.Network.RequestId} requestId568   * @param {!Protocol.Network.MonotonicTime} time569   * @param {string} errorMessage570   */571  webSocketFrameError(requestId, time, errorMessage) {572    var networkRequest = this._inflightRequestsById[requestId];573    if (!networkRequest)574      return;575    networkRequest.addFrameError(errorMessage, time);576    networkRequest.responseReceivedTime = time;577    this._updateNetworkRequest(networkRequest);578  }579  /**580   * @override581   * @param {!Protocol.Network.RequestId} requestId582   * @param {!Protocol.Network.MonotonicTime} time583   */584  webSocketClosed(requestId, time) {585    var networkRequest = this._inflightRequestsById[requestId];586    if (!networkRequest)587      return;588    this._finishNetworkRequest(networkRequest, time, -1);589  }590  /**591   * @override592   * @param {!Protocol.Network.RequestId} requestId593   * @param {!Protocol.Network.MonotonicTime} time594   * @param {string} eventName595   * @param {string} eventId596   * @param {string} data597   */598  eventSourceMessageReceived(requestId, time, eventName, eventId, data) {599    var networkRequest = this._inflightRequestsById[requestId];600    if (!networkRequest)601      return;602    networkRequest.addEventSourceMessage(time, eventName, eventId, data);603  }604  /**605   * @override606   * @param {!Protocol.Network.InterceptionId} interceptionId607   * @param {!Protocol.Network.Request} request608   * @param {!Protocol.Page.FrameId} frameId609   * @param {!Protocol.Page.ResourceType} resourceType610   * @param {boolean} isNavigationRequest611   * @param {string=} redirectUrl612   * @param {!Protocol.Network.AuthChallenge=} authChallenge613   * @param {!Protocol.Network.ErrorReason=} responseErrorReason614   * @param {number=} responseStatusCode615   * @param {!Protocol.Network.Headers=} responseHeaders616   */617  requestIntercepted(618      interceptionId, request, frameId, resourceType, isNavigationRequest, redirectUrl, authChallenge,619      responseErrorReason, responseStatusCode, responseHeaders) {620    SDK.multitargetNetworkManager._requestIntercepted(new SDK.MultitargetNetworkManager.InterceptedRequest(621        this._manager.target().networkAgent(), interceptionId, request, frameId, resourceType, isNavigationRequest,622        redirectUrl, authChallenge, responseErrorReason, responseStatusCode, responseHeaders));623  }624  /**625   * @param {!Protocol.Network.RequestId} requestId626   * @param {!Protocol.Network.MonotonicTime} time627   * @param {string} redirectURL628   * @return {!SDK.NetworkRequest}629   */630  _appendRedirect(requestId, time, redirectURL) {631    var originalNetworkRequest = this._inflightRequestsById[requestId];632    var redirectCount = 0;633    for (var redirect = originalNetworkRequest.redirectSource(); redirect; redirect = redirect.redirectSource())634      redirectCount++;635    originalNetworkRequest.setRequestId(requestId + ':redirected.' + redirectCount);636    this._finishNetworkRequest(originalNetworkRequest, time, -1);637    var newNetworkRequest = this._createNetworkRequest(638        requestId, originalNetworkRequest.frameId, originalNetworkRequest.loaderId, redirectURL,639        originalNetworkRequest.documentURL, originalNetworkRequest.initiator());640    newNetworkRequest.setRedirectSource(originalNetworkRequest);641    return newNetworkRequest;642  }643  /**644   * @param {!SDK.NetworkRequest} networkRequest645   */646  _startNetworkRequest(networkRequest) {647    this._inflightRequestsById[networkRequest.requestId()] = networkRequest;648    this._inflightRequestsByURL[networkRequest.url()] = networkRequest;649    this._manager.dispatchEventToListeners(SDK.NetworkManager.Events.RequestStarted, networkRequest);650  }651  /**652   * @param {!SDK.NetworkRequest} networkRequest653   */654  _updateNetworkRequest(networkRequest) {655    this._manager.dispatchEventToListeners(SDK.NetworkManager.Events.RequestUpdated, networkRequest);656  }657  /**658   * @param {!SDK.NetworkRequest} networkRequest659   * @param {!Protocol.Network.MonotonicTime} finishTime660   * @param {number} encodedDataLength661   * @param {boolean=} blockedCrossSiteDocument662   */663  _finishNetworkRequest(networkRequest, finishTime, encodedDataLength, blockedCrossSiteDocument) {664    networkRequest.endTime = finishTime;665    networkRequest.finished = true;666    if (encodedDataLength >= 0)667      networkRequest.setTransferSize(encodedDataLength);668    this._manager.dispatchEventToListeners(SDK.NetworkManager.Events.RequestFinished, networkRequest);669    delete this._inflightRequestsById[networkRequest.requestId()];670    delete this._inflightRequestsByURL[networkRequest.url()];671    if (blockedCrossSiteDocument) {672      var message = Common.UIString(673          `Blocked current origin from receiving cross-site document at %s with MIME type %s.`, networkRequest.url(),674          networkRequest.mimeType);675      this._manager.dispatchEventToListeners(676          SDK.NetworkManager.Events.MessageGenerated,677          {message: message, requestId: networkRequest.requestId(), warning: true});678    }679    if (Common.moduleSetting('monitoringXHREnabled').get() &&680        networkRequest.resourceType().category() === Common.resourceCategories.XHR) {681      var message = Common.UIString(682          (networkRequest.failed || networkRequest.hasErrorStatusCode()) ? '%s failed loading: %s "%s".' :683                                                                           '%s finished loading: %s "%s".',684          networkRequest.resourceType().title(), networkRequest.requestMethod, networkRequest.url());685      this._manager.dispatchEventToListeners(686          SDK.NetworkManager.Events.MessageGenerated,687          {message: message, requestId: networkRequest.requestId(), warning: false});688    }689  }690  /**691   * @param {!Protocol.Network.RequestId} requestId692   * @param {string} frameId693   * @param {!Protocol.Network.LoaderId} loaderId694   * @param {string} url695   * @param {string} documentURL696   * @param {?Protocol.Network.Initiator} initiator697   */698  _createNetworkRequest(requestId, frameId, loaderId, url, documentURL, initiator) {699    var request = new SDK.NetworkRequest(requestId, url, documentURL, frameId, loaderId, initiator);700    request[SDK.NetworkManager._networkManagerForRequestSymbol] = this._manager;701    return request;702  }703};704/**705 * @implements {SDK.TargetManager.Observer}706 * @unrestricted707 */708SDK.MultitargetNetworkManager = class extends Common.Object {709  constructor() {710    super();711    this._userAgentOverride = '';712    /** @type {!Set<!Protocol.NetworkAgent>} */713    this._agents = new Set();714    /** @type {!SDK.NetworkManager.Conditions} */715    this._networkConditions = SDK.NetworkManager.NoThrottlingConditions;716    /** @type {?Promise} */717    this._updatingInterceptionPatternsPromise = null;718    // TODO(allada) Remove these and merge it with request interception.719    this._blockingEnabledSetting = Common.moduleSetting('requestBlockingEnabled');720    this._blockedPatternsSetting = Common.settings.createSetting('networkBlockedPatterns', []);721    this._effectiveBlockedURLs = [];722    this._updateBlockedPatterns();723    /** @type {!Multimap<!SDK.MultitargetNetworkManager.RequestInterceptor, !SDK.MultitargetNetworkManager.InterceptionPattern>} */724    this._urlsForRequestInterceptor = new Multimap();725    SDK.targetManager.observeTargets(this, SDK.Target.Capability.Network);726  }727  /**728   * @param {string} uaString729   * @return {string}730   */731  static patchUserAgentWithChromeVersion(uaString) {732    // Patches Chrome/CriOS version from user agent ("1.2.3.4" when user agent is: "Chrome/1.2.3.4").733    var chromeRegex = new RegExp('(?:^|\\W)Chrome/(\\S+)');734    var chromeMatch = navigator.userAgent.match(chromeRegex);735    if (chromeMatch && chromeMatch.length > 1)736      return String.sprintf(uaString, chromeMatch[1]);737    return uaString;738  }739  /**740   * @override741   * @param {!SDK.Target} target742   */743  targetAdded(target) {744    var networkAgent = target.networkAgent();745    if (this._extraHeaders)746      networkAgent.setExtraHTTPHeaders(this._extraHeaders);747    if (this._currentUserAgent())748      networkAgent.setUserAgentOverride(this._currentUserAgent());749    if (this._effectiveBlockedURLs.length)750      networkAgent.setBlockedURLs(this._effectiveBlockedURLs);751    if (this.isIntercepting())752      networkAgent.setRequestInterception(this._urlsForRequestInterceptor.valuesArray());753    this._agents.add(networkAgent);754    if (this.isThrottling())755      this._updateNetworkConditions(networkAgent);756  }757  /**758   * @override759   * @param {!SDK.Target} target760   */761  targetRemoved(target) {762    this._agents.delete(target.networkAgent());763  }764  /**765   * @return {boolean}766   */767  isThrottling() {768    return this._networkConditions.download >= 0 || this._networkConditions.upload >= 0 ||769        this._networkConditions.latency > 0;770  }771  /**772   * @return {boolean}773   */774  isOffline() {775    return !this._networkConditions.download && !this._networkConditions.upload;776  }777  /**778   * @param {!SDK.NetworkManager.Conditions} conditions779   */780  setNetworkConditions(conditions) {781    this._networkConditions = conditions;782    for (var agent of this._agents)783      this._updateNetworkConditions(agent);784    this.dispatchEventToListeners(SDK.MultitargetNetworkManager.Events.ConditionsChanged);785  }786  /**787   * @return {!SDK.NetworkManager.Conditions}788   */789  networkConditions() {790    return this._networkConditions;791  }792  /**793   * @param {!Protocol.NetworkAgent} networkAgent794   */795  _updateNetworkConditions(networkAgent) {796    var conditions = this._networkConditions;797    if (!this.isThrottling()) {798      networkAgent.emulateNetworkConditions(false, 0, 0, 0);799    } else {800      networkAgent.emulateNetworkConditions(801          this.isOffline(), conditions.latency, conditions.download < 0 ? 0 : conditions.download,802          conditions.upload < 0 ? 0 : conditions.upload, SDK.NetworkManager._connectionType(conditions));803    }804  }805  /**806   * @param {!Protocol.Network.Headers} headers807   */808  setExtraHTTPHeaders(headers) {809    this._extraHeaders = headers;810    for (var agent of this._agents)811      agent.setExtraHTTPHeaders(this._extraHeaders);812  }813  /**814   * @return {string}815   */816  _currentUserAgent() {817    return this._customUserAgent ? this._customUserAgent : this._userAgentOverride;818  }819  _updateUserAgentOverride() {820    var userAgent = this._currentUserAgent();821    for (var agent of this._agents)822      agent.setUserAgentOverride(userAgent);823  }824  /**825   * @param {string} userAgent826   */827  setUserAgentOverride(userAgent) {828    if (this._userAgentOverride === userAgent)829      return;830    this._userAgentOverride = userAgent;831    if (!this._customUserAgent)832      this._updateUserAgentOverride();833    this.dispatchEventToListeners(SDK.MultitargetNetworkManager.Events.UserAgentChanged);834  }835  /**836   * @return {string}837   */838  userAgentOverride() {839    return this._userAgentOverride;840  }841  /**842   * @param {string} userAgent843   */844  setCustomUserAgentOverride(userAgent) {845    this._customUserAgent = userAgent;846    this._updateUserAgentOverride();847  }848  // TODO(allada) Move all request blocking into interception and let view manage blocking.849  /**850   * @return {!Array<!SDK.NetworkManager.BlockedPattern>}851   */852  blockedPatterns() {853    return this._blockedPatternsSetting.get().slice();854  }855  /**856   * @return {boolean}857   */858  blockingEnabled() {859    return this._blockingEnabledSetting.get();860  }861  /**862   * @return {boolean}863   */864  isBlocking() {865    return !!this._effectiveBlockedURLs.length;866  }867  /**868   * @param {!Array<!SDK.NetworkManager.BlockedPattern>} patterns869   */870  setBlockedPatterns(patterns) {871    this._blockedPatternsSetting.set(patterns);872    this._updateBlockedPatterns();873    this.dispatchEventToListeners(SDK.MultitargetNetworkManager.Events.BlockedPatternsChanged);874  }875  /**876   * @param {boolean} enabled877   */878  setBlockingEnabled(enabled) {879    if (this._blockingEnabledSetting.get() === enabled)880      return;881    this._blockingEnabledSetting.set(enabled);882    this._updateBlockedPatterns();883    this.dispatchEventToListeners(SDK.MultitargetNetworkManager.Events.BlockedPatternsChanged);884  }885  _updateBlockedPatterns() {886    var urls = [];887    if (this._blockingEnabledSetting.get()) {888      for (var pattern of this._blockedPatternsSetting.get()) {889        if (pattern.enabled)890          urls.push(pattern.url);891      }892    }893    if (!urls.length && !this._effectiveBlockedURLs.length)894      return;895    this._effectiveBlockedURLs = urls;896    for (var agent of this._agents)897      agent.setBlockedURLs(this._effectiveBlockedURLs);898  }899  /**900   * @return {boolean}901   */902  isIntercepting() {903    return !!this._urlsForRequestInterceptor.size;904  }905  /**906   * @param {!Array<!SDK.MultitargetNetworkManager.InterceptionPattern>} patterns907   * @param {!SDK.MultitargetNetworkManager.RequestInterceptor} requestInterceptor908   * @return {!Promise}909   */910  setInterceptionHandlerForPatterns(patterns, requestInterceptor) {911    // Note: requestInterceptors may recieve interception requests for patterns they did not subscribe to.912    this._urlsForRequestInterceptor.deleteAll(requestInterceptor);913    for (var newPattern of patterns)914      this._urlsForRequestInterceptor.set(requestInterceptor, newPattern);915    return this._updateInterceptionPatternsOnNextTick();916  }917  /**918   * @return {!Promise}919   */920  _updateInterceptionPatternsOnNextTick() {921    // This is used so we can register and unregister patterns in loops without sending lots of protocol messages.922    if (!this._updatingInterceptionPatternsPromise)923      this._updatingInterceptionPatternsPromise = Promise.resolve().then(this._updateInterceptionPatterns.bind(this));924    return this._updatingInterceptionPatternsPromise;925  }926  /**927   * @return {!Promise}928   */929  _updateInterceptionPatterns() {930    if (!Common.moduleSetting('cacheDisabled').get())931      Common.moduleSetting('cacheDisabled').set(true);932    this._updatingInterceptionPatternsPromise = null;933    var promises = /** @type {!Array<!Promise>} */ ([]);934    for (var agent of this._agents)935      promises.push(agent.setRequestInterception(this._urlsForRequestInterceptor.valuesArray()));936    this.dispatchEventToListeners(SDK.MultitargetNetworkManager.Events.InterceptorsChanged);937    return Promise.all(promises);938  }939  /**940   * @param {!SDK.MultitargetNetworkManager.InterceptedRequest} interceptedRequest941   */942  async _requestIntercepted(interceptedRequest) {943    for (var requestInterceptor of this._urlsForRequestInterceptor.keysArray()) {944      await requestInterceptor(interceptedRequest);945      if (interceptedRequest.hasResponded())946        return;947    }948    if (!interceptedRequest.hasResponded())949      interceptedRequest.continueRequestWithoutChange();950  }951  clearBrowserCache() {952    for (var agent of this._agents)953      agent.clearBrowserCache();954  }955  clearBrowserCookies() {956    for (var agent of this._agents)957      agent.clearBrowserCookies();958  }959  /**960   * @param {string} origin961   * @return {!Promise<!Array<string>>}962   */963  getCertificate(origin) {964    var target = SDK.targetManager.mainTarget();965    return target.networkAgent().getCertificate(origin).then(certificate => certificate || []);966  }967  /**968   * @param {string} url969   * @param {function(number, !Object.<string, string>, string)} callback970   */971  loadResource(url, callback) {972    var headers = {};973    var currentUserAgent = this._currentUserAgent();974    if (currentUserAgent)975      headers['User-Agent'] = currentUserAgent;976    if (Common.moduleSetting('cacheDisabled').get())977      headers['Cache-Control'] = 'no-cache';978    Host.ResourceLoader.load(url, headers, callback);979  }980};981/** @enum {symbol} */982SDK.MultitargetNetworkManager.Events = {983  BlockedPatternsChanged: Symbol('BlockedPatternsChanged'),984  ConditionsChanged: Symbol('ConditionsChanged'),985  UserAgentChanged: Symbol('UserAgentChanged'),986  InterceptorsChanged: Symbol('InterceptorsChanged')987};988SDK.MultitargetNetworkManager.InterceptedRequest = class {989  /**990   * @param {!Protocol.NetworkAgent} networkAgent991   * @param {!Protocol.Network.InterceptionId} interceptionId992   * @param {!Protocol.Network.Request} request993   * @param {!Protocol.Page.FrameId} frameId994   * @param {!Protocol.Page.ResourceType} resourceType995   * @param {boolean} isNavigationRequest996   * @param {string=} redirectUrl997   * @param {!Protocol.Network.AuthChallenge=} authChallenge998   * @param {!Protocol.Network.ErrorReason=} responseErrorReason999   * @param {number=} responseStatusCode1000   * @param {!Protocol.Network.Headers=} responseHeaders1001   */1002  constructor(1003      networkAgent, interceptionId, request, frameId, resourceType, isNavigationRequest, redirectUrl, authChallenge,1004      responseErrorReason, responseStatusCode, responseHeaders) {1005    this._networkAgent = networkAgent;1006    this._interceptionId = interceptionId;1007    this._hasResponded = false;1008    this.request = request;1009    this.frameId = frameId;1010    this.resourceType = resourceType;1011    this.isNavigationRequest = isNavigationRequest;1012    this.redirectUrl = redirectUrl;1013    this.authChallenge = authChallenge;1014    this.responseErrorReason = responseErrorReason;1015    this.responseStatusCode = responseStatusCode;1016    this.responseHeaders = responseHeaders;1017  }1018  /**1019   * @return {boolean}1020   */1021  hasResponded() {1022    return this._hasResponded;1023  }1024  /**1025   * @param {!Blob} contentBlob1026   */1027  async continueRequestWithContent(contentBlob) {1028    this._hasResponded = true;1029    var headers = [1030      'HTTP/1.1 200 OK',1031      'Date: ' + (new Date()).toUTCString(),1032      'Server: Chrome Devtools Request Interceptor',1033      'Connection: closed',1034      'Content-Length: ' + contentBlob.size,1035      'Content-Type: ' + contentBlob.type || 'text/x-unknown',1036    ];1037    var encodedResponse = await blobToBase64(new Blob([headers.join('\r\n'), '\r\n\r\n', contentBlob]));1038    this._networkAgent.continueInterceptedRequest(this._interceptionId, undefined, encodedResponse);1039    /**1040     * @param {!Blob} blob1041     * @return {!Promise<string>}1042     */1043    async function blobToBase64(blob) {1044      var reader = new FileReader();1045      var fileContentsLoadedPromise = new Promise(resolve => reader.onloadend = resolve);1046      reader.readAsDataURL(blob);1047      await fileContentsLoadedPromise;1048      if (reader.error) {1049        console.error('Could not convert blob to base64.', reader.error);1050        return '';1051      }1052      var result = reader.result;1053      if (result === undefined) {1054        console.error('Could not convert blob to base64.');1055        return '';1056      }1057      return result.substring(result.indexOf(',') + 1);1058    }1059  }1060  continueRequestWithoutChange() {1061    console.assert(!this._hasResponded);1062    this._hasResponded = true;1063    this._networkAgent.continueInterceptedRequest(this._interceptionId);1064  }1065  /**1066   * @param {!Protocol.Network.ErrorReason} errorReason1067   */1068  continueRequestWithError(errorReason) {1069    console.assert(!this._hasResponded);1070    this._hasResponded = true;1071    this._networkAgent.continueInterceptedRequest(this._interceptionId, errorReason);1072  }1073  /**1074   * @return {!Promise<!SDK.NetworkRequest.ContentData>}1075   */1076  async responseBody() {1077    var response =1078        await this._networkAgent.invoke_getResponseBodyForInterception({interceptionId: this._interceptionId});1079    var error = response[Protocol.Error] || null;1080    return {error: error, content: error ? null : response.body, encoded: response.base64Encoded};1081  }1082};1083/** @typedef {!{urlPattern: string, interceptionStage: !Protocol.Network.InterceptionStage}} */1084SDK.MultitargetNetworkManager.InterceptionPattern;1085/** @typedef {!function(!SDK.MultitargetNetworkManager.InterceptedRequest):!Promise} */1086SDK.MultitargetNetworkManager.RequestInterceptor;1087/**1088 * @type {!SDK.MultitargetNetworkManager}1089 */...NetworkRequest.js
Source:NetworkRequest.js  
1/*2 * Copyright (C) 2012 Google Inc. All rights reserved.3 *4 * Redistribution and use in source and binary forms, with or without5 * modification, are permitted provided that the following conditions are6 * met:7 *8 *     * Redistributions of source code must retain the above copyright9 * notice, this list of conditions and the following disclaimer.10 *     * Redistributions in binary form must reproduce the above11 * copyright notice, this list of conditions and the following disclaimer12 * in the documentation and/or other materials provided with the13 * distribution.14 *     * Neither the name of Google Inc. nor the names of its15 * contributors may be used to endorse or promote products derived from16 * this software without specific prior written permission.17 *18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.29 */30/**31 * @constructor32 * @extends {WebInspector.SDKObject}33 * @implements {WebInspector.ContentProvider}34 * @param {!NetworkAgent.RequestId} requestId35 * @param {!WebInspector.Target} target36 * @param {string} url37 * @param {string} documentURL38 * @param {!PageAgent.FrameId} frameId39 * @param {!NetworkAgent.LoaderId} loaderId40 * @param {?NetworkAgent.Initiator} initiator41 */42WebInspector.NetworkRequest = function(target, requestId, url, documentURL, frameId, loaderId, initiator)43{44    WebInspector.SDKObject.call(this, target);45    this._requestId = requestId;46    this.url = url;47    this._documentURL = documentURL;48    this._frameId = frameId;49    this._loaderId = loaderId;50    /** @type {?NetworkAgent.Initiator} */51    this._initiator = initiator;52    this._issueTime = -1;53    this._startTime = -1;54    this._endTime = -1;55    this.statusCode = 0;56    this.statusText = "";57    this.requestMethod = "";58    this.requestTime = 0;59    this.protocol = "";60    /** @type {!WebInspector.ResourceType} */61    this._resourceType = WebInspector.resourceTypes.Other;62    this._contentEncoded = false;63    this._pendingContentCallbacks = [];64    /** @type {!Array.<!WebInspector.NetworkRequest.WebSocketFrame>} */65    this._frames = [];66    /** @type {!Array.<!WebInspector.NetworkRequest.EventSourceMessage>} */67    this._eventSourceMessages = [];68    this._responseHeaderValues = {};69    this._remoteAddress = "";70    /** @type {string} */71    this.connectionId = "0";72}73WebInspector.NetworkRequest.Events = {74    FinishedLoading: "FinishedLoading",75    TimingChanged: "TimingChanged",76    RemoteAddressChanged: "RemoteAddressChanged",77    RequestHeadersChanged: "RequestHeadersChanged",78    ResponseHeadersChanged: "ResponseHeadersChanged",79    WebsocketFrameAdded: "WebsocketFrameAdded",80    EventSourceMessageAdded: "EventSourceMessageAdded",81}82/** @enum {string} */83WebInspector.NetworkRequest.InitiatorType = {84    Other: "other",85    Parser: "parser",86    Redirect: "redirect",87    Script: "script"88}89/** @typedef {!{name: string, value: string}} */90WebInspector.NetworkRequest.NameValue;91/** @enum {string} */92WebInspector.NetworkRequest.WebSocketFrameType = {93    Send: "send",94    Receive: "receive",95    Error: "error"96}97/** @typedef {!{type: WebInspector.NetworkRequest.WebSocketFrameType, time: number, text: string, opCode: number, mask: boolean}} */98WebInspector.NetworkRequest.WebSocketFrame;99/** @typedef {!{time: number, eventName: string, eventId: string, data: string}} */100WebInspector.NetworkRequest.EventSourceMessage;101WebInspector.NetworkRequest.prototype = {102    /**103     * @param {!WebInspector.NetworkRequest} other104     * @return {number}105     */106    indentityCompare: function(other) {107        if (this._requestId > other._requestId)108            return 1;109        if (this._requestId < other._requestId)110            return -1;111        return 0;112    },113    /**114     * @return {!NetworkAgent.RequestId}115     */116    get requestId()117    {118        return this._requestId;119    },120    set requestId(requestId)121    {122        this._requestId = requestId;123    },124    /**125     * @return {string}126     */127    get url()128    {129        return this._url;130    },131    set url(x)132    {133        if (this._url === x)134            return;135        this._url = x;136        this._parsedURL = new WebInspector.ParsedURL(x);137        delete this._queryString;138        delete this._parsedQueryParameters;139        delete this._name;140        delete this._path;141    },142    /**143     * @return {string}144     */145    get documentURL()146    {147        return this._documentURL;148    },149    get parsedURL()150    {151        return this._parsedURL;152    },153    /**154     * @return {!PageAgent.FrameId}155     */156    get frameId()157    {158        return this._frameId;159    },160    /**161     * @return {!NetworkAgent.LoaderId}162     */163    get loaderId()164    {165        return this._loaderId;166    },167    /**168     * @param {string} ip169     * @param {number} port170     */171    setRemoteAddress: function(ip, port)172    {173        if (ip.indexOf(":") !== -1)174            ip = "[" + ip + "]";175        this._remoteAddress = ip + ":" + port;176        this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RemoteAddressChanged, this);177    },178    /**179     * @return {string}180     */181    remoteAddress: function()182    {183        return this._remoteAddress;184    },185    /**186     * @return {number}187     */188    get startTime()189    {190        return this._startTime || -1;191    },192    /**193     * @param {number} monotonicTime194     * @param {number} wallTime195     */196    setIssueTime: function(monotonicTime, wallTime)197    {198        this._issueTime = monotonicTime;199        this._wallIssueTime = wallTime;200        this._startTime = monotonicTime;201    },202    /**203     * @return {number}204     */205    issueTime: function()206    {207        return this._issueTime;208    },209    /**210     * @param {number} monotonicTime211     * @return {number}212     */213    pseudoWallTime: function(monotonicTime)214    {215        return this._wallIssueTime ? this._wallIssueTime - this._issueTime + monotonicTime : monotonicTime;216    },217    /**218     * @return {number}219     */220    get responseReceivedTime()221    {222        return this._responseReceivedTime || -1;223    },224    set responseReceivedTime(x)225    {226        this._responseReceivedTime = x;227    },228    /**229     * @return {number}230     */231    get endTime()232    {233        return this._endTime || -1;234    },235    set endTime(x)236    {237        if (this.timing && this.timing.requestTime) {238            // Check against accurate responseReceivedTime.239            this._endTime = Math.max(x, this.responseReceivedTime);240        } else {241            // Prefer endTime since it might be from the network stack.242            this._endTime = x;243            if (this._responseReceivedTime > x)244                this._responseReceivedTime = x;245        }246        this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.TimingChanged, this);247    },248    /**249     * @return {number}250     */251    get duration()252    {253        if (this._endTime === -1 || this._startTime === -1)254            return -1;255        return this._endTime - this._startTime;256    },257    /**258     * @return {number}259     */260    get latency()261    {262        if (this._responseReceivedTime === -1 || this._startTime === -1)263            return -1;264        return this._responseReceivedTime - this._startTime;265    },266    /**267     * @return {number}268     */269    get resourceSize()270    {271        return this._resourceSize || 0;272    },273    set resourceSize(x)274    {275        this._resourceSize = x;276    },277    /**278     * @return {number}279     */280    get transferSize()281    {282        return this._transferSize || 0;283    },284    /**285     * @param {number} x286     */287    increaseTransferSize: function(x)288    {289        this._transferSize = (this._transferSize || 0) + x;290    },291    /**292     * @param {number} x293     */294    setTransferSize: function(x)295    {296        this._transferSize = x;297    },298    /**299     * @return {boolean}300     */301    get finished()302    {303        return this._finished;304    },305    set finished(x)306    {307        if (this._finished === x)308            return;309        this._finished = x;310        if (x) {311            this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.FinishedLoading, this);312            if (this._pendingContentCallbacks.length)313                this._innerRequestContent();314        }315    },316    /**317     * @return {boolean}318     */319    get failed()320    {321        return this._failed;322    },323    set failed(x)324    {325        this._failed = x;326    },327    /**328     * @return {boolean}329     */330    get canceled()331    {332        return this._canceled;333    },334    set canceled(x)335    {336        this._canceled = x;337    },338    /**339     * @return {boolean}340     */341    cached: function()342    {343        return (!!this._fromMemoryCache || !!this._fromDiskCache) && !this._transferSize;344    },345    setFromMemoryCache: function()346    {347        this._fromMemoryCache = true;348        delete this._timing;349    },350    setFromDiskCache: function()351    {352        this._fromDiskCache = true;353    },354    /**355     * @return {boolean}356     */357    get fetchedViaServiceWorker()358    {359        return this._fetchedViaServiceWorker;360    },361    set fetchedViaServiceWorker(x)362    {363        this._fetchedViaServiceWorker = x;364    },365    /**366     * @return {!NetworkAgent.ResourceTiming|undefined}367     */368    get timing()369    {370        return this._timing;371    },372    set timing(x)373    {374        if (x && !this._fromMemoryCache) {375            // Take startTime and responseReceivedTime from timing data for better accuracy.376            // Timing's requestTime is a baseline in seconds, rest of the numbers there are ticks in millis.377            this._startTime = x.requestTime;378            this._responseReceivedTime = x.requestTime + x.receiveHeadersEnd / 1000.0;379            this._timing = x;380            this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.TimingChanged, this);381        }382    },383    /**384     * @return {string}385     */386    get mimeType()387    {388        return this._mimeType;389    },390    set mimeType(x)391    {392        this._mimeType = x;393    },394    /**395     * @return {string}396     */397    get displayName()398    {399        return this._parsedURL.displayName;400    },401    /**402     * @return {string}403     */404    name: function()405    {406        if (this._name)407            return this._name;408        this._parseNameAndPathFromURL();409        return this._name;410    },411    /**412     * @return {string}413     */414    path: function()415    {416        if (this._path)417            return this._path;418        this._parseNameAndPathFromURL();419        return this._path;420    },421    _parseNameAndPathFromURL: function()422    {423        if (this._parsedURL.isDataURL()) {424            this._name = this._parsedURL.dataURLDisplayName();425            this._path = "";426        } else if (this._parsedURL.isAboutBlank()) {427            this._name = this._parsedURL.url;428            this._path = "";429        } else {430            this._path = this._parsedURL.host + this._parsedURL.folderPathComponents;431            this._path = this._path.trimURL(this.target().resourceTreeModel.inspectedPageDomain());432            if (this._parsedURL.lastPathComponent || this._parsedURL.queryParams)433                this._name = this._parsedURL.lastPathComponent + (this._parsedURL.queryParams ? "?" + this._parsedURL.queryParams : "");434            else if (this._parsedURL.folderPathComponents) {435                this._name = this._parsedURL.folderPathComponents.substring(this._parsedURL.folderPathComponents.lastIndexOf("/") + 1) + "/";436                this._path = this._path.substring(0, this._path.lastIndexOf("/"));437            } else {438                this._name = this._parsedURL.host;439                this._path = "";440            }441        }442    },443    /**444     * @return {string}445     */446    get folder()447    {448        var path = this._parsedURL.path;449        var indexOfQuery = path.indexOf("?");450        if (indexOfQuery !== -1)451            path = path.substring(0, indexOfQuery);452        var lastSlashIndex = path.lastIndexOf("/");453        return lastSlashIndex !== -1 ? path.substring(0, lastSlashIndex) : "";454    },455    /**456     * @return {!WebInspector.ResourceType}457     */458    resourceType: function()459    {460        return this._resourceType;461    },462    /**463     * @param {!WebInspector.ResourceType} resourceType464     */465    setResourceType: function(resourceType)466    {467        this._resourceType = resourceType;468    },469    /**470     * @return {string}471     */472    get domain()473    {474        return this._parsedURL.host;475    },476    /**477     * @return {string}478     */479    get scheme()480    {481        return this._parsedURL.scheme;482    },483    /**484     * @return {?WebInspector.NetworkRequest}485     */486    get redirectSource()487    {488        if (this.redirects && this.redirects.length > 0)489            return this.redirects[this.redirects.length - 1];490        return this._redirectSource;491    },492    set redirectSource(x)493    {494        this._redirectSource = x;495        delete this._initiatorInfo;496    },497    /**498     * @return {!Array.<!WebInspector.NetworkRequest.NameValue>}499     */500    requestHeaders: function()501    {502        return this._requestHeaders || [];503    },504    /**505     * @param {!Array.<!WebInspector.NetworkRequest.NameValue>} headers506     */507    setRequestHeaders: function(headers)508    {509        this._requestHeaders = headers;510        delete this._requestCookies;511        this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged);512    },513    /**514     * @return {string|undefined}515     */516    requestHeadersText: function()517    {518        return this._requestHeadersText;519    },520    /**521     * @param {string} text522     */523    setRequestHeadersText: function(text)524    {525        this._requestHeadersText = text;526        this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged);527    },528    /**529     * @param {string} headerName530     * @return {string|undefined}531     */532    requestHeaderValue: function(headerName)533    {534        return this._headerValue(this.requestHeaders(), headerName);535    },536    /**537     * @return {!Array.<!WebInspector.Cookie>}538     */539    get requestCookies()540    {541        if (!this._requestCookies)542            this._requestCookies = WebInspector.CookieParser.parseCookie(this.target(), this.requestHeaderValue("Cookie"));543        return this._requestCookies;544    },545    /**546     * @return {string|undefined}547     */548    get requestFormData()549    {550        return this._requestFormData;551    },552    set requestFormData(x)553    {554        this._requestFormData = x;555        delete this._parsedFormParameters;556    },557    /**558     * @return {string}559     */560    requestHttpVersion: function()561    {562        var headersText = this.requestHeadersText();563        if (!headersText)564            return this.requestHeaderValue("version") || this.requestHeaderValue(":version") || "unknown";565        var firstLine = headersText.split(/\r\n/)[0];566        var match = firstLine.match(/(HTTP\/\d+\.\d+)$/);567        return match ? match[1] : "HTTP/0.9";568    },569    /**570     * @return {!Array.<!WebInspector.NetworkRequest.NameValue>}571     */572    get responseHeaders()573    {574        return this._responseHeaders || [];575    },576    set responseHeaders(x)577    {578        this._responseHeaders = x;579        delete this._sortedResponseHeaders;580        delete this._responseCookies;581        this._responseHeaderValues = {};582        this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged);583    },584    /**585     * @return {string}586     */587    get responseHeadersText()588    {589        return this._responseHeadersText;590    },591    set responseHeadersText(x)592    {593        this._responseHeadersText = x;594        this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged);595    },596    /**597     * @return {!Array.<!WebInspector.NetworkRequest.NameValue>}598     */599    get sortedResponseHeaders()600    {601        if (this._sortedResponseHeaders !== undefined)602            return this._sortedResponseHeaders;603        this._sortedResponseHeaders = this.responseHeaders.slice();604        this._sortedResponseHeaders.sort(function(a, b) { return a.name.toLowerCase().compareTo(b.name.toLowerCase()); });605        return this._sortedResponseHeaders;606    },607    /**608     * @param {string} headerName609     * @return {string|undefined}610     */611    responseHeaderValue: function(headerName)612    {613        var value = this._responseHeaderValues[headerName];614        if (value === undefined) {615            value = this._headerValue(this.responseHeaders, headerName);616            this._responseHeaderValues[headerName] = (value !== undefined) ? value : null;617        }618        return (value !== null) ? value : undefined;619    },620    /**621     * @return {!Array.<!WebInspector.Cookie>}622     */623    get responseCookies()624    {625        if (!this._responseCookies)626            this._responseCookies = WebInspector.CookieParser.parseSetCookie(this.target(), this.responseHeaderValue("Set-Cookie"));627        return this._responseCookies;628    },629    /**630     * @return {?string}631     */632    queryString: function()633    {634        if (this._queryString !== undefined)635            return this._queryString;636        var queryString = null;637        var url = this.url;638        var questionMarkPosition = url.indexOf("?");639        if (questionMarkPosition !== -1) {640            queryString = url.substring(questionMarkPosition + 1);641            var hashSignPosition = queryString.indexOf("#");642            if (hashSignPosition !== -1)643                queryString = queryString.substring(0, hashSignPosition);644        }645        this._queryString = queryString;646        return this._queryString;647    },648    /**649     * @return {?Array.<!WebInspector.NetworkRequest.NameValue>}650     */651    get queryParameters()652    {653        if (this._parsedQueryParameters)654            return this._parsedQueryParameters;655        var queryString = this.queryString();656        if (!queryString)657            return null;658        this._parsedQueryParameters = this._parseParameters(queryString);659        return this._parsedQueryParameters;660    },661    /**662     * @return {?Array.<!WebInspector.NetworkRequest.NameValue>}663     */664    get formParameters()665    {666        if (this._parsedFormParameters)667            return this._parsedFormParameters;668        if (!this.requestFormData)669            return null;670        var requestContentType = this.requestContentType();671        if (!requestContentType || !requestContentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i))672            return null;673        this._parsedFormParameters = this._parseParameters(this.requestFormData);674        return this._parsedFormParameters;675    },676    /**677     * @return {string}678     */679    responseHttpVersion: function()680    {681        var headersText = this._responseHeadersText;682        if (!headersText)683            return this.responseHeaderValue("version") || this.responseHeaderValue(":version") || "unknown";684        var firstLine = headersText.split(/\r\n/)[0];685        var match = firstLine.match(/^(HTTP\/\d+\.\d+)/);686        return match ? match[1] : "HTTP/0.9";687    },688    /**689     * @param {string} queryString690     * @return {!Array.<!WebInspector.NetworkRequest.NameValue>}691     */692    _parseParameters: function(queryString)693    {694        function parseNameValue(pair)695        {696            var position = pair.indexOf("=");697            if (position === -1)698                return {name: pair, value: ""};699            else700                return {name: pair.substring(0, position), value: pair.substring(position + 1)};701        }702        return queryString.split("&").map(parseNameValue);703    },704    /**705     * @param {!Array.<!WebInspector.NetworkRequest.NameValue>} headers706     * @param {string} headerName707     * @return {string|undefined}708     */709    _headerValue: function(headers, headerName)710    {711        headerName = headerName.toLowerCase();712        var values = [];713        for (var i = 0; i < headers.length; ++i) {714            if (headers[i].name.toLowerCase() === headerName)715                values.push(headers[i].value);716        }717        if (!values.length)718            return undefined;719        // Set-Cookie values should be separated by '\n', not comma, otherwise cookies could not be parsed.720        if (headerName === "set-cookie")721            return values.join("\n");722        return values.join(", ");723    },724    /**725     * @return {?string|undefined}726     */727    get content()728    {729        return this._content;730    },731    /**732     * @return {?Protocol.Error|undefined}733     */734    contentError: function()735    {736        return this._contentError;737    },738    /**739     * @return {boolean}740     */741    get contentEncoded()742    {743        return this._contentEncoded;744    },745    /**746     * @override747     * @return {string}748     */749    contentURL: function()750    {751        return this._url;752    },753    /**754     * @override755     * @return {!WebInspector.ResourceType}756     */757    contentType: function()758    {759        return this._resourceType;760    },761    /**762     * @override763     * @param {function(?string)} callback764     */765    requestContent: function(callback)766    {767        // We do not support content retrieval for WebSockets at the moment.768        // Since WebSockets are potentially long-living, fail requests immediately769        // to prevent caller blocking until resource is marked as finished.770        if (this._resourceType === WebInspector.resourceTypes.WebSocket) {771            callback(null);772            return;773        }774        if (typeof this._content !== "undefined") {775            callback(this.content || null);776            return;777        }778        this._pendingContentCallbacks.push(callback);779        if (this.finished)780            this._innerRequestContent();781    },782    /**783     * @override784     * @param {string} query785     * @param {boolean} caseSensitive786     * @param {boolean} isRegex787     * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback788     */789    searchInContent: function(query, caseSensitive, isRegex, callback)790    {791        callback([]);792    },793    /**794     * @return {boolean}795     */796    isHttpFamily: function()797    {798        return !!this.url.match(/^https?:/i);799    },800    /**801     * @return {string|undefined}802     */803    requestContentType: function()804    {805        return this.requestHeaderValue("Content-Type");806    },807    /**808     * @return {boolean}809     */810    hasErrorStatusCode: function()811    {812        return this.statusCode >= 400;813    },814    /**815     * @param {!Element} image816     */817    populateImageSource: function(image)818    {819        WebInspector.Resource.populateImageSource(this._url, this._mimeType, this, image);820    },821    /**822     * @return {?string}823     */824    asDataURL: function()825    {826        var content = this._content;827        var charset = null;828        if (!this._contentEncoded) {829            content = content.toBase64();830            charset = "utf-8";831        }832        return WebInspector.Resource.contentAsDataURL(content, this.mimeType, true, charset);833    },834    _innerRequestContent: function()835    {836        if (this._contentRequested)837            return;838        this._contentRequested = true;839        /**840         * @param {?Protocol.Error} error841         * @param {string} content842         * @param {boolean} contentEncoded843         * @this {WebInspector.NetworkRequest}844         */845        function onResourceContent(error, content, contentEncoded)846        {847            this._content = error ? null : content;848            this._contentError = error;849            this._contentEncoded = contentEncoded;850            var callbacks = this._pendingContentCallbacks.slice();851            for (var i = 0; i < callbacks.length; ++i)852                callbacks[i](this._content);853            this._pendingContentCallbacks.length = 0;854            delete this._contentRequested;855        }856        this.target().networkAgent().getResponseBody(this._requestId, onResourceContent.bind(this));857    },858    /**859     * @return {?NetworkAgent.Initiator}860     */861    initiator: function()862    {863        return this._initiator;864    },865    /**866     * @return {!{type: !WebInspector.NetworkRequest.InitiatorType, url: string, lineNumber: number, columnNumber: number}}867     */868    initiatorInfo: function()869    {870        if (this._initiatorInfo)871            return this._initiatorInfo;872        var type = WebInspector.NetworkRequest.InitiatorType.Other;873        var url = "";874        var lineNumber = -Infinity;875        var columnNumber = -Infinity;876        var initiator = this._initiator;877        if (this.redirectSource) {878            type = WebInspector.NetworkRequest.InitiatorType.Redirect;879            url = this.redirectSource.url;880        } else if (initiator) {881            if (initiator.type === NetworkAgent.InitiatorType.Parser) {882                type = WebInspector.NetworkRequest.InitiatorType.Parser;883                url = initiator.url ? initiator.url : url;884                lineNumber = initiator.lineNumber ? initiator.lineNumber : lineNumber;885            } else if (initiator.type === NetworkAgent.InitiatorType.Script) {886                var topFrame = initiator.stackTrace[0];887                if (topFrame.url) {888                    type = WebInspector.NetworkRequest.InitiatorType.Script;889                    url = topFrame.url;890                    lineNumber = topFrame.lineNumber;891                    columnNumber = topFrame.columnNumber;892                }893            }894        }895        this._initiatorInfo = {type: type, url: url, lineNumber: lineNumber, columnNumber: columnNumber};896        return this._initiatorInfo;897    },898    /**899     * @return {!Array.<!WebInspector.NetworkRequest.WebSocketFrame>}900     */901    frames: function()902    {903        return this._frames;904    },905    /**906     * @param {string} errorMessage907     * @param {number} time908     */909    addFrameError: function(errorMessage, time)910    {911        this._addFrame({ type: WebInspector.NetworkRequest.WebSocketFrameType.Error, text: errorMessage, time: this.pseudoWallTime(time), opCode: -1, mask: false });912    },913    /**914     * @param {!NetworkAgent.WebSocketFrame} response915     * @param {number} time916     * @param {boolean} sent917     */918    addFrame: function(response, time, sent)919    {920        var type = sent ? WebInspector.NetworkRequest.WebSocketFrameType.Send : WebInspector.NetworkRequest.WebSocketFrameType.Receive;921        this._addFrame({ type: type, text: response.payloadData, time: this.pseudoWallTime(time), opCode: response.opcode, mask: response.mask });922    },923    /**924     * @param {!WebInspector.NetworkRequest.WebSocketFrame} frame925     */926    _addFrame: function(frame)927    {928        this._frames.push(frame);929        this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.WebsocketFrameAdded, frame);930    },931    /**932     * @return {!Array.<!WebInspector.NetworkRequest.EventSourceMessage>}933     */934    eventSourceMessages: function()935    {936        return this._eventSourceMessages;937    },938    /**939     * @param {number} time940     * @param {string} eventName941     * @param {string} eventId942     * @param {string} data943     */944    addEventSourceMessage: function(time, eventName, eventId, data)945    {946        var message = {time: this.pseudoWallTime(time), eventName: eventName, eventId: eventId, data: data};947        this._eventSourceMessages.push(message);948        this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.EventSourceMessageAdded, message);949    },950    replayXHR: function()951    {952        this.target().networkAgent().replayXHR(this.requestId);953    },954    __proto__: WebInspector.SDKObject.prototype...HAREntry.js
Source:HAREntry.js  
1/*2 * Copyright (C) 2012 Google Inc. All rights reserved.3 *4 * Redistribution and use in source and binary forms, with or without5 * modification, are permitted provided that the following conditions are6 * met:7 *8 *     * Redistributions of source code must retain the above copyright9 * notice, this list of conditions and the following disclaimer.10 *     * Redistributions in binary form must reproduce the above11 * copyright notice, this list of conditions and the following disclaimer12 * in the documentation and/or other materials provided with the13 * distribution.14 *     * Neither the name of Google Inc. nor the names of its15 * contributors may be used to endorse or promote products derived from16 * this software without specific prior written permission.17 *18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.29 */30// See http://www.softwareishard.com/blog/har-12-spec/31// for HAR specification.32// FIXME: Some fields are not yet supported due to back-end limitations.33// See https://bugs.webkit.org/show_bug.cgi?id=58127 for details.34/**35 * @constructor36 * @param {!WebInspector.NetworkRequest} request37 */38WebInspector.HAREntry = function(request)39{40    this._request = request;41}42WebInspector.HAREntry.prototype = {43    /**44     * @return {!Object}45     */46    build: function()47    {48        var entry = {49            startedDateTime: WebInspector.HARLog.pseudoWallTime(this._request, this._request.startTime),50            time: this._request.timing ? WebInspector.HAREntry._toMilliseconds(this._request.duration) : 0,51            request: this._buildRequest(),52            response: this._buildResponse(),53            cache: { }, // Not supported yet.54            timings: this._buildTimings()55        };56        if (this._request.connectionId !== "0")57            entry.connection = this._request.connectionId;58        var page = this._request.target().networkLog.pageLoadForRequest(this._request);59        if (page)60            entry.pageref = "page_" + page.id;61        return entry;62    },63    /**64     * @return {!Object}65     */66    _buildRequest: function()67    {68        var headersText = this._request.requestHeadersText();69        var res = {70            method: this._request.requestMethod,71            url: this._buildRequestURL(this._request.url),72            httpVersion: this._request.requestHttpVersion(),73            headers: this._request.requestHeaders(),74            queryString: this._buildParameters(this._request.queryParameters || []),75            cookies: this._buildCookies(this._request.requestCookies || []),76            headersSize: headersText ? headersText.length : -1,77            bodySize: this.requestBodySize78        };79        if (this._request.requestFormData)80            res.postData = this._buildPostData();81        return res;82    },83    /**84     * @return {!Object}85     */86    _buildResponse: function()87    {88        var headersText = this._request.responseHeadersText;89        return {90            status: this._request.statusCode,91            statusText: this._request.statusText,92            httpVersion: this._request.responseHttpVersion(),93            headers: this._request.responseHeaders,94            cookies: this._buildCookies(this._request.responseCookies || []),95            content: this._buildContent(),96            redirectURL: this._request.responseHeaderValue("Location") || "",97            headersSize: headersText ? headersText.length : -1,98            bodySize: this.responseBodySize,99            _transferSize: this._request.transferSize,100            _error: this._request.localizedFailDescription101        };102    },103    /**104     * @return {!Object}105     */106    _buildContent: function()107    {108        var content = {109            size: this._request.resourceSize,110            mimeType: this._request.mimeType || "x-unknown",111            // text: this._request.content // TODO: pull out into a boolean flag, as content can be huge (and needs to be requested with an async call)112        };113        var compression = this.responseCompression;114        if (typeof compression === "number")115            content.compression = compression;116        return content;117    },118    /**119     * @return {!Object}120     */121    _buildTimings: function()122    {123        // Order of events: request_start = 0, [proxy], [dns], [connect [ssl]], [send], receive_headers_end124        // HAR 'blocked' time is time before first network activity.125        var timing = this._request.timing;126        if (!timing)127            return {blocked: -1, dns: -1, connect: -1, send: 0, wait: 0, receive: 0, ssl: -1};128        function firstNonNegative(values)129        {130            for (var i = 0; i < values.length; ++i) {131                if (values[i] >= 0)132                    return values[i];133            }134            console.assert(false, "Incomplete request timing information.");135        }136        var blocked = firstNonNegative([timing.dnsStart, timing.connectStart, timing.sendStart]);137        var dns = -1;138        if (timing.dnsStart >= 0)139            dns = firstNonNegative([timing.connectStart, timing.sendStart]) - timing.dnsStart;140        var connect = -1;141        if (timing.connectStart >= 0)142            connect = timing.sendStart - timing.connectStart;143        var send = timing.sendEnd - timing.sendStart;144        var wait = timing.receiveHeadersEnd - timing.sendEnd;145        var receive = WebInspector.HAREntry._toMilliseconds(this._request.duration) - timing.receiveHeadersEnd;146        var ssl = -1;147        if (timing.sslStart >= 0 && timing.sslEnd >= 0)148            ssl = timing.sslEnd - timing.sslStart;149        return {blocked: blocked, dns: dns, connect: connect, send: send, wait: wait, receive: receive, ssl: ssl};150    },151    /**152     * @return {!Object}153     */154    _buildPostData: function()155    {156        var res = {157            mimeType: this._request.requestContentType(),158            text: this._request.requestFormData159        };160        if (this._request.formParameters)161            res.params = this._buildParameters(this._request.formParameters);162        return res;163    },164    /**165     * @param {!Array.<!Object>} parameters166     * @return {!Array.<!Object>}167     */168    _buildParameters: function(parameters)169    {170        return parameters.slice();171    },172    /**173     * @param {string} url174     * @return {string}175     */176    _buildRequestURL: function(url)177    {178        return url.split("#", 2)[0];179    },180    /**181     * @param {!Array.<!WebInspector.Cookie>} cookies182     * @return {!Array.<!Object>}183     */184    _buildCookies: function(cookies)185    {186        return cookies.map(this._buildCookie.bind(this));187    },188    /**189     * @param {!WebInspector.Cookie} cookie190     * @return {!Object}191     */192    _buildCookie: function(cookie)193    {194        return {195            name: cookie.name(),196            value: cookie.value(),197            path: cookie.path(),198            domain: cookie.domain(),199            expires: cookie.expiresDate(WebInspector.HARLog.pseudoWallTime(this._request, this._request.startTime)),200            httpOnly: cookie.httpOnly(),201            secure: cookie.secure()202        };203    },204    /**205     * @return {number}206     */207    get requestBodySize()208    {209        return !this._request.requestFormData ? 0 : this._request.requestFormData.length;210    },211    /**212     * @return {number}213     */214    get responseBodySize()215    {216        if (this._request.cached() || this._request.statusCode === 304)217            return 0;218        if (!this._request.responseHeadersText)219            return -1;220        return this._request.transferSize - this._request.responseHeadersText.length;221    },222    /**223     * @return {number|undefined}224     */225    get responseCompression()226    {227        if (this._request.cached() || this._request.statusCode === 304 || this._request.statusCode === 206)228            return;229        if (!this._request.responseHeadersText)230            return;231        return this._request.resourceSize - this.responseBodySize;232    }233}234/**235 * @param {number} time236 * @return {number}237 */238WebInspector.HAREntry._toMilliseconds = function(time)239{240    return time === -1 ? -1 : time * 1000;241}242/**243 * @constructor244 * @param {!Array.<!WebInspector.NetworkRequest>} requests245 */246WebInspector.HARLog = function(requests)247{248    this._requests = requests;249}250/**251 * @param {!WebInspector.NetworkRequest} request252 * @param {number} monotonicTime253 * @return {!Date}254 */255WebInspector.HARLog.pseudoWallTime = function(request, monotonicTime)256{257    return new Date(request.pseudoWallTime(monotonicTime) * 1000);258}259WebInspector.HARLog.prototype = {260    /**261     * @return {!Object}262     */263    build: function()264    {265        return {266            version: "1.2",267            creator: this._creator(),268            pages: this._buildPages(),269            entries: this._requests.map(this._convertResource.bind(this))270        }271    },272    _creator: function()273    {274        var webKitVersion = /AppleWebKit\/([^ ]+)/.exec(window.navigator.userAgent);275        return {276            name: "WebInspector",277            version: webKitVersion ? webKitVersion[1] : "n/a"278        };279    },280    /**281     * @return {!Array.<!Object>}282     */283    _buildPages: function()284    {285        var seenIdentifiers = {};286        var pages = [];287        for (var i = 0; i < this._requests.length; ++i) {288            var request = this._requests[i];289            var page = request.target().networkLog.pageLoadForRequest(request);290            if (!page || seenIdentifiers[page.id])291                continue;292            seenIdentifiers[page.id] = true;293            pages.push(this._convertPage(page, request));294        }295        return pages;296    },297    /**298     * @param {!WebInspector.PageLoad} page299     * @param {!WebInspector.NetworkRequest} request300     * @return {!Object}301     */302    _convertPage: function(page, request)303    {304        return {305            startedDateTime: WebInspector.HARLog.pseudoWallTime(request, page.startTime),306            id: "page_" + page.id,307            title: page.url, // We don't have actual page title here. URL is probably better than nothing.308            pageTimings: {309                onContentLoad: this._pageEventTime(page, page.contentLoadTime),310                onLoad: this._pageEventTime(page, page.loadTime)311            }312        }313    },314    /**315     * @param {!WebInspector.NetworkRequest} request316     * @return {!Object}317     */318    _convertResource: function(request)319    {320        return (new WebInspector.HAREntry(request)).build();321    },322    /**323     * @param {!WebInspector.PageLoad} page324     * @param {number} time325     * @return {number}326     */327    _pageEventTime: function(page, time)328    {329        var startTime = page.startTime;330        if (time === -1 || startTime === -1)331            return -1;332        return WebInspector.HAREntry._toMilliseconds(time - startTime);333    }...async.js
Source:async.js  
1"use strict";2Object.defineProperty(exports, "__esModule", {3  value: true4});5exports.TimeoutRunnerError = exports.TimeoutRunner = exports.ManualPromise = void 0;6exports.raceAgainstTimeout = raceAgainstTimeout;7var _utils = require("./utils");8let _Symbol$species, _Symbol$toStringTag;9class TimeoutRunnerError extends Error {}10exports.TimeoutRunnerError = TimeoutRunnerError;11class TimeoutRunner {12  constructor(timeout) {13    this._running = void 0;14    this._timeout = void 0;15    this._elapsed = void 0;16    this._timeout = timeout;17    this._elapsed = 0;18  }19  async run(cb) {20    const running = this._running = {21      start: (0, _utils.monotonicTime)(),22      timer: undefined,23      timeoutPromise: new ManualPromise()24    };25    try {26      const resultPromise = Promise.race([cb(), running.timeoutPromise]);27      this._updateTimeout(running, this._timeout);28      return await resultPromise;29    } finally {30      this._elapsed += (0, _utils.monotonicTime)() - running.start;31      this._updateTimeout(running, 0);32      if (this._running === running) this._running = undefined;33    }34  }35  interrupt() {36    if (this._running) this._updateTimeout(this._running, -1);37  }38  updateTimeout(timeout) {39    this._timeout = timeout;40    if (this._running) this._updateTimeout(this._running, timeout);41  }42  resetTimeout(timeout) {43    this._elapsed = 0;44    this.updateTimeout(timeout);45  }46  _updateTimeout(running, timeout) {47    if (running.timer) {48      clearTimeout(running.timer);49      running.timer = undefined;50    }51    if (timeout === 0) return;52    const elapsed = (0, _utils.monotonicTime)() - running.start + this._elapsed;53    timeout = timeout - elapsed;54    if (timeout <= 0) running.timeoutPromise.reject(new TimeoutRunnerError());else running.timer = setTimeout(() => running.timeoutPromise.reject(new TimeoutRunnerError()), timeout);55  }56}57exports.TimeoutRunner = TimeoutRunner;58async function raceAgainstTimeout(cb, timeout) {59  const runner = new TimeoutRunner(timeout);60  try {61    return {62      result: await runner.run(cb),63      timedOut: false64    };65  } catch (e) {66    if (e instanceof TimeoutRunnerError) return {67      timedOut: true68    };69    throw e;70  }71}72_Symbol$species = Symbol.species;73_Symbol$toStringTag = Symbol.toStringTag;74class ManualPromise extends Promise {75  constructor() {76    let resolve;77    let reject;78    super((f, r) => {79      resolve = f;80      reject = r;81    });82    this._resolve = void 0;83    this._reject = void 0;84    this._isDone = void 0;85    this._isDone = false;86    this._resolve = resolve;87    this._reject = reject;88  }89  isDone() {90    return this._isDone;91  }92  resolve(t) {93    this._isDone = true;94    this._resolve(t);95  }96  reject(e) {97    this._isDone = true;98    this._reject(e);99  }100  static get [_Symbol$species]() {101    return Promise;102  }103  get [_Symbol$toStringTag]() {104    return 'ManualPromise';105  }106}...live.controller.js
Source:live.controller.js  
1'use strict';2var anemonode = require('../../../../build/Release/anemonode');3var timeest = require('../../../timeest.js');4var pendingCalls = {}5var pendingCallPackets = [];6var lastFetch;7// Get list of values, only from the best source per channel8exports.index = function(req, res) {9  var response = {};10  var monotonicTime = anemonode.currentTime();11  for (var i in anemonode.dispatcher.values) {12    if (anemonode.dispatcher.values[i].length() > 013        && Math.abs(anemonode.dispatcher.values[i].time().getTime() - monotonicTime.getTime()) < 2000) {14      response[i] = {15        v: anemonode.dispatcher.values[i].value(),16        s: anemonode.dispatcher.values[i].source()17      };18    }19  }20  if (pendingCallPackets.length > 0) {21    response.rpcCalls = pendingCallPackets;22    pendingCallPackets = [];23  }24  lastFetch = monotonicTime;25  res.json(response);26};27exports.allSources = function(req, res) {28  var response = {};29  var sources = anemonode.dispatcher.allSources();30  for (var channel in sources) {31    var sourcesForChannel = { }32    for (var source in sources[channel]) {33      sourcesForChannel[source] = {34        v: sources[channel][source].value(),35        t: timeest.monotonicToEstimatedTime(sources[channel][source].time()),36        p: anemonode.dispatcher.sourcePriority(source)37      };38    }39    response[channel] = sourcesForChannel;40  }41  res.json(response);42}43function handleError(res, err) {44  return res.status(500).send(err);45}46exports.callRpc = function(func, args, callback) {47  var packet = {48    callId: Math.round(Math.random() * 65535),49    func: func,50    args: args51  };52  pendingCalls[packet.callId] = callback || function() {};53  pendingCallPackets.push(packet);54}55exports.rpcReply = function(req, res) {56  var callId = req.params.callId;57  if (callId == undefined) {58    return res.status(403).send("no callId");59  }60  if (!(callId in pendingCalls)) {61    return res.status(404).send("No such callId");62  }63  64  var answer = ('answer' in req.body ? req.body.answer : undefined);65  pendingCalls[callId](answer);66  res.status(200).send();67}68exports.isConnected = function() {69  if (!lastFetch) {70    return false;71  }72  return (anemonode.currentTime().getTime() - lastFetch.getTime()) < 5000;...irc-antispam.js
Source:irc-antispam.js  
...29    /**30     * Monotonic time in nanoseconds31     * @return {bigint}32     */33    static monotonicTime() {34        const nano = hrtime.bigint();35        return nano / 1_000_000n;36    }37    /**38     * Check if key was called before this.period has passed.39     * @param {string} channel40     * @return {boolean} false if the user did not call too soon.41     */42    check(channel) {43        if (this.period === 0) return true;44        if (!this.map.get(channel) ||45            Antispam.monotonicTime() -46                this.map.get(channel) >= this.period47        ) {48            this.map.set(channel, Antispam.monotonicTime());49            return false;50        }51        return true;52    }53}...Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3  const browser = await chromium.launch();4  const context = await browser.newContext();5  const page = await context.newPage();6  const time = await page.evaluate(() => window.playwright.monotonicTime());7  console.log(time);8  await browser.close();9})();Using AI Code Generation
1const { monotonicTime } = require('playwright/lib/utils/utils');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch();5  const page = await browser.newPage();6  await page.waitForTimeout(2000);7  console.log('Time in milliseconds since Playwright was launched : ' + monotonicTime());8  await browser.close();9})();10This has been a guide to the monotonicTime() method of Playwright Internal API. Here we discuss the method and its implementation. You may also look at the following articles to learn more –11Playwright BrowserType.launchPersistentContext() MethodUsing AI Code Generation
1const { monotonicTime } = require('playwright/lib/utils/utils');2console.log(monotonicTime());3const { monotonicTime } = require('playwright/lib/utils/utils');4console.log(monotonicTime());5const { monotonicTime } = require('playwright/lib/utils/utils');6console.log(monotonicTime());7const { monotonicTime } = require('playwright/lib/utils/utils');8console.log(monotonicTime());9const { monotonicTime } = require('playwright/lib/utils/utils');10console.log(monotonicTime());11const { monotonicTime } = require('playwright/lib/utils/utils');12console.log(monotonicTime());13const { monotonicTime } = require('playwright/lib/utils/utils');14console.log(monotonicTime());15const { monotonicTime } = require('playwright/lib/utils/utils');16console.log(monotonicTime());17const { monotonicTime } = require('playwright/lib/utils/utils');18console.log(monotonicTime());19const { monotonicTime } = require('playwright/lib/utils/utils');20console.log(monotonicTime());21const { monotonicTime } = require('playwright/lib/utils/utils');22console.log(monotonicTime());23const { monotonicTime } = require('playwright/lib/utils/utils');24console.log(monotonicTime());Using AI Code Generation
1const { monotonicTime } = require('@playwright/test/lib/utils/utils');2console.log(monotonicTime());3const { test } = require('@playwright/test');4test('test', async ({ page }) => {5  const { monotonicTime } = require('@playwright/test/lib/utils/utils');6  console.log(monotonicTime());7});8const { test } = require('@playwright/test');9const { monotonicTime } = require('@playwright/test/lib/utils/utils');10test('test', async ({ page }) => {11  console.log(monotonicTime());12});13const { test } = require('@playwright/test');14const { monotonicTime } = require('@playwright/test/lib/utils/utils');15test('test', async ({ page }) => {16  const start = monotonicTime();17  await page.click('text=Get Started');18  const end = monotonicTime();19  console.log(`Time taken to click the Get Started button: ${end - start} ms`);20});21const { test } = require('@playwright/test');22const { monotonicTime } = require('@playwright/test/lib/utils/utils');23test('test', async ({ page }) => {24  for (let i = 0; i < 10;Using AI Code Generation
1const { monotonicTime } = require('playwright/lib/utils/monotonicTime');2console.log(monotonicTime());3{4  "dependencies": {5  },6  "devDependencies": {},7  "scripts": {8  },9}10const { monotonicTime } = require('playwright/lib/utils/monotonicTime');11console.log(monotonicTime() / 1000);12console.log(Date.now());13{14  "dependencies": {},15  "devDependencies": {16  },17  "scripts": {18  },19}20console.log(Date.now() / 1000);Using AI Code Generation
1const { monotonicTime } = require('playwright/lib/utils/utils');2console.log(monotonicTime());3const { monotonicTime } = require('playwright/lib/utils/utils');4console.log(monotonicTime());5const { monotonicTime } = require('playwright/lib/utils/utils');6console.log(monotonicTime());7const { monotonicTime } = require('playwright/lib/utils/utils');8console.log(monotonicTime());9const { monotonicTime } = require('playwright/lib/utils/utils');10console.log(monotonicTime());11const { monotonicTime } = require('playwright/lib/utils/utils');12console.log(monotonicTime());13const { monotonicTime } = require('playwright/lib/utils/utils');14console.log(monotonicTime());15const { monotonicTime } = require('playwright/lib/utils/utils');16console.log(monotonicTime());17const { monotonicTime } = require('playwright/lib/utils/utils');18console.log(monotonicTime());19const { monotonicTime } = require('playwright/lib/utils/utils');20console.log(monotonicTime());Using AI Code Generation
1const { monotonicTime } = require('playwright/lib/utils/utils');2console.log(monotonicTime());3const { monotonicTime } = require('playwright/lib/utils/utils');4console.log(monotonicTime());5const { monotonicTime } = require('playwright/lib/utils/utils');6console.log(monotonicTime());7const { monotonicTime } = require('playwright/lib/utils/utils');8console.log(monotonicTime());9const { monotonicTime } = require('playwright/lib/utils/utils');10console.log(monotonicTime());11const { monotonicTime } = require('playwright/lib/utils/utils');12console.log(monotonicTime());13const { monotonicTime } = require('playwright/lib/utils/utils');14console.log(monotonicTime());15const { monotonicTime } = require('playwright/lib/utils/utils');16console.log(monotonicTime());17const { monotonicTime } = require('playwright/lib/utils/utils');18console.log(monotonicTime());19const { monotonicTime } = require('playwright/lib/utils/utils');20console.log(monotonicLambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!
