Skip to content

Commit 26dcf9e

Browse files
committed
switch from request to axios for http(s)
Since request is no longer receiving updates, switch to axios. Attempt to keep the same options as much as possible. However these changes occurred in the switch: 1. There is only one option for redirects `followRedirect: true|false` (defaults to true). 2. `httpSignature` is not implemented in axios and now not available. (If this feature is still desired, please help by providing a pull request to implement it.) 3. `auth` now allows `username` and `password` but not the aliases `user` and `pass`
1 parent d0f5f86 commit 26dcf9e

File tree

7 files changed

+534
-708
lines changed

7 files changed

+534
-708
lines changed

README.md

+9-16
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ var opts = {
155155
'tcp:foo.com:8000',
156156
'socket:/my/sock',
157157
'http://unix:/my/sock:/my/url',
158-
'http-get://unix:/my/sock:/my/url'
158+
'http-get://unix:/my/sock:/my/url',
159159
],
160160
delay: 1000, // initial delay in ms, default 0
161161
interval: 100, // poll interval in ms, default 250ms
@@ -176,22 +176,17 @@ var opts = {
176176
passphrase: 'yourpassphrase',
177177
auth: {
178178
user: 'theuser', // or username
179-
pass: 'thepassword' // or password
180-
},
181-
httpSignature: {
182-
keyId: 'yourKeyId',
183-
key: 'yourKey'
179+
pass: 'thepassword', // or password
184180
},
185181
strictSSL: false,
186-
followAllRedirects: true,
187182
followRedirect: true,
188183
headers: {
189-
'x-custom': 'headers'
190-
}
184+
'x-custom': 'headers',
185+
},
191186
};
192187

