diff options
Diffstat (limited to 'devtools/client/netmonitor/src/har/har-utils.js')
-rw-r--r-- | devtools/client/netmonitor/src/har/har-utils.js | 167 |
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; |