UNPKG

3.22 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 (opts) => {
24 const qs = querystring.encode(opts.qs);
25 const completeUrl = new URL(opts.uri + (qs.length ? `?${qs}` : ''));
26
27 const reqOpts = {
28 method: opts.method,
29 host: completeUrl.hostname,
30 port: completeUrl.port,
31 path: completeUrl.pathname + completeUrl.search + completeUrl.hash,
32 headers: opts.headers,
33 agent: opts.agent,
34 };
35
36 let responseType;
37 if (opts.responseType) {
38 responseType = opts.responseType;
39 } else {
40 responseType = ResponseType.JSON;
41 }
42
43 if (opts.body) {
44 reqOpts.headers['content-length'] = Buffer.byteLength(opts.body);
45 }
46
47 const adapter = (completeUrl.protocol === 'https:') ? https : http;
48
49 return new Promise((resolve, reject) => {
50 const req = adapter.request(reqOpts, (res) => {
51 if (responseType === ResponseType.Stream) {
52 return resolve({
53 statusCode: res.statusCode,
54 headers: res.headers,
55 data: res,
56 });
57 }
58 const data = [];
59 res.on('data', (chunk) => data.push(chunk));
60 res.on('end', () => {
61 let result = Buffer.concat(data);
62 if (responseType === ResponseType.Text || !result.length) {
63 result = result.toString();
64 } else if (responseType === ResponseType.JSON) {
65 const contentType = res.headers['content-type'];
66 if (!/^application\/json/.test(contentType)) {
67 return reject(new Error('Invalid content-type. ' +
68 `Expected application/json but received ${contentType}`));
69 }
70 result = JSON.parse(result);
71 }
72 resolve({
73 statusCode: res.statusCode,
74 headers: res.headers,
75 data: result,
76 });
77 });
78 });
79
80 req.on('error', reject);
81
82 if (opts.body) {
83 req.write(opts.body);
84 }
85 req.end();
86 });
87};
88
89request.responseType = ResponseType;
90
91module.exports = request;