193188
// Usage with callback function
194-
waitOn(opts, function(err) {
189+
waitOn(opts, function (err) {
195190
if (err) {
196191
return handleError(err);
197192
}
@@ -200,10 +195,10 @@ waitOn(opts, function(err) {
200195

201196
// Usage with promises
202197
waitOn(opts)
203-
.then(function() {
198+
.then(function () {
204199
// once here, all resources are available
205200
})
206-
.catch(function(err) {
201+
.catch(function (err) {
207202
handleError(err);
208203
});
209204

@@ -227,17 +222,15 @@ waitOn(opts, [cb]) - function which triggers resource checks
227222
- opts.tcpTimeout - optional tcp timeout in ms, default 300ms
228223
- opts.verbose - optional flag which outputs debug output, default false
229224
- opts.window - optional stabilization time in ms, default 750ms. Waits this amount of time for file sizes to stabilize or other resource availability to remain unchanged.
230-
- http(s) specific options, see https://github.com/request/request#readme for specific details
225+
- http(s) specific options, see https://nodejs.org/api/tls.html#tls_tls_connect_options_callback for specific details
231226

232227
- opts.ca: [ /* strings or binaries */ ],
233228
- opts.cert: [ /* strings or binaries */ ],
234229
- opts.key: [ /* strings or binaries */ ],
235230
- opts.passphrase: 'yourpassphrase',
236231
- opts.auth: { user, pass }
237-
- opts.httpSignature: { keyId, key }
238232
- opts.strictSSL: false,
239-
- opts.followAllRedirects: true,
240-
- opts.followRedirect: true,
233+
- opts.followRedirect: false, // defaults to true
241234
- opts.headers: { 'x-custom': 'headers' },
242235

243236
- cb(err) - if err is provided then, resource checks did not succeed

exampleConfig.js

+13-12
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
module.exports = {
22
// specify additional options here, especially http(s)
3-
// see https://github.com/request/request#readme for specifics
4-
ca: [ /* strings or binaries */],
5-
cert: [ /* strings or binaries */],
6-
key: [ /* strings or binaries */],
3+
// see https://nodejs.org/api/tls.html#tls_tls_connect_options_callback for specifics
4+
ca: [
5+
/* strings or binaries */
6+
],
7+
cert: [
8+
/* strings or binaries */
9+
],
10+
key: [
11+
/* strings or binaries */
12+
],
713
passphrase: 'yourpassphrase',
814
auth: {
915
user: 'yourusername',
10-
pass: 'yourpassword'
11-
},
12-
httpSignature: {
13-
keyId: 'keyId',
14-
key: 'yourkey'
16+
pass: 'yourpassword',
1517
},
1618
strictSSL: false,
17-
followAllRedirects: false,
1819
followRedirect: false,
1920
headers: {
20-
'x-custom': 'headers'
21-
}
21+
'x-custom': 'headers',
22+
},
2223
};

lib/wait-on.js

+68-83
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
const fs = require('fs');
44
const { promisify } = require('util');
55
const Joi = require('@hapi/joi');
6+
const https = require('https');
67
const net = require('net');
7-
const requestProm = require('request-promise-native');
8+
const util = require('util');
9+
const axios = require('axios').default;
810
const { isBoolean, isEmpty, negate, noop, once, partial, pick, zip } = require('lodash/fp');
911
const { NEVER, combineLatest, from, merge, throwError, timer } = require('rxjs');
1012
const { distinctUntilChanged, map, mergeMap, scan, startWith, take, takeWhile } = require('rxjs/operators');
@@ -15,62 +17,34 @@ const fstat = promisify(fs.stat);
1517
const PREFIX_RE = /^((https?-get|https?|tcp|socket|file):)(.+)$/;
1618
const HOST_PORT_RE = /^(([^:]*):)?(\d+)$/;
1719
const HTTP_GET_RE = /^https?-get:/;
20+
const HTTP_UNIX_RE = /^http:\/\/unix:([^:]+):([^:]+)$/;
1821
const TIMEOUT_ERR_MSG = 'Timeout';
1922

2023
const WAIT_ON_SCHEMA = Joi.object({
21-
resources: Joi.array()
22-
.items(Joi.string().required())
23-
.required(),
24-
delay: Joi.number()
25-
.integer()
26-
.min(0)
27-
.default(0),
28-
httpTimeout: Joi.number()
29-
.integer()
30-
.min(0),
31-
interval: Joi.number()
32-
.integer()
33-
.min(0)
34-
.default(250),
24+
resources: Joi.array().items(Joi.string().required()).required(),
25+
delay: Joi.number().integer().min(0).default(0),
26+
httpTimeout: Joi.number().integer().min(0),
27+
interval: Joi.number().integer().min(0).default(250),
3528
log: Joi.boolean().default(false),
3629
reverse: Joi.boolean().default(false),
37-
simultaneous: Joi.number()
38-
.integer()
39-
.min(1)
40-
.default(Infinity),
41-
timeout: Joi.number()
42-
.integer()
43-
.min(0)
44-
.default(Infinity),
30+
simultaneous: Joi.number().integer().min(1).default(Infinity),
31+
timeout: Joi.number().integer().min(0).default(Infinity),
4532
verbose: Joi.boolean().default(false),
46-
window: Joi.number()
47-
.integer()
48-
.min(0)
49-
.default(750),
50-
tcpTimeout: Joi.number()
51-
.integer()
52-
.min(0)
53-
.default(300),
54-
55-
// http options3
33+
window: Joi.number().integer().min(0).default(750),
34+
tcpTimeout: Joi.number().integer().min(0).default(300),
35+
36+
// http/https options
5637
ca: [Joi.string(), Joi.binary()],
5738
cert: [Joi.string(), Joi.binary()],
58-
key: [Joi.string(), Joi.binary()],
39+
key: [Joi.string(), Joi.binary(), Joi.object()],
5940
passphrase: Joi.string(),
6041
auth: Joi.object({
61-
user: Joi.string(),
6242
username: Joi.string(),
6343
password: Joi.string(),
64-
pass: Joi.string()
65-
}),
66-
httpSignature: Joi.object({
67-
keyId: Joi.string().required(),
68-
key: Joi.string().required()
6944
}),
70-
strictSSL: Joi.boolean(),
71-
followAllRedirects: Joi.boolean(),
72-
followRedirect: Joi.boolean(),
73-
headers: Joi.object()
45+
strictSSL: Joi.boolean().default(false),
46+
followRedirect: Joi.boolean().default(true), // HTTP 3XX responses
47+
headers: Joi.object(),
7448
});
7549

7650
/**
@@ -86,6 +60,9 @@ const WAIT_ON_SCHEMA = Joi.object({
8660
- https-get: - HTTPS GET returns 2XX response. ex: https://my/bar
8761
- tcp:my.server.com:3000 verifies a service is listening on port
8862
- socket:/path/sock verifies a service is listening on (UDS) socket
63+
For http over socket, use http://unix:SOCK_PATH:URL_PATH
64+
like http://unix:/path/to/sock:/foo/bar or
65+
http-get://unix:/path/to/sock:/foo/bar
8966
9067
@param opts object configuring waitOn
9168
@param opts.resources array of string resources to wait for. prefix determines the type of resource with the default type of `file:`
@@ -107,8 +84,8 @@ function waitOn(opts, cb) {
10784
return waitOnImpl(opts, cb);
10885
} else {
10986
// promise API
110-
return new Promise(function(resolve, reject) {
111-
waitOnImpl(opts, function(err) {
87+
return new Promise(function (resolve, reject) {
88+
waitOnImpl(opts, function (err) {
11289
if (err) {
11390
reject(err);
11491
} else {
@@ -129,7 +106,7 @@ function waitOnImpl(opts, cbFunc) {
129106
...validResult.value, // use defaults
130107
// window needs to be at least interval
131108
...(validResult.value.window < validResult.value.interval ? { window: validResult.value.interval } : {}),
132-
...(validResult.value.verbose ? { log: true } : {}) // if debug logging then normal log is also enabled
109+
...(validResult.value.verbose ? { log: true } : {}), // if debug logging then normal log is also enabled
133110
};
134111

135112
const { resources, log: shouldLog, timeout, verbose, reverse } = validatedOpts;
@@ -167,14 +144,14 @@ function waitOnImpl(opts, cbFunc) {
167144
const resourcesCompleted$ = combineLatest(resources.map(createResourceWithDeps$));
168145

169146
merge(timeoutError$, resourcesCompleted$)
170-
.pipe(takeWhile(resourceStates => resourceStates.some(x => !x)))
147+
.pipe(takeWhile((resourceStates) => resourceStates.some((x) => !x)))
171148
.subscribe({
172-
next: resourceStates => {
149+
next: (resourceStates) => {
173150
lastResourcesState = resourceStates;
174151
logWaitingForWDeps(resourceStates);
175152
},
176153
error: cleanup,
177-
complete: cleanup
154+
complete: cleanup,
178155
});
179156
}
180157

@@ -214,7 +191,7 @@ function createFileResource$(
214191
) {
215192
const filePath = extractPath(resource);
216193
const checkOperator = reverse
217-
? map(size => size === -1) // check that file does not exist
194+
? map((size) => size === -1) // check that file does not exist
218195
: scan(
219196
// check that file exists and the size is stable
220197
(acc, x) => {
@@ -244,7 +221,7 @@ function createFileResource$(
244221
return from(getFileSize(filePath));
245222
}, simultaneous),
246223
checkOperator,
247-
map(x => (isNotABoolean(x) ? false : x)),
224+
map((x) => (isNotABoolean(x) ? false : x)),
248225
startWith(false),
249226
distinctUntilChanged(),
250227
take(2)
@@ -277,35 +254,39 @@ async function getFileSize(filePath) {
277254
}
278255

279256
function createHTTP$({ validatedOpts, output }, resource) {
280-
const { delay, interval, reverse, simultaneous } = validatedOpts;
281-
const method = HTTP_GET_RE.test(resource) ? 'GET' : 'HEAD';
282-
const uri = resource.replace('-get:', ':');
257+
const {
258+
delay,
259+
followRedirect,
260+
httpTimeout: timeout,
261+
interval,
262+
reverse,
263+
simultaneous,
264+
strictSSL: rejectUnauthorized,
265+
} = validatedOpts;
266+
const method = HTTP_GET_RE.test(resource) ? 'get' : 'head';
267+
const url = resource.replace('-get:', ':');
268+
const matchHttpUnixSocket = HTTP_UNIX_RE.exec(url); // http://unix:/sock:/url
269+
const urlSocketOptions = matchHttpUnixSocket
270+
? { socketPath: matchHttpUnixSocket[1], url: matchHttpUnixSocket[2] }
271+
: { url };
272+
const socketPathDesc = urlSocketOptions.socketPath ? `socketPath:${urlSocketOptions.socketPath}` : '';
283273
const httpOptions = {
284-
...pick(
285-
[
286-
'auth',
287-
'httpSignature',
288-
'followRedirect',
289-
'followAllRedirects',
290-
'strictSSL',
291-
'headers',
292-
'cert',
293-
'key',
294-
'passphrase',
295-
'ca'
296-
],
297-
validatedOpts
298-
),
299-
...(validatedOpts.httpTimeout ? { timeout: validatedOpts.httpTimeout } : {}),
300-
uri,
274+
...pick(['auth', 'headers'], validatedOpts),
275+
httpsAgent: new https.Agent({
276+
rejectUnauthorized,
277+
...pick(['ca', 'cert', 'key', 'passphrase'], validatedOpts),
278+
}),
279+
...(followRedirect ? {} : { maxRedirects: 0 }), // defaults to 5 (enabled)
280+
...(timeout && { timeout }),
281+
...urlSocketOptions,
301282
method,
302-
resolveWithFullResponse: true,
303-
simple: true // statusCodes other than 2xx will reject
283+
// by default it provides full response object
284+
// validStatus is 2xx unless followRedirect is true (default)
304285
};
305286
const checkFn = reverse ? negateAsync(httpCallSucceeds) : httpCallSucceeds;
306287
return timer(delay, interval).pipe(
307288
mergeMap(() => {
308-
output(`making HTTP ${method} request to ${uri} ...`);
289+
output(`making HTTP(S) ${method} request to ${socketPathDesc} url:${urlSocketOptions.url} ...`);
309290
return from(checkFn(output, httpOptions));
310291
}, simultaneous),
311292
startWith(false),
@@ -316,11 +297,15 @@ function createHTTP$({ validatedOpts, output }, resource) {
316297

317298
async function httpCallSucceeds(output, httpOptions) {
318299
try {
319-
const result = await requestProm(httpOptions);
320-
output(` HTTP result for ${httpOptions.uri}: ${JSON.stringify(result)}`);
300+
const result = await axios(httpOptions);
301+
output(
302+
` HTTP(S) result for ${httpOptions.url}: ${util.inspect(
303+
pick(['status', 'statusText', 'headers', 'data'], result)
304+
)}`
305+
);
321306
return true;
322307
} catch (err) {
323-
output(` HTTP error for ${httpOptions.uri} ${err.toString()}`);
308+
output(` HTTP(S) error for ${httpOptions.url} ${err.toString()}`);
324309
return false;
325310
}
326311
}
@@ -342,10 +327,10 @@ function createTCP$({ validatedOpts: { delay, interval, tcpTimeout, reverse, sim
342327
async function tcpExists(output, tcpPath, tcpTimeout) {
343328
const [, , /* full, hostWithColon */ hostMatched, port] = HOST_PORT_RE.exec(tcpPath);
344329
const host = hostMatched || 'localhost';
345-
return new Promise(resolve => {
330+
return new Promise((resolve) => {
346331
const conn = net
347332
.connect(port, host)
348-
.on('error', err => {
333+
.on('error', (err) => {
349334
output(` error connecting to TCP host:${host} port:${port} ${err.toString()}`);
350335
resolve(false);
351336
})
@@ -378,10 +363,10 @@ function createSocket$({ validatedOpts: { delay, interval, reverse, simultaneous
378363
}
379364

380365
async function socketExists(output, socketPath) {
381-
return new Promise(resolve => {
366+
return new Promise((resolve) => {
382367
const conn = net
383368
.connect(socketPath)
384-
.on('error', err => {
369+
.on('error', (err) => {
385370
output(` error connecting to socket socket:${socketPath} ${err.toString()}`);
386371
resolve(false);
387372
})
@@ -394,7 +379,7 @@ async function socketExists(output, socketPath) {
394379
}
395380

396381
function negateAsync(asyncFn) {
397-
return async function(...args) {
382+
return async function (...args) {
398383
return !(await asyncFn(...args));
399384
};
400385
}

0 commit comments

Comments
 (0)