summaryrefslogtreecommitdiffstats
path: root/devtools/client/netmonitor/src/har/har-utils.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--devtools/client/netmonitor/src/har/har-utils.js167
1 files changed, 167 insertions, 0 deletions
diff --git a/devtools/client/netmonitor/src/har/har-utils.js b/devtools/client/netmonitor/src/har/har-utils.js
new file mode 100644
index 0000000000..fc7ae533f1
--- /dev/null
+++ b/devtools/client/netmonitor/src/har/har-utils.js
@@ -0,0 +1,167 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const { XPCOMUtils } = ChromeUtils.importESModule(
+ "resource://gre/modules/XPCOMUtils.sys.mjs"
+);
+
+XPCOMUtils.defineLazyGetter(this, "ZipWriter", function () {
+ return Components.Constructor("@mozilla.org/zipwriter;1", "nsIZipWriter");
+});
+
+const OPEN_FLAGS = {
+ RDONLY: parseInt("0x01", 16),
+ WRONLY: parseInt("0x02", 16),
+ CREATE_FILE: parseInt("0x08", 16),
+ APPEND: parseInt("0x10", 16),
+ TRUNCATE: parseInt("0x20", 16),
+ EXCL: parseInt("0x80", 16),
+};
+
+function formatDate(date) {
+ const year = String(date.getFullYear() % 100).padStart(2, "0");
+ const month = String(date.getMonth() + 1).padStart(2, "0");
+ const day = String(date.getDate()).padStart(2, "0");
+ const hour = String(date.getHours()).padStart(2, "0");
+ const minutes = String(date.getMinutes()).padStart(2, "0");
+ const seconds = String(date.getSeconds()).padStart(2, "0");
+
+ return `${year}-${month}-${day} ${hour}-${minutes}-${seconds}`;
+}
+
+/**
+ * Helper API for HAR export features.
+ */
+var HarUtils = {
+ getHarFileName(defaultFileName, jsonp, compress, hostname) {
+ const extension = jsonp ? ".harp" : ".har";
+
+ const now = new Date();
+ let name = defaultFileName.replace(/%date/g, formatDate(now));
+ name = name.replace(/%hostname/g, hostname);
+ name = name.replace(/\:/gm, "-", "");
+ name = name.replace(/\//gm, "_", "");
+
+ let fileName = name + extension;
+
+ // Default file extension is zip if compressing is on.
+ if (compress) {
+ fileName += ".zip";
+ }
+
+ return fileName;
+ },
+
+ /**
+ * Save HAR string into a given file. The file might be compressed
+ * if specified in the options.
+ *
+ * @param {File} file Target file where the HAR string (JSON)
+ * should be stored.
+ * @param {String} jsonString HAR data (JSON or JSONP)
+ * @param {Boolean} compress The result file is zipped if set to true.
+ */
+ saveToFile(file, jsonString, compress) {
+ const openFlags =
+ OPEN_FLAGS.WRONLY | OPEN_FLAGS.CREATE_FILE | OPEN_FLAGS.TRUNCATE;
+
+ try {
+ const foStream = Cc[
+ "@mozilla.org/network/file-output-stream;1"
+ ].createInstance(Ci.nsIFileOutputStream);
+
+ const permFlags = parseInt("0666", 8);
+ foStream.init(file, openFlags, permFlags, 0);
+
+ const convertor = Cc[
+ "@mozilla.org/intl/converter-output-stream;1"
+ ].createInstance(Ci.nsIConverterOutputStream);
+ convertor.init(foStream, "UTF-8");
+
+ // The entire jsonString can be huge so, write the data in chunks.
+ const chunkLength = 1024 * 1024;
+ for (let i = 0; i <= jsonString.length; i++) {
+ const data = jsonString.substr(i, chunkLength + 1);
+ if (data) {
+ convertor.writeString(data);
+ }
+
+ i = i + chunkLength;
+ }
+
+ // this closes foStream
+ convertor.close();
+ } catch (err) {
+ console.error(err);
+ return false;
+ }
+
+ // If no compressing then bail out.
+ if (!compress) {
+ return true;
+ }
+
+ // Remember name of the original file, it'll be replaced by a zip file.
+ const originalFilePath = file.path;
+ const originalFileName = file.leafName;
+
+ try {
+ // Rename using unique name (the file is going to be removed).
+ file.moveTo(null, "temp" + new Date().getTime() + "temphar");
+
+ // Create compressed file with the original file path name.
+ const zipFile = Cc["@mozilla.org/file/local;1"].createInstance(
+ Ci.nsIFile
+ );
+ zipFile.initWithPath(originalFilePath);
+
+ // The file within the zipped file doesn't use .zip extension.
+ let fileName = originalFileName;
+ if (fileName.indexOf(".zip") == fileName.length - 4) {
+ fileName = fileName.substr(0, fileName.indexOf(".zip"));
+ }
+
+ const zip = new ZipWriter();
+ zip.open(zipFile, openFlags);
+ zip.addEntryFile(
+ fileName,
+ Ci.nsIZipWriter.COMPRESSION_DEFAULT,
+ file,
+ false
+ );
+ zip.close();
+
+ // Remove the original file (now zipped).
+ file.remove(true);
+ return true;
+ } catch (err) {
+ console.error(err);
+
+ // Something went wrong (disk space?) rename the original file back.
+ file.moveTo(null, originalFileName);
+ }
+
+ return false;
+ },
+
+ getLocalDirectory(path) {
+ let dir;
+
+ if (!path) {
+ dir = Services.dirsvc.get("ProfD", Ci.nsIFile);
+ dir.append("har");
+ dir.append("logs");
+ } else {
+ dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
+ dir.initWithPath(path);
+ }
+
+ return dir;
+ },
+};
+
+// Exports from this module
+exports.HarUtils = HarUtils;