UNPKG

9.36 kBJavaScriptView Raw
1"use strict";
2/**
3 * This file is part of the @egodigital/egoose distribution.
4 * Copyright (c) e.GO Digital GmbH, Aachen, Germany (https://www.e-go-digital.com/)
5 *
6 * @egodigital/egoose is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation, version 3.
9 *
10 * @egodigital/egoose is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18Object.defineProperty(exports, "__esModule", { value: true });
19const _ = require("lodash");
20const streams_1 = require("../streams");
21const NormalizeHeaderCase = require("header-case-normalizer");
22const HTTP = require("http");
23const HTTPs = require("https");
24const index_1 = require("../index");
25const IsStream = require("is-stream");
26const url = require("url");
27/**
28 * Does a HTTP 'CONNECT' request.
29 *
30 * @param {HttpRequestUrl} u The URL to call.
31 * @param {HttpRequestOptionsWithBody} [opts] Options for the request.
32 *
33 * @return {Promise<HttpResponse>} The promise with the response.
34 */
35function CONNECT(u, opts) {
36 return request('CONNECT', u, opts);
37}
38exports.CONNECT = CONNECT;
39/**
40 * Does a HTTP 'DELETE' request.
41 *
42 * @param {HttpRequestUrl} u The URL to call.
43 * @param {HttpRequestOptionsWithBody} [opts] Options for the request.
44 *
45 * @return {Promise<HttpResponse>} The promise with the response.
46 */
47function DELETE(u, opts) {
48 return request('DELETE', u, opts);
49}
50exports.DELETE = DELETE;
51/**
52 * Does a HTTP 'GET' request.
53 *
54 * @param {HttpRequestUrl} u The URL to call.
55 * @param {HttpRequestOptions} [opts] Options for the request.
56 *
57 * @return {Promise<HttpResponse>} The promise with the response.
58 */
59function GET(u, opts) {
60 return request('GET', u, opts);
61}
62exports.GET = GET;
63/**
64 * Does a HTTP 'HEAD' request.
65 *
66 * @param {HttpRequestUrl} u The URL to call.
67 * @param {HttpRequestOptionsWithBody} [opts] Options for the request.
68 *
69 * @return {Promise<HttpResponse>} The promise with the response.
70 */
71function HEAD(u, opts) {
72 return request('HEAD', u, opts);
73}
74exports.HEAD = HEAD;
75/**
76 * Does a HTTP 'OPTIONS' request.
77 *
78 * @param {HttpRequestUrl} u The URL to call.
79 * @param {HttpRequestOptionsWithBody} [opts] Options for the request.
80 *
81 * @return {Promise<HttpResponse>} The promise with the response.
82 */
83function OPTIONS(u, opts) {
84 return request('OPTIONS', u, opts);
85}
86exports.OPTIONS = OPTIONS;
87/**
88 * Does a HTTP 'PATCH' request.
89 *
90 * @param {HttpRequestUrl} u The URL to call.
91 * @param {HttpRequestOptionsWithBody} [opts] Options for the request.
92 *
93 * @return {Promise<HttpResponse>} The promise with the response.
94 */
95function PATCH(u, opts) {
96 return request('PATCH', u, opts);
97}
98exports.PATCH = PATCH;
99/**
100 * Does a HTTP 'POST' request.
101 *
102 * @param {HttpRequestUrl} u The URL to call.
103 * @param {HttpRequestOptionsWithBody} [opts] Options for the request.
104 *
105 * @return {Promise<HttpResponse>} The promise with the response.
106 */
107function POST(u, opts) {
108 return request('POST', u, opts);
109}
110exports.POST = POST;
111/**
112 * Does a HTTP 'PUT' request.
113 *
114 * @param {HttpRequestUrl} u The URL to call.
115 * @param {HttpRequestOptionsWithBody} [opts] Options for the request.
116 *
117 * @return {Promise<HttpResponse>} The promise with the response.
118 */
119function PUT(u, opts) {
120 return request('PUT', u, opts);
121}
122exports.PUT = PUT;
123/**
124 * Does a HTTP 'GET' request.
125 *
126 * @param {string} method The method.
127 * @param {HttpRequestUrl} u The URL to call.
128 * @param {HttpRequestOptionsWithBody} [opts] Options for the request.
129 *
130 * @return {Promise<HttpResponse>} The promise with the response.
131 */
132function request(method, u, opts) {
133 method = index_1.toStringSafe(method).toUpperCase().trim();
134 if ('' === method) {
135 method = 'GET';
136 }
137 if (!_.isObject(u)) {
138 u = url.parse(index_1.toStringSafe(u));
139 }
140 if (_.isNil(opts)) {
141 opts = {};
142 }
143 let enc = index_1.normalizeString(opts.encoding);
144 if ('' === enc) {
145 enc = 'utf8';
146 }
147 return new Promise(async (resolve, reject) => {
148 try {
149 const REQUEST_URL = u;
150 const REQUEST_OPTS = {
151 auth: REQUEST_URL.auth,
152 headers: {},
153 hostname: index_1.toStringSafe(REQUEST_URL.hostname).trim(),
154 port: parseInt(index_1.toStringSafe(REQUEST_URL.port).trim()),
155 method: method,
156 path: REQUEST_URL.path,
157 };
158 let request;
159 const CALLBACK = (response) => {
160 let respBody = false;
161 const RESPONSE = {
162 code: response.statusCode,
163 headers: response.headers || {},
164 pipe: function (target) {
165 return response.pipe(target);
166 },
167 readBody: async function () {
168 if (false === respBody) {
169 respBody = await streams_1.readAll(response);
170 }
171 return respBody;
172 },
173 readJSON: async function (enc) {
174 return JSON.parse(await this.readString(enc));
175 },
176 readString: async function (enc) {
177 enc = index_1.normalizeString(enc);
178 if ('' === enc) {
179 enc = 'utf8';
180 }
181 return (await this.readBody()).toString(enc);
182 },
183 request: request,
184 response: response,
185 status: response.statusMessage,
186 };
187 resolve(RESPONSE);
188 };
189 let requestFactory = false;
190 if ('' === REQUEST_OPTS.hostname) {
191 REQUEST_OPTS.hostname = 'localhost';
192 }
193 if (!_.isNil(opts.headers)) {
194 for (const H in opts.headers) {
195 const HEADER_NAME = index_1.toBooleanSafe(opts.doNotNormalizeHeaders) ?
196 index_1.toStringSafe(H).trim() :
197 NormalizeHeaderCase(index_1.toStringSafe(H).trim());
198 REQUEST_OPTS.headers[HEADER_NAME] =
199 index_1.toStringSafe(opts.headers[H]);
200 }
201 }
202 let timeout = parseInt(index_1.toStringSafe(opts.timeout).trim());
203 if (!isNaN(timeout)) {
204 REQUEST_OPTS.timeout = timeout;
205 }
206 let socket = index_1.toStringSafe(opts.socket);
207 if (index_1.isEmptyString(socket)) {
208 socket = undefined;
209 }
210 REQUEST_OPTS.socketPath = socket;
211 const PROTOCOL = index_1.normalizeString(REQUEST_URL.protocol);
212 switch (PROTOCOL) {
213 case '':
214 case ':':
215 case 'http:':
216 requestFactory = () => {
217 const HTTP_OPTS = REQUEST_OPTS;
218 HTTP_OPTS.protocol = 'http:';
219 if (isNaN(HTTP_OPTS.port)) {
220 HTTP_OPTS.port = 80;
221 }
222 return HTTP.request(HTTP_OPTS, CALLBACK);
223 };
224 break;
225 case 'https:':
226 requestFactory = () => {
227 const HTTPs_OPTS = REQUEST_OPTS;
228 HTTPs_OPTS.protocol = 'https:';
229 HTTPs_OPTS.rejectUnauthorized = false;
230 if (isNaN(HTTPs_OPTS.port)) {
231 HTTPs_OPTS.port = 443;
232 }
233 return HTTPs.request(HTTPs_OPTS, CALLBACK);
234 };
235 break;
236 }
237 if (false === requestFactory) {
238 throw new Error(`HTTP protocol '${PROTOCOL}' not supported`);
239 }
240 request = requestFactory();
241 let body = opts.body;
242 if (_.isFunction(body)) {
243 body = await Promise.resolve(body());
244 }
245 if (!_.isNil(body)) {
246 if (IsStream.readable(body)) {
247 body.pipe(request);
248 }
249 else if (Buffer.isBuffer(body)) {
250 request.write(body);
251 }
252 else {
253 request.write(Buffer.from(index_1.toStringSafe(body), enc));
254 }
255 }
256 request.end();
257 }
258 catch (e) {
259 reject(e);
260 }
261 });
262}
263exports.request = request;
264/**
265 * Does a HTTP 'TRACE' request.
266 *
267 * @param {HttpRequestUrl} u The URL to call.
268 * @param {HttpRequestOptionsWithBody} [opts] Options for the request.
269 *
270 * @return {Promise<HttpResponse>} The promise with the response.
271 */
272function TRACE(u, opts) {
273 return request('TRACE', u, opts);
274}
275exports.TRACE = TRACE;
276//# sourceMappingURL=index.js.map
\No newline at end of file