tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

har-importer.js (4949B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 const {
      8  TIMING_KEYS,
      9 } = require("resource://devtools/client/netmonitor/src/constants.js");
     10 const {
     11  getUrlDetails,
     12 } = require("resource://devtools/client/netmonitor/src/utils/request-utils.js");
     13 
     14 var guid = 0;
     15 
     16 /**
     17 * This object is responsible for importing HAR file. See HAR spec:
     18 * https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HAR/Overview.html
     19 * http://www.softwareishard.com/blog/har-12-spec/
     20 */
     21 class HarImporter {
     22  constructor(actions) {
     23    this.actions = actions;
     24  }
     25  /**
     26   * This is the main method used to import HAR data.
     27   */
     28  import(har) {
     29    const json = JSON.parse(har);
     30    this.doImport(json);
     31  }
     32 
     33  doImport(har) {
     34    this.actions.clearRequests({ isExplicitClear: true });
     35 
     36    // Helper map for pages.
     37    const pages = new Map();
     38    har.log.pages.forEach(page => {
     39      pages.set(page.id, page);
     40    });
     41 
     42    // Iterate all entries/requests and generate state.
     43    har.log.entries.forEach(entry => {
     44      const requestId = String(++guid);
     45      const startedMs = Date.parse(entry.startedDateTime);
     46 
     47      // Add request
     48      this.actions.addRequest(
     49        requestId,
     50        {
     51          startedMs,
     52          method: entry.request.method,
     53          url: entry.request.url,
     54          urlDetails: getUrlDetails(entry.request.url),
     55          isXHR: false,
     56          cause: {
     57            loadingDocumentUri: "",
     58            stackTraceAvailable: false,
     59            type: "",
     60          },
     61          fromCache: false,
     62          fromServiceWorker: false,
     63        },
     64        false
     65      );
     66 
     67      // Update request
     68      const data = {
     69        requestHeaders: {
     70          headers: entry.request.headers,
     71          headersSize: entry.request.headersSize,
     72          rawHeaders: "",
     73        },
     74        responseHeaders: {
     75          headers: entry.response.headers,
     76          headersSize: entry.response.headersSize,
     77          rawHeaders: "",
     78        },
     79        requestCookies: entry.request.cookies,
     80        responseCookies: entry.response.cookies,
     81        requestPostData: {
     82          postData: entry.request.postData || {},
     83          postDataDiscarded: false,
     84        },
     85        responseContent: {
     86          content: entry.response.content,
     87          contentDiscarded: false,
     88        },
     89        eventTimings: {
     90          timings: entry.timings,
     91        },
     92        totalTime: TIMING_KEYS.reduce((sum, type) => {
     93          const time = entry.timings[type];
     94          return typeof time != "undefined" && time != -1 ? sum + time : sum;
     95        }, 0),
     96 
     97        httpVersion: entry.request.httpVersion,
     98        contentSize: entry.response.content.size,
     99        mimeType: entry.response.content.mimeType,
    100        remoteAddress: entry.serverIPAddress,
    101        remotePort: entry.connection,
    102        status: entry.response.status,
    103        statusText: entry.response.statusText,
    104        transferredSize: entry.response.bodySize,
    105        securityState: entry._securityState,
    106 
    107        // Avoid auto-fetching data from the backend
    108        eventTimingsAvailable: false,
    109        requestCookiesAvailable: false,
    110        requestHeadersAvailable: false,
    111        responseContentAvailable: false,
    112        responseStartAvailable: false,
    113        responseCookiesAvailable: false,
    114        responseHeadersAvailable: false,
    115        securityInfoAvailable: false,
    116        requestPostDataAvailable: false,
    117      };
    118 
    119      if (entry.cache.afterRequest) {
    120        const { afterRequest } = entry.cache;
    121        data.responseCache = {
    122          cache: {
    123            expires: afterRequest.expires,
    124            fetchCount: afterRequest.fetchCount,
    125            lastFetched: afterRequest.lastFetched,
    126            // TODO: eTag support, see Bug 1799844.
    127            // eTag: afterRequest.eTag,
    128            _dataSize: afterRequest._dataSize,
    129            _lastModified: afterRequest._lastModified,
    130            _device: afterRequest._device,
    131          },
    132        };
    133      }
    134 
    135      this.actions.updateRequest(requestId, data, false);
    136 
    137      // Page timing markers
    138      const pageTimings = pages.get(entry.pageref)?.pageTimings;
    139      let onContentLoad = (pageTimings && pageTimings.onContentLoad) || 0;
    140      let onLoad = (pageTimings && pageTimings.onLoad) || 0;
    141 
    142      // Set 0 as the default value
    143      onContentLoad = onContentLoad != -1 ? onContentLoad : 0;
    144      onLoad = onLoad != -1 ? onLoad : 0;
    145 
    146      // Add timing markers
    147      if (onContentLoad > 0) {
    148        this.actions.addTimingMarker({
    149          name: "dom-interactive",
    150          time: startedMs + onContentLoad,
    151        });
    152      }
    153 
    154      if (onLoad > 0) {
    155        this.actions.addTimingMarker({
    156          name: "dom-complete",
    157          time: startedMs + onLoad,
    158        });
    159      }
    160    });
    161  }
    162 }
    163 
    164 // Exports from this module
    165 exports.HarImporter = HarImporter;