UNPKG

flagpole

Version:

Simple and fast DOM integration, headless or headful browser, and REST API testing framework.

382 lines 11.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.HttpRequest = exports.HttpMethodVerbAllowedValues = void 0; const httpresponse_1 = require("./httpresponse"); const needle = require("needle"); const tunnel = require("tunnel"); const FormData = require("form-data"); const form_urlencoded_1 = require("form-urlencoded"); const image_probe_1 = require("@zerodeps/image-probe"); const flagpoleexecution_1 = require("./flagpoleexecution"); const CONTENT_TYPE_JSON = "application/json"; const CONTENT_TYPE_FORM_MULTIPART = "multipart/form-data"; const CONTENT_TYPE_FORM = "application/x-www-form-urlencoded"; const ENCODING_GZIP = "gzip,deflate"; exports.HttpMethodVerbAllowedValues = [ "get", "head", "delete", "patch", "post", "put", "options", ]; class HttpRequest { constructor(opts) { this._uri = null; this._method = "get"; this._headers = {}; this._cookies = {}; this._verifyCert = false; this._timeout = { open: 10000 }; this._maxRedirects = 10; this._fetched = false; this._browser = {}; this._type = "generic"; this.setOptions(opts); } get uri() { return this._uri; } set uri(value) { if (!this.isImmutable) { this._uri = value; } } get method() { return this._method; } set method(value) { if (!this.isImmutable) { this._method = value; } } get type() { return this._type; } set type(value) { if (!this.isImmutable) { this._type = value; if (value === "json") { this.headers["Content-Type"] = CONTENT_TYPE_JSON; } } } get headers() { return this._headers; } set headers(value) { if (!this.isImmutable) { this._headers = value; } } get cookies() { return this._cookies; } set cookies(value) { if (!this.isImmutable) { this._cookies = value; } } get auth() { return this._auth; } set auth(value) { if (!this.isImmutable) { this._auth = value; } } get authType() { return this._authType; } set authType(value) { if (!this.isImmutable) { this._authType = value; } } get maxRedirects() { return this._maxRedirects; } set maxRedirects(value) { if (!this.isImmutable) { this._maxRedirects = value; } } get timeout() { return this._timeout; } set timeout(value) { if (!this.isImmutable) { this._timeout = value; } } get proxy() { return this._proxy; } set proxy(value) { if (!this.isImmutable) { this._proxy = value; } } get verifyCert() { return this._verifyCert; } set verifyCert(value) { if (!this.isImmutable) { this._verifyCert = value; } } get data() { return this._data; } set data(value) { if (!this.isImmutable) { this._data = value; } } get browser() { return this._browser; } set browser(value) { if (!this.isImmutable) { this._browser = value; } } get proxyAgent() { if (this._proxy) { return tunnel.httpOverHttp({ proxy: { host: this._proxy.host, port: this._proxy.port, proxyAuth: `${this._proxy.auth.username}:${this._proxy.auth.password}`, }, }); } } get isImmutable() { return this._fetched; } get outputFile() { return this._outputFile; } set outputFile(value) { if (!this.isImmutable) { this._outputFile = value; } } get options() { return { uri: this._uri, method: this._method, headers: this._headers, cookies: this._cookies, verifyCert: this._verifyCert, proxy: this._proxy, maxRedirects: this._maxRedirects, timeout: this._timeout, auth: this._auth, authType: this._authType, outputFile: this._outputFile, data: this._data, type: this._type, }; } get needleOptions() { var _a, _b; return { agent: this.proxyAgent, auth: this._authType || "auto", compressed: this.headers["Accept-Encoding"] === ENCODING_GZIP, cookies: this.cookies, follow_max: this.maxRedirects, headers: this.headers, json: this.headers["Content-Type"] === CONTENT_TYPE_JSON, multipart: this.headers["Content-Type"] === CONTENT_TYPE_FORM_MULTIPART, open_timeout: this.timeout.open, output: this.outputFile, parse_cookies: true, parse_response: false, password: (_a = this.auth) === null || _a === void 0 ? void 0 : _a.password, read_timeout: this.timeout.read, rejectUnauthorized: this.verifyCert, username: (_b = this.auth) === null || _b === void 0 ? void 0 : _b.username, user_agent: "Flagpole", }; } get httpOptions() { return { agent: this.proxyAgent, headers: this.headers, method: this.method, timeout: this.timeout.open, }; } get gotOptions() { return { agent: this.proxyAgent, allowGetBody: true, body: this.data, followRedirect: this.maxRedirects > 0, headers: this.headers, maxRedirects: this.maxRedirects, method: this.method, timeout: this.timeout.open, }; } urlEncodeForm(data) { const encoded = []; Object.keys(data).forEach((key) => { encoded.push(`${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`); }); return encoded.join("&"); } setOptions(opts) { if (!this.isImmutable) { this._type = opts.type || this._type; this._uri = opts.uri || this._uri; this._method = opts.method || this._method; this._headers = opts.headers || this._headers; this._cookies = opts.cookies || this._cookies; this._verifyCert = typeof opts.verifyCert === "undefined" ? this._verifyCert : opts.verifyCert; this._proxy = opts.proxy; this._maxRedirects = typeof opts.maxRedirects === "undefined" ? this._maxRedirects : opts.maxRedirects; this._timeout = (() => { if (!opts.timeout) { return this._timeout; } if (typeof opts.timeout == "number") { return { open: opts.timeout, }; } return opts.timeout; })(); this._auth = opts.auth || this._auth; this._browser = opts.browserOptions || this._browser; this._data = opts.data || this._data; this._outputFile = opts.outputFile || this._outputFile; } return this; } setCookie(key, value) { if (!this.isImmutable) { this._cookies[key] = value; } } getCookie(key) { return this._cookies[key]; } setHeader(key, value) { if (!this.isImmutable) { this._headers[key] = value; } } getHeader(key) { return this._headers[key]; } setJsonData(data) { this.setHeader("Content-Type", CONTENT_TYPE_JSON); this.data = data; } setFormData(data, isMultipart) { if (data instanceof FormData && !isMultipart) { throw new Error("This format of form data must be multipart."); } this.setHeader("Content-Type", isMultipart ? CONTENT_TYPE_FORM_MULTIPART : CONTENT_TYPE_FORM); if (data instanceof FormData) { this.data = data; } else if (isMultipart) { const formData = new FormData(); Object.keys(data).forEach((key) => formData.append(key, data[key])); this.data = formData; } else { this.data = form_urlencoded_1.default(data); } return this; } fetch(opts) { if (this._fetched) { throw new Error("This request was already fetched."); } this._fetched = true; if (this._uri === null) { throw new Error("Invalid URI"); } if (this.type === "image") { return this._fetchImage(opts); } else { return this._fetchHttp(opts); } } _fetchHttp(opts) { return new Promise((resolve, reject) => { if (this.options.cacheKey) { const response = flagpoleexecution_1.FlagpoleExecution.global.getCache(this.options.cacheKey); if (response !== null) { return resolve(response); } } const stream = needle.request(this.method === "options" ? "head" : this.method, this.uri || "/", this.data || null, this.needleOptions, (err, resp) => { if (!err && resp) { const response = httpresponse_1.HttpResponse.fromNeedle(resp); if (this.options.cacheKey) { flagpoleexecution_1.FlagpoleExecution.global.setCache(this.options.cacheKey, response); } return resolve(response); } reject(err); }); if (opts === null || opts === void 0 ? void 0 : opts.redirect) { stream.on("redirect", opts.redirect); } }); } _fetchImage(opts) { return new Promise((resolve, reject) => { const stream = needle.request("get", this.uri || "/", null, this.needleOptions); if (opts === null || opts === void 0 ? void 0 : opts.redirect) { stream.on("redirect", opts.redirect); } const response = { statusCode: 0, length: 0, url: this.uri || "", headers: {}, imageData: { width: 0, height: 0, type: "", mimeType: "", }, }; stream .on("header", (statusCode, headers) => { response.statusCode = statusCode; response.headers = headers; response.length = Number(headers["content-length"]); }) .on("readable", () => { const chunk = stream.read(512); response.imageData = image_probe_1.ImageProbe.fromBuffer(chunk) || response.imageData; stream.pause(); try { stream.destroy(); } catch (_a) { } resolve(httpresponse_1.HttpResponse.fromProbeImage(response)); }); }); } } exports.HttpRequest = HttpRequest; //# sourceMappingURL=httprequest.js.map