UNPKG

3.48 kBJavaScriptView Raw
1/**************************************************************************
2 * (C) Copyright ModusBox Inc. 2020 - All rights reserved. *
3 * *
4 * This file is made available under the terms of the license agreement *
5 * specified in the corresponding source code repository. *
6 * *
7 * ORIGINAL AUTHOR: *
8 * Yevhen Kyriukha - yevhen.kyriukha@modusbox.com *
9 **************************************************************************/
10
11const http = require('http');
12const https = require('https');
13const querystring = require('querystring');
14const { URL } = require('url');
15
16const ResponseType = Object.freeze({
17 ArrayBuffer: Symbol('arraybuffer'),
18 JSON: Symbol('json'),
19 Text: Symbol('text'),
20 Stream: Symbol('stream'),
21});
22
23const request = async ({
24 uri,
25 qs = null,
26 responseType = ResponseType.JSON,
27 body = null,
28 method,
29 headers,
30 agent,
31}) => {
32 const qsEnc = querystring.encode(qs);
33 const completeUrl = new URL(uri + (qsEnc.length ? `?${qsEnc}` : ''));
34
35 const reqOpts = {
36 method,
37 host: completeUrl.hostname,
38 port: completeUrl.port,
39 path: completeUrl.pathname + completeUrl.search + completeUrl.hash,
40 headers,
41 agent,
42 };
43
44 if (body) {
45 reqOpts.headers['content-length'] = Buffer.byteLength(body);
46 }
47
48 const adapter = (completeUrl.protocol === 'https:') ? https : http;
49
50 return new Promise((resolve, reject) => {
51 const originalRequest = {
52 ...reqOpts,
53 body,
54 };
55
56 const req = adapter.request(reqOpts, (res) => {
57 if (responseType === ResponseType.Stream) {
58 return resolve({
59 statusCode: res.statusCode,
60 headers: res.headers,
61 data: res,
62 originalRequest,
63 });
64 }
65 const data = [];
66 res.on('data', (chunk) => data.push(chunk));
67 res.on('end', () => {
68 let result = Buffer.concat(data);
69 if (responseType === ResponseType.Text || !result.length) {
70 result = result.toString();
71 } else if (responseType === ResponseType.JSON) {
72 const contentType = res.headers['content-type'];
73 if (!/^application\/json/.test(contentType)) {
74 let err = new Error('Invalid content-type. ' +
75 `Expected application/json but received ${contentType}`);
76 err.originalRequest = originalRequest;
77 return reject(err);
78 }
79 result = JSON.parse(result);
80 }
81 resolve({
82 statusCode: res.statusCode,
83 headers: res.headers,
84 data: result,
85 originalRequest,
86 });
87 });
88 });
89
90 req.on('error', (err) => {
91 err.originalRequest = originalRequest;
92 reject(err);
93 });
94
95 if (body) {
96 req.write(body);
97 }
98 req.end();
99 });
100};
101
102request.responseType = ResponseType;
103
104module.exports = request;