@egodigital/egoose
Version:
Helper classes and functions for Node.js 10 or later.
276 lines • 9.36 kB
JavaScript
;
/**
* 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