1 | ;
|
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 | */
|
18 | Object.defineProperty(exports, "__esModule", { value: true });
|
19 | const _ = require("lodash");
|
20 | const streams_1 = require("../streams");
|
21 | const NormalizeHeaderCase = require("header-case-normalizer");
|
22 | const HTTP = require("http");
|
23 | const HTTPs = require("https");
|
24 | const index_1 = require("../index");
|
25 | const IsStream = require("is-stream");
|
26 | const 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 | */
|
35 | function CONNECT(u, opts) {
|
36 | return request('CONNECT', u, opts);
|
37 | }
|
38 | exports.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 | */
|
47 | function DELETE(u, opts) {
|
48 | return request('DELETE', u, opts);
|
49 | }
|
50 | exports.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 | */
|
59 | function GET(u, opts) {
|
60 | return request('GET', u, opts);
|
61 | }
|
62 | exports.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 | */
|
71 | function HEAD(u, opts) {
|
72 | return request('HEAD', u, opts);
|
73 | }
|
74 | exports.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 | */
|
83 | function OPTIONS(u, opts) {
|
84 | return request('OPTIONS', u, opts);
|
85 | }
|
86 | exports.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 | */
|
95 | function PATCH(u, opts) {
|
96 | return request('PATCH', u, opts);
|
97 | }
|
98 | exports.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 | */
|
107 | function POST(u, opts) {
|
108 | return request('POST', u, opts);
|
109 | }
|
110 | exports.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 | */
|
119 | function PUT(u, opts) {
|
120 | return request('PUT', u, opts);
|
121 | }
|
122 | exports.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 | */
|
132 | function 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 | }
|
263 | exports.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 | */
|
272 | function TRACE(u, opts) {
|
273 | return request('TRACE', u, opts);
|
274 | }
|
275 | exports.TRACE = TRACE;
|
276 | //# sourceMappingURL=index.js.map |
\ | No newline at end of file |