@aikidosec/firewall
Version:
Zen by Aikido is an embedded Web Application Firewall that autonomously protects Node.js apps against common and critical attacks
60 lines (59 loc) • 2.08 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.fetch = fetch;
const http_1 = require("http");
const https_1 = require("https");
const zlib_1 = require("zlib");
async function request({ url, method, body, headers, signal, }) {
const request = url.protocol === "https:" ? https_1.request : http_1.request;
return new Promise((resolve, reject) => {
const req = request(url, {
method,
headers,
signal,
}, (response) => {
let stream = response;
if (response.headers["content-encoding"] === "gzip") {
const gunzip = (0, zlib_1.createGunzip)();
stream = response.pipe(gunzip);
}
let data = "";
stream.on("data", (chunk) => {
data += chunk;
});
stream.on("end", () => {
// We don't throw errors unless the request times out, is aborted or fails for low level reasons
// Error objects are annoying to work with
// That's why we use `resolve` instead of `reject`
resolve({
body: data,
statusCode: response.statusCode || 0,
});
});
});
req.on("error", (error) => {
reject(error);
});
req.end(body);
});
}
async function fetch({ url, method = "GET", headers = {}, body = "", timeoutInMS = 5000, }) {
const abort = new AbortController();
return await Promise.race([
request({
url,
method,
headers,
signal: abort.signal,
body,
}),
new Promise((_, reject) => {
const timeout = setTimeout(() => {
abort.abort();
reject(new Error(`Request to ${url.toString()} timed out after ${timeoutInMS}ms`));
}, timeoutInMS);
// We don't want to keep Node.js running because of this timeout
timeout.unref();
}),
]);
}