UNPKG

@egodigital/egoose

Version:

Helper classes and functions for Node.js 10 or later.

276 lines 9.36 kB
"use strict"; /** * This file is part of the @egodigital/egoose distribution. * Copyright (c) e.GO Digital GmbH, Aachen, Germany (https://www.e-go-digital.com/) * * @egodigital/egoose is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, version 3. * * @egodigital/egoose is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ Object.defineProperty(exports, "__esModule", { value: true }); const _ = require("lodash"); const streams_1 = require("../streams"); const NormalizeHeaderCase = require("header-case-normalizer"); const HTTP = require("http"); const HTTPs = require("https"); const index_1 = require("../index"); const IsStream = require("is-stream"); const url = require("url"); /** * Does a HTTP 'CONNECT' request. * * @param {HttpRequestUrl} u The URL to call. * @param {HttpRequestOptionsWithBody} [opts] Options for the request. * * @return {Promise<HttpResponse>} The promise with the response. */ function CONNECT(u, opts) { return request('CONNECT', u, opts); } exports.CONNECT = CONNECT; /** * Does a HTTP 'DELETE' request. * * @param {HttpRequestUrl} u The URL to call. * @param {HttpRequestOptionsWithBody} [opts] Options for the request. * * @return {Promise<HttpResponse>} The promise with the response. */ function DELETE(u, opts) { return request('DELETE', u, opts); } exports.DELETE = DELETE; /** * Does a HTTP 'GET' request. * * @param {HttpRequestUrl} u The URL to call. * @param {HttpRequestOptions} [opts] Options for the request. * * @return {Promise<HttpResponse>} The promise with the response. */ function GET(u, opts) { return request('GET', u, opts); } exports.GET = GET; /** * Does a HTTP 'HEAD' request. * * @param {HttpRequestUrl} u The URL to call. * @param {HttpRequestOptionsWithBody} [opts] Options for the request. * * @return {Promise<HttpResponse>} The promise with the response. */ function HEAD(u, opts) { return request('HEAD', u, opts); } exports.HEAD = HEAD; /** * Does a HTTP 'OPTIONS' request. * * @param {HttpRequestUrl} u The URL to call. * @param {HttpRequestOptionsWithBody} [opts] Options for the request. * * @return {Promise<HttpResponse>} The promise with the response. */ function OPTIONS(u, opts) { return request('OPTIONS', u, opts); } exports.OPTIONS = OPTIONS; /** * Does a HTTP 'PATCH' request. * * @param {HttpRequestUrl} u The URL to call. * @param {HttpRequestOptionsWithBody} [opts] Options for the request. * * @return {Promise<HttpResponse>} The promise with the response. */ function PATCH(u, opts) { return request('PATCH', u, opts); } exports.PATCH = PATCH; /** * Does a HTTP 'POST' request. * * @param {HttpRequestUrl} u The URL to call. * @param {HttpRequestOptionsWithBody} [opts] Options for the request. * * @return {Promise<HttpResponse>} The promise with the response. */ function POST(u, opts) { return request('POST', u, opts); } exports.POST = POST; /** * Does a HTTP 'PUT' request. * * @param {HttpRequestUrl} u The URL to call. * @param {HttpRequestOptionsWithBody} [opts] Options for the request. * * @return {Promise<HttpResponse>} The promise with the response. */ function PUT(u, opts) { return request('PUT', u, opts); } exports.PUT = PUT; /** * Does a HTTP 'GET' request. * * @param {string} method The method. * @param {HttpRequestUrl} u The URL to call. * @param {HttpRequestOptionsWithBody} [opts] Options for the request. * * @return {Promise<HttpResponse>} The promise with the response. */ function request(method, u, opts) { method = index_1.toStringSafe(method).toUpperCase().trim(); if ('' === method) { method = 'GET'; } if (!_.isObject(u)) { u = url.parse(index_1.toStringSafe(u)); } if (_.isNil(opts)) { opts = {}; } let enc = index_1.normalizeString(opts.encoding); if ('' === enc) { enc = 'utf8'; } return new Promise(async (resolve, reject) => { try { const REQUEST_URL = u; const REQUEST_OPTS = { auth: REQUEST_URL.auth, headers: {}, hostname: index_1.toStringSafe(REQUEST_URL.hostname).trim(), port: parseInt(index_1.toStringSafe(REQUEST_URL.port).trim()), method: method, path: REQUEST_URL.path, }; let request; const CALLBACK = (response) => { let respBody = false; const RESPONSE = { code: response.statusCode, headers: response.headers || {}, pipe: function (target) { return response.pipe(target); }, readBody: async function () { if (false === respBody) { respBody = await streams_1.readAll(response); } return respBody; }, readJSON: async function (enc) { return JSON.parse(await this.readString(enc)); }, readString: async function (enc) { enc = index_1.normalizeString(enc); if ('' === enc) { enc = 'utf8'; } return (await this.readBody()).toString(enc); }, request: request, response: response, status: response.statusMessage, }; resolve(RESPONSE); }; let requestFactory = false; if ('' === REQUEST_OPTS.hostname) { REQUEST_OPTS.hostname = 'localhost'; } if (!_.isNil(opts.headers)) { for (const H in opts.headers) { const HEADER_NAME = index_1.toBooleanSafe(opts.doNotNormalizeHeaders) ? index_1.toStringSafe(H).trim() : NormalizeHeaderCase(index_1.toStringSafe(H).trim()); REQUEST_OPTS.headers[HEADER_NAME] = index_1.toStringSafe(opts.headers[H]); } } let timeout = parseInt(index_1.toStringSafe(opts.timeout).trim()); if (!isNaN(timeout)) { REQUEST_OPTS.timeout = timeout; } let socket = index_1.toStringSafe(opts.socket); if (index_1.isEmptyString(socket)) { socket = undefined; } REQUEST_OPTS.socketPath = socket; const PROTOCOL = index_1.normalizeString(REQUEST_URL.protocol); switch (PROTOCOL) { case '': case ':': case 'http:': requestFactory = () => { const HTTP_OPTS = REQUEST_OPTS; HTTP_OPTS.protocol = 'http:'; if (isNaN(HTTP_OPTS.port)) { HTTP_OPTS.port = 80; } return HTTP.request(HTTP_OPTS, CALLBACK); }; break; case 'https:': requestFactory = () => { const HTTPs_OPTS = REQUEST_OPTS; HTTPs_OPTS.protocol = 'https:'; HTTPs_OPTS.rejectUnauthorized = false; if (isNaN(HTTPs_OPTS.port)) { HTTPs_OPTS.port = 443; } return HTTPs.request(HTTPs_OPTS, CALLBACK); }; break; } if (false === requestFactory) { throw new Error(`HTTP protocol '${PROTOCOL}' not supported`); } request = requestFactory(); let body = opts.body; if (_.isFunction(body)) { body = await Promise.resolve(body()); } if (!_.isNil(body)) { if (IsStream.readable(body)) { body.pipe(request); } else if (Buffer.isBuffer(body)) { request.write(body); } else { request.write(Buffer.from(index_1.toStringSafe(body), enc)); } } request.end(); } catch (e) { reject(e); } }); } exports.request = request; /** * Does a HTTP 'TRACE' request. * * @param {HttpRequestUrl} u The URL to call. * @param {HttpRequestOptionsWithBody} [opts] Options for the request. * * @return {Promise<HttpResponse>} The promise with the response. */ function TRACE(u, opts) { return request('TRACE', u, opts); } exports.TRACE = TRACE; //# sourceMappingURL=index.js.map