azurite
Version:
An open source Azure Storage API compatible server
151 lines • 5.96 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.getMD5FromStream = exports.getMD5FromString = exports.getURLQueries = exports.truncatedISO8061Date = exports.computeHMACSHA256 = exports.newEtag = exports.convertRawHeadersToMetadata = exports.convertDateTimeStringMsTo7Digital = exports.minDate = exports.rimrafAsync = exports.lfsa = void 0;
const tslib_1 = require("tslib");
const crypto_1 = require("crypto");
const rimraf = require("rimraf");
const url_1 = require("url");
const util_1 = require("util");
const StorageErrorFactory_1 = tslib_1.__importDefault(require("../../blob/errors/StorageErrorFactory"));
const constants_1 = require("./constants");
// LokiFsStructuredAdapter
// tslint:disable-next-line:no-var-requires
exports.lfsa = require("lokijs/src/loki-fs-structured-adapter.js");
exports.rimrafAsync = (0, util_1.promisify)(rimraf);
function minDate(date1, date2) {
return date1 > date2 ? date2 : date1;
}
exports.minDate = minDate;
// Blob Snapshot is has 7 digital for Milliseconds, but Datetime has Milliseconds with 3 digital. So need convert.
function convertDateTimeStringMsTo7Digital(dateTimeString) {
return dateTimeString.replace("Z", "0000Z");
}
exports.convertDateTimeStringMsTo7Digital = convertDateTimeStringMsTo7Digital;
function convertRawHeadersToMetadata(rawHeaders = [], contextId = "") {
const metadataPrefix = "x-ms-meta-";
const res = {};
let isEmpty = true;
for (let i = 0; i < rawHeaders.length; i = i + 2) {
const header = rawHeaders[i];
if (header.toLowerCase().startsWith(metadataPrefix) &&
header.length > metadataPrefix.length) {
const key = header.substr(metadataPrefix.length);
if (!key.match(constants_1.VALID_CSHARP_IDENTIFIER_REGEX)) {
throw StorageErrorFactory_1.default.getInvalidMetadata(contextId);
}
let value = rawHeaders[i + 1] || "";
if (res[key] !== undefined) {
value = `${res[key]},${value}`;
}
res[key] = value;
isEmpty = false;
continue;
}
}
return isEmpty ? undefined : res;
}
exports.convertRawHeadersToMetadata = convertRawHeadersToMetadata;
function newEtag() {
// Etag should match ^"0x[A-F0-9]{15,}"$
// Date().getTime().toString(16) only has 11 digital
// so multiply a number between 70000-100000, can get a 16 based 15+ digital number
return ('"0x' +
(new Date().getTime() * Math.round(Math.random() * 30000 + 70000))
.toString(16)
.toUpperCase() +
'"');
}
exports.newEtag = newEtag;
/**
* Generates a hash signature for an HTTP request or for a SAS.
*
* @param {string} stringToSign
* @param {key} key
* @returns {string}
*/
function computeHMACSHA256(stringToSign, key) {
return (0, crypto_1.createHmac)("sha256", key)
.update(stringToSign, "utf8")
.digest("base64");
}
exports.computeHMACSHA256 = computeHMACSHA256;
/**
* Rounds a date off to seconds.
*
* @export
* @param {Date} date
* @param {boolean} [withMilliseconds=true] If true, YYYY-MM-DDThh:mm:ss.fffffffZ will be returned;
* If false, YYYY-MM-DDThh:mm:ssZ will be returned.
* @returns {string} Date string in ISO8061 format, with or without 7 milliseconds component
*/
function truncatedISO8061Date(date, withMilliseconds = true, hrtimePrecision = false) {
// Date.toISOString() will return like "2018-10-29T06:34:36.139Z"
const dateString = date.toISOString();
// some clients are very fast, and require more than ms precision available in JS
// This is an approximation based on the hrtime function in nodejs.
// The nanosecond value is appended to the millisecond value from the datetime
// object which gives us a good enough difference in the case of faster high
// volume transactions
if (hrtimePrecision) {
return (dateString.substring(0, dateString.length - 1) +
process.hrtime()[1].toString().padStart(4, "0").slice(0, 4) +
"Z");
}
return withMilliseconds
? dateString.substring(0, dateString.length - 1) + "0000" + "Z"
: dateString.substring(0, dateString.length - 5) + "Z";
}
exports.truncatedISO8061Date = truncatedISO8061Date;
/**
* Get URL query key value pairs from an URL string.
*
* @export
* @param {string} url
* @returns {{[key: string]: string}}
*/
function getURLQueries(url) {
let queryString = (0, url_1.parse)(url).query;
if (!queryString) {
return {};
}
queryString = queryString.trim();
queryString = queryString.startsWith("?")
? queryString.substr(1)
: queryString;
let querySubStrings = queryString.split("&");
querySubStrings = querySubStrings.filter((value) => {
const indexOfEqual = value.indexOf("=");
const lastIndexOfEqual = value.lastIndexOf("=");
return indexOfEqual > 0 && indexOfEqual === lastIndexOfEqual;
});
const queries = {};
for (const querySubString of querySubStrings) {
const splitResults = querySubString.split("=");
const key = splitResults[0];
const value = splitResults[1];
queries[key] = value;
}
return queries;
}
exports.getURLQueries = getURLQueries;
async function getMD5FromString(text) {
return (0, crypto_1.createHash)("md5").update(text).digest();
}
exports.getMD5FromString = getMD5FromString;
async function getMD5FromStream(stream) {
const hash = (0, crypto_1.createHash)("md5");
return new Promise((resolve, reject) => {
stream
.on("data", (data) => {
hash.update(data);
})
.on("end", () => {
resolve(hash.digest());
})
.on("error", (err) => {
reject(err);
});
});
}
exports.getMD5FromStream = getMD5FromStream;
//# sourceMappingURL=utils.js.map
;