UNPKG

6.79 kBJavaScriptView Raw
1'use strict';
2
3const logger = require('./logger').getLogger('http-request');
4const superagent = require('superagent');
5const Promise = require('bluebird');
6const { makeCounters } = require('./httpRequestCounters');
7
8const wrapWithMonitoring = makeCounters();
9
10const DEFAULT_REQUEST_TIMEOUT = process.env.DEFAULT_REQUEST_TIMEOUT || 30000; //30sec timeout
11const DOWNLOAD_REQUEST_TIMEOUT = 60000; //1min timeout
12
13function getCaFile() {
14 return global.caFileContent;
15}
16
17function binaryParser(res, fn) {
18 const data = [];
19
20 res.on('data', (chunk) => {
21 data.push(chunk); // Append Buffer object
22 });
23 res.on('end', () => {
24 fn(null, Buffer.concat(data)); // Merge the chunks and return
25 });
26}
27
28function getProxy() {
29 if (!superagent.Request.prototype.proxy && global.SuperagentProxy) {
30 global.SuperagentProxy(superagent);
31 }
32 return global.proxyUri;
33}
34
35function deleteMethod(url, headers, timeout) {
36 return deleteFullRes(url, headers, timeout)
37 .then(res => {
38 if (res.type === 'text/plain') {
39 return res.text;
40 }
41 return res.body;
42 })
43 .tapCatch((err) => logger.error('failed to delete request', { url, error: { message: err.message, stack: err.stack } }));
44}
45
46function deleteFullRes(url, headers = {}, timeout = DEFAULT_REQUEST_TIMEOUT) {
47 const request = superagent
48 .delete(url)
49 .timeout(timeout)
50 .set(headers);
51
52 if (getCaFile()) {
53 request.ca(getCaFile());
54 }
55
56 if (getProxy()) {
57 request.proxy(getProxy());
58 }
59
60 return Promise.fromCallback((callback) => request.end(callback));
61}
62
63function post({
64 url, body, headers, timeout, retry,
65}) {
66 return postFullRes(url, body, headers, timeout, retry)
67 .then(res => {
68 if (res.type === 'text/plain') {
69 return res.text;
70 }
71 return res.body;
72 })
73 .tapCatch((err) => logger.error('failed to post request', { url, error: { message: err.message, stack: err.stack } }));
74}
75
76function postFullRes(url, body, headers = {}, timeout = DEFAULT_REQUEST_TIMEOUT, retry) {
77 const request = superagent
78 .post(url)
79 .send(body)
80 .timeout(timeout)
81 .set(headers);
82
83 if (getCaFile()) {
84 request.ca(getCaFile());
85 }
86
87 if (getProxy()) {
88 request.proxy(getProxy());
89 }
90
91 if (retry) {
92 request.retry(retry);
93 }
94
95 return Promise.fromCallback((callback) => request.end(callback)).catch(e => e, e => {
96 e.url = url;
97 e.originalRequestTimeout = timeout;
98 e.additionalSetHeaders = headers;
99 throw e;
100 });
101}
102
103function postForm(url, fields, files, headers = {}, timeout = DEFAULT_REQUEST_TIMEOUT) {
104 const request = superagent
105 .post(url)
106 .type('form')
107 .timeout(timeout)
108 .set(headers);
109
110 request.field(fields);
111
112 Object.keys(files).forEach(file => {
113 request.attach(file, files[file].buffer, files[file].fileName);
114 });
115
116 if (getCaFile()) {
117 request.ca(getCaFile());
118 }
119
120 if (getProxy()) {
121 request.proxy(getProxy());
122 }
123
124 return Promise.fromCallback((callback) => request.end(callback))
125 .then((res) => {
126 if (res.type === 'text/plain') {
127 return res.text;
128 }
129 return res.body;
130 })
131 .tapCatch((err) => logger.error('failed to post request', { url, error: { message: err.message, stack: err.stack } }));
132}
133
134function _get(url, query, headers = {}, timeout = DEFAULT_REQUEST_TIMEOUT, { isBinary = false } = {}) {
135 const request = superagent
136 .get(url)
137 .query(query)
138 .timeout(timeout)
139 .set(headers);
140
141 if (isBinary) {
142 request.buffer(true);
143 }
144
145 if (getCaFile()) {
146 request.ca(getCaFile());
147 }
148
149 if (getProxy()) {
150 request.proxy(getProxy());
151 }
152
153 return Promise.fromCallback((callback) => request.end(callback));
154}
155
156function getText(url, query, headers) {
157 return _get(url, query, headers)
158 .then((res) => res.text)
159 .tapCatch((err) => logger.error('failed to getText request', { url, query, error: { message: err.message, stack: err.stack } }));
160}
161
162function get(url, query, headers, timeout, options) {
163 return _get(url, query, headers, timeout, options)
164 .then((res) => res.body)
165 .tapCatch((err) => logger.warn('failed to get request', { url, query, error: { message: err.message, stack: err.stack } }));
166}
167
168function getFullRes(url, query, headers, timeout) {
169 return _get(url, query, headers, timeout);
170}
171
172function head(url) {
173 const request = superagent
174 .head(url)
175 .timeout(DEFAULT_REQUEST_TIMEOUT);
176
177 if (getCaFile()) {
178 request.ca(getCaFile());
179 }
180
181 if (getProxy()) {
182 request.proxy(getProxy());
183 }
184
185 return Promise.fromCallback((callback) => request.end(callback))
186 .tapCatch((err) => logger.error('failed to head request', { url, error: { message: err.message, stack: err.stack } }));
187}
188
189function put(url, body, headers = {}, timeout = DEFAULT_REQUEST_TIMEOUT) {
190 const request = superagent
191 .put(url)
192 .send(body)
193 .timeout(timeout)
194 .set(headers);
195
196 if (getCaFile()) {
197 request.ca(getCaFile());
198 }
199
200 if (getProxy()) {
201 request.proxy(getProxy());
202 }
203
204 return Promise.fromCallback((callback) => request.end(callback))
205 .then((res) => res.body)
206 .tapCatch((err) => logger.error('failed to put request', { url, error: { message: err.message, stack: err.stack } }));
207}
208
209function download(url) {
210 logger.info('start to download', { url });
211
212 const request = superagent
213 .get(url)
214 .timeout(DOWNLOAD_REQUEST_TIMEOUT)
215 .buffer(true)
216 .parse(binaryParser);
217
218 if (getCaFile()) {
219 request.ca(getCaFile());
220 }
221
222 if (getProxy()) {
223 request.proxy(getProxy());
224 }
225
226 return Promise.fromCallback((callback) => request.end(callback))
227 .tap(() => logger.info('finished to download', { url }))
228 .tapCatch((err) => logger.error('failed to download', { error: { message: err.message, stack: err.stack } }));
229}
230
231module.exports = {
232 delete: wrapWithMonitoring(deleteMethod),
233 deleteFullRes: wrapWithMonitoring(deleteFullRes),
234 put: wrapWithMonitoring(put),
235 get: wrapWithMonitoring(get),
236 getText: wrapWithMonitoring(getText),
237 post: wrapWithMonitoring(post),
238 postFullRes: wrapWithMonitoring(postFullRes),
239 getFullRes: wrapWithMonitoring(getFullRes),
240 postForm: wrapWithMonitoring(postForm),
241 head: wrapWithMonitoring(head),
242 download: wrapWithMonitoring(download),
243 isNetworkHealthy: wrapWithMonitoring.isNetworkHealthy,
244};