tor-browser

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

har-utils.js (4727B)


      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 ChromeUtils.defineLazyGetter(this, "ZipWriter", function () {
      8  return Components.Constructor("@mozilla.org/zipwriter;1", "nsIZipWriter");
      9 });
     10 
     11 const OPEN_FLAGS = {
     12  RDONLY: parseInt("0x01", 16),
     13  WRONLY: parseInt("0x02", 16),
     14  CREATE_FILE: parseInt("0x08", 16),
     15  APPEND: parseInt("0x10", 16),
     16  TRUNCATE: parseInt("0x20", 16),
     17  EXCL: parseInt("0x80", 16),
     18 };
     19 
     20 function formatDate(date) {
     21  const year = String(date.getFullYear() % 100).padStart(2, "0");
     22  const month = String(date.getMonth() + 1).padStart(2, "0");
     23  const day = String(date.getDate()).padStart(2, "0");
     24  const hour = String(date.getHours()).padStart(2, "0");
     25  const minutes = String(date.getMinutes()).padStart(2, "0");
     26  const seconds = String(date.getSeconds()).padStart(2, "0");
     27 
     28  return `${year}-${month}-${day} ${hour}-${minutes}-${seconds}`;
     29 }
     30 
     31 /**
     32 * Helper API for HAR export features.
     33 */
     34 var HarUtils = {
     35  getHarFileName(defaultFileName, jsonp, compress, hostname, pathname = "") {
     36    const extension = jsonp ? ".harp" : ".har";
     37 
     38    const now = new Date();
     39    let name = defaultFileName.replace(/%date/g, formatDate(now));
     40    name = name.replace(/%hostname/g, hostname + pathname);
     41    name = name.replace(/\:/gm, "-", "");
     42    name = name.replace(/\//gm, "_", "");
     43 
     44    let fileName = name + extension;
     45 
     46    // Default file extension is zip if compressing is on.
     47    if (compress) {
     48      fileName += ".zip";
     49    }
     50 
     51    return fileName;
     52  },
     53 
     54  /**
     55   * Save HAR string into a given file. The file might be compressed
     56   * if specified in the options.
     57   *
     58   * @param {File} file Target file where the HAR string (JSON)
     59   * should be stored.
     60   * @param {string} jsonString HAR data (JSON or JSONP)
     61   * @param {boolean} compress The result file is zipped if set to true.
     62   */
     63  saveToFile(file, jsonString, compress) {
     64    const openFlags =
     65      OPEN_FLAGS.WRONLY | OPEN_FLAGS.CREATE_FILE | OPEN_FLAGS.TRUNCATE;
     66 
     67    try {
     68      const foStream = Cc[
     69        "@mozilla.org/network/file-output-stream;1"
     70      ].createInstance(Ci.nsIFileOutputStream);
     71 
     72      const permFlags = parseInt("0666", 8);
     73      foStream.init(file, openFlags, permFlags, 0);
     74 
     75      const convertor = Cc[
     76        "@mozilla.org/intl/converter-output-stream;1"
     77      ].createInstance(Ci.nsIConverterOutputStream);
     78      convertor.init(foStream, "UTF-8");
     79 
     80      // The entire jsonString can be huge so, write the data in chunks.
     81      const chunkLength = 1024 * 1024;
     82      for (let i = 0; i <= jsonString.length; i++) {
     83        const data = jsonString.substr(i, chunkLength + 1);
     84        if (data) {
     85          convertor.writeString(data);
     86        }
     87 
     88        i = i + chunkLength;
     89      }
     90 
     91      // this closes foStream
     92      convertor.close();
     93    } catch (err) {
     94      console.error(err);
     95      return false;
     96    }
     97 
     98    // If no compressing then bail out.
     99    if (!compress) {
    100      return true;
    101    }
    102 
    103    // Remember name of the original file, it'll be replaced by a zip file.
    104    const originalFilePath = file.path;
    105    const originalFileName = file.leafName;
    106 
    107    try {
    108      // Rename using unique name (the file is going to be removed).
    109      file.moveTo(null, "temp" + new Date().getTime() + "temphar");
    110 
    111      // Create compressed file with the original file path name.
    112      const zipFile = Cc["@mozilla.org/file/local;1"].createInstance(
    113        Ci.nsIFile
    114      );
    115      zipFile.initWithPath(originalFilePath);
    116 
    117      // The file within the zipped file doesn't use .zip extension.
    118      let fileName = originalFileName;
    119      if (fileName.indexOf(".zip") == fileName.length - 4) {
    120        fileName = fileName.substr(0, fileName.indexOf(".zip"));
    121      }
    122 
    123      const zip = new ZipWriter();
    124      zip.open(zipFile, openFlags);
    125      zip.addEntryFile(
    126        fileName,
    127        Ci.nsIZipWriter.COMPRESSION_DEFAULT,
    128        file,
    129        false
    130      );
    131      zip.close();
    132 
    133      // Remove the original file (now zipped).
    134      file.remove(true);
    135      return true;
    136    } catch (err) {
    137      console.error(err);
    138 
    139      // Something went wrong (disk space?) rename the original file back.
    140      file.moveTo(null, originalFileName);
    141    }
    142 
    143    return false;
    144  },
    145 
    146  getLocalDirectory(path) {
    147    let dir;
    148 
    149    if (!path) {
    150      dir = Services.dirsvc.get("ProfD", Ci.nsIFile);
    151      dir.append("har");
    152      dir.append("logs");
    153    } else {
    154      dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
    155      dir.initWithPath(path);
    156    }
    157 
    158    return dir;
    159  },
    160 };
    161 
    162 // Exports from this module
    163 exports.HarUtils = HarUtils;