got 9.2.1 → 9.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +15 -12
- package/readme.md +131 -13
- package/source/as-promise.js +40 -42
- package/source/as-stream.js +8 -31
- package/source/create.js +24 -14
- package/source/errors.js +9 -5
- package/source/get-response.js +4 -33
- package/source/index.js +15 -7
- package/source/known-hook-events.js +6 -1
- package/source/merge.js +41 -0
- package/source/normalize-arguments.js +123 -132
- package/source/progress.js +34 -5
- package/source/request-as-event-emitter.js +171 -109
- package/source/{deep-freeze.js → utils/deep-freeze.js} +0 -0
- package/source/{get-body-size.js → utils/get-body-size.js} +0 -4
- package/source/{is-form-data.js → utils/is-form-data.js} +0 -0
- package/source/{is-retry-on-network-error-allowed.js → utils/is-retry-on-network-error-allowed.js} +4 -1
- package/source/utils/timed-out.js +153 -0
- package/source/{url-to-options.js → utils/url-to-options.js} +0 -0
- package/source/merge-instances.js +0 -36
- package/source/timed-out.js +0 -160
|
@@ -6,38 +6,42 @@ const http = require('http');
|
|
|
6
6
|
const https = require('https');
|
|
7
7
|
const urlLib = require('url');
|
|
8
8
|
const CacheableRequest = require('cacheable-request');
|
|
9
|
+
const toReadableStream = require('to-readable-stream');
|
|
9
10
|
const is = require('@sindresorhus/is');
|
|
10
11
|
const timer = require('@szmarczak/http-timer');
|
|
11
|
-
const timedOut = require('./timed-out');
|
|
12
|
-
const getBodySize = require('./get-body-size');
|
|
12
|
+
const timedOut = require('./utils/timed-out');
|
|
13
|
+
const getBodySize = require('./utils/get-body-size');
|
|
13
14
|
const getResponse = require('./get-response');
|
|
14
15
|
const progress = require('./progress');
|
|
15
|
-
const {
|
|
16
|
+
const {CacheError, UnsupportedProtocolError, MaxRedirectsError, RequestError, TimeoutError} = require('./errors');
|
|
17
|
+
const urlToOptions = require('./utils/url-to-options');
|
|
16
18
|
|
|
17
19
|
const getMethodRedirectCodes = new Set([300, 301, 302, 303, 304, 305, 307, 308]);
|
|
18
20
|
const allMethodRedirectCodes = new Set([300, 303, 307, 308]);
|
|
19
21
|
|
|
20
|
-
module.exports = options => {
|
|
22
|
+
module.exports = (options, input) => {
|
|
21
23
|
const emitter = new EventEmitter();
|
|
22
|
-
const requestUrl = options.href || (new URL(options.path, urlLib.format(options))).toString();
|
|
23
24
|
const redirects = [];
|
|
24
|
-
|
|
25
|
-
let
|
|
26
|
-
let
|
|
27
|
-
let redirectUrl;
|
|
25
|
+
let currentRequest;
|
|
26
|
+
let requestUrl;
|
|
27
|
+
let redirectString;
|
|
28
28
|
let uploadBodySize;
|
|
29
|
+
let retryCount = 0;
|
|
30
|
+
let shouldAbort = false;
|
|
29
31
|
|
|
30
32
|
const setCookie = options.cookieJar ? util.promisify(options.cookieJar.setCookie.bind(options.cookieJar)) : null;
|
|
31
33
|
const getCookieString = options.cookieJar ? util.promisify(options.cookieJar.getCookieString.bind(options.cookieJar)) : null;
|
|
34
|
+
const agents = is.object(options.agent) ? options.agent : null;
|
|
32
35
|
|
|
33
36
|
const get = async options => {
|
|
34
|
-
const currentUrl =
|
|
37
|
+
const currentUrl = redirectString || requestUrl;
|
|
35
38
|
|
|
36
39
|
if (options.protocol !== 'http:' && options.protocol !== 'https:') {
|
|
37
|
-
|
|
38
|
-
return;
|
|
40
|
+
throw new UnsupportedProtocolError(options);
|
|
39
41
|
}
|
|
40
42
|
|
|
43
|
+
decodeURI(currentUrl);
|
|
44
|
+
|
|
41
45
|
let fn;
|
|
42
46
|
if (is.function(options.request)) {
|
|
43
47
|
fn = {request: options.request};
|
|
@@ -58,124 +62,109 @@ module.exports = options => {
|
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
if (options.cookieJar) {
|
|
61
|
-
|
|
62
|
-
const cookieString = await getCookieString(currentUrl, {});
|
|
65
|
+
const cookieString = await getCookieString(currentUrl, {});
|
|
63
66
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
} catch (error) {
|
|
68
|
-
emitter.emit('error', error);
|
|
67
|
+
if (is.nonEmptyString(cookieString)) {
|
|
68
|
+
options.headers.cookie = cookieString;
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
let timings;
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
73
|
+
const handleResponse = async response => {
|
|
74
|
+
try {
|
|
75
|
+
/* istanbul ignore next: fixes https://github.com/electron/electron/blob/cbb460d47628a7a146adf4419ed48550a98b2923/lib/browser/api/net.js#L59-L65 */
|
|
76
|
+
if (options.useElectronNet) {
|
|
77
|
+
response = new Proxy(response, {
|
|
78
|
+
get: (target, name) => {
|
|
79
|
+
if (name === 'trailers' || name === 'rawTrailers') {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const value = target[name];
|
|
84
|
+
return is.function(value) ? value.bind(target) : value;
|
|
81
85
|
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
82
88
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const {statusCode} = response;
|
|
90
|
-
response.url = currentUrl;
|
|
91
|
-
response.requestUrl = requestUrl;
|
|
92
|
-
response.retryCount = retryCount;
|
|
93
|
-
response.timings = timings;
|
|
89
|
+
const {statusCode} = response;
|
|
90
|
+
response.url = currentUrl;
|
|
91
|
+
response.requestUrl = requestUrl;
|
|
92
|
+
response.retryCount = retryCount;
|
|
93
|
+
response.timings = timings;
|
|
94
|
+
response.redirectUrls = redirects;
|
|
94
95
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
try {
|
|
96
|
+
const rawCookies = response.headers['set-cookie'];
|
|
97
|
+
if (options.cookieJar && rawCookies) {
|
|
98
98
|
await Promise.all(rawCookies.map(rawCookie => setCookie(rawCookie, response.url)));
|
|
99
|
-
} catch (error) {
|
|
100
|
-
emitter.emit('error', error);
|
|
101
99
|
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const followRedirect = options.followRedirect && 'location' in response.headers;
|
|
105
|
-
const redirectGet = followRedirect && getMethodRedirectCodes.has(statusCode);
|
|
106
|
-
const redirectAll = followRedirect && allMethodRedirectCodes.has(statusCode);
|
|
107
100
|
|
|
108
|
-
|
|
109
|
-
|
|
101
|
+
if (options.followRedirect && 'location' in response.headers) {
|
|
102
|
+
if (allMethodRedirectCodes.has(statusCode) || (getMethodRedirectCodes.has(statusCode) && (options.method === 'GET' || options.method === 'HEAD'))) {
|
|
103
|
+
response.resume(); // We're being redirected, we don't care about the response.
|
|
110
104
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
105
|
+
if (statusCode === 303) {
|
|
106
|
+
// Server responded with "see other", indicating that the resource exists at another location,
|
|
107
|
+
// and the client should request it from that location via GET or HEAD.
|
|
108
|
+
options.method = 'GET';
|
|
109
|
+
}
|
|
116
110
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
111
|
+
if (redirects.length >= 10) {
|
|
112
|
+
throw new MaxRedirectsError(statusCode, redirects, options);
|
|
113
|
+
}
|
|
121
114
|
|
|
122
|
-
|
|
123
|
-
|
|
115
|
+
// Handles invalid URLs. See https://github.com/sindresorhus/got/issues/604
|
|
116
|
+
const redirectBuffer = Buffer.from(response.headers.location, 'binary').toString();
|
|
117
|
+
const redirectURL = new URL(redirectBuffer, currentUrl);
|
|
118
|
+
redirectString = redirectURL.toString();
|
|
124
119
|
|
|
125
|
-
|
|
126
|
-
decodeURI(redirectUrl);
|
|
127
|
-
} catch (error) {
|
|
128
|
-
emitter.emit('error', error);
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
120
|
+
redirects.push(redirectString);
|
|
131
121
|
|
|
132
|
-
|
|
122
|
+
const redirectOpts = {
|
|
123
|
+
...options,
|
|
124
|
+
...urlToOptions(redirectURL)
|
|
125
|
+
};
|
|
133
126
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
127
|
+
for (const hook of options.hooks.beforeRedirect) {
|
|
128
|
+
// eslint-disable-next-line no-await-in-loop
|
|
129
|
+
await hook(redirectOpts);
|
|
130
|
+
}
|
|
138
131
|
|
|
139
|
-
|
|
132
|
+
emitter.emit('redirect', response, redirectOpts);
|
|
140
133
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
134
|
+
await get(redirectOpts);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
144
138
|
|
|
145
|
-
|
|
146
|
-
getResponse(response, options, emitter, redirects);
|
|
139
|
+
getResponse(response, options, emitter);
|
|
147
140
|
} catch (error) {
|
|
148
141
|
emitter.emit('error', error);
|
|
149
142
|
}
|
|
150
|
-
}
|
|
143
|
+
};
|
|
151
144
|
|
|
152
|
-
|
|
153
|
-
if (
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
145
|
+
const handleRequest = request => {
|
|
146
|
+
if (shouldAbort) {
|
|
147
|
+
request.once('error', () => {});
|
|
148
|
+
request.abort();
|
|
149
|
+
return;
|
|
157
150
|
}
|
|
158
|
-
});
|
|
159
151
|
|
|
160
|
-
|
|
161
|
-
let aborted = false;
|
|
162
|
-
request.once('abort', _ => {
|
|
163
|
-
aborted = true;
|
|
164
|
-
});
|
|
152
|
+
currentRequest = request;
|
|
165
153
|
|
|
166
154
|
request.once('error', error => {
|
|
167
|
-
if (aborted) {
|
|
155
|
+
if (request.aborted) {
|
|
168
156
|
return;
|
|
169
157
|
}
|
|
170
158
|
|
|
171
|
-
if (
|
|
159
|
+
if (error instanceof timedOut.TimeoutError) {
|
|
160
|
+
error = new TimeoutError(error, options);
|
|
161
|
+
} else {
|
|
172
162
|
error = new RequestError(error, options);
|
|
173
163
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
});
|
|
164
|
+
|
|
165
|
+
if (emitter.retry(error) === false) {
|
|
166
|
+
emitter.emit('error', error);
|
|
167
|
+
}
|
|
179
168
|
});
|
|
180
169
|
|
|
181
170
|
timings = timer(request);
|
|
@@ -183,38 +172,109 @@ module.exports = options => {
|
|
|
183
172
|
progress.upload(request, emitter, uploadBodySize);
|
|
184
173
|
|
|
185
174
|
if (options.gotTimeout) {
|
|
186
|
-
timedOut(request, options);
|
|
175
|
+
timedOut(request, options.gotTimeout, options);
|
|
187
176
|
}
|
|
188
177
|
|
|
189
178
|
emitter.emit('request', request);
|
|
190
|
-
|
|
179
|
+
|
|
180
|
+
const uploadComplete = () => {
|
|
181
|
+
request.emit('upload-complete');
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
try {
|
|
185
|
+
if (is.nodeStream(options.body)) {
|
|
186
|
+
options.body.once('end', uploadComplete);
|
|
187
|
+
options.body.pipe(request);
|
|
188
|
+
options.body = undefined;
|
|
189
|
+
} else if (options.body) {
|
|
190
|
+
request.end(options.body, uploadComplete);
|
|
191
|
+
} else if (input && (options.method === 'POST' || options.method === 'PUT' || options.method === 'PATCH')) {
|
|
192
|
+
input.once('end', uploadComplete);
|
|
193
|
+
input.pipe(request);
|
|
194
|
+
} else {
|
|
195
|
+
request.end(uploadComplete);
|
|
196
|
+
}
|
|
197
|
+
} catch (error) {
|
|
198
|
+
emitter.emit('error', new RequestError(error, options));
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
if (options.cache) {
|
|
203
|
+
const cacheableRequest = new CacheableRequest(fn.request, options.cache);
|
|
204
|
+
const cacheReq = cacheableRequest(options, handleResponse);
|
|
205
|
+
|
|
206
|
+
cacheReq.once('error', error => {
|
|
207
|
+
if (error instanceof CacheableRequest.RequestError) {
|
|
208
|
+
emitter.emit('error', new RequestError(error, options));
|
|
209
|
+
} else {
|
|
210
|
+
emitter.emit('error', new CacheError(error, options));
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
cacheReq.once('request', handleRequest);
|
|
215
|
+
} else {
|
|
216
|
+
// Catches errors thrown by calling fn.request(...)
|
|
217
|
+
try {
|
|
218
|
+
handleRequest(fn.request(options, handleResponse));
|
|
219
|
+
} catch (error) {
|
|
220
|
+
emitter.emit('error', new RequestError(error, options));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
191
223
|
};
|
|
192
224
|
|
|
193
|
-
emitter.
|
|
225
|
+
emitter.retry = error => {
|
|
194
226
|
let backoff;
|
|
227
|
+
|
|
195
228
|
try {
|
|
196
|
-
backoff = options.
|
|
229
|
+
backoff = options.retry.retries(++retryCount, error);
|
|
197
230
|
} catch (error2) {
|
|
198
231
|
emitter.emit('error', error2);
|
|
199
232
|
return;
|
|
200
233
|
}
|
|
201
234
|
|
|
202
235
|
if (backoff) {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
236
|
+
const retry = async options => {
|
|
237
|
+
try {
|
|
238
|
+
for (const hook of options.hooks.beforeRetry) {
|
|
239
|
+
// eslint-disable-next-line no-await-in-loop
|
|
240
|
+
await hook(options, error, retryCount);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
await get(options);
|
|
244
|
+
} catch (error) {
|
|
245
|
+
emitter.emit('error', error);
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
setTimeout(retry, backoff, {...options, forceRefresh: true});
|
|
250
|
+
return true;
|
|
207
251
|
}
|
|
208
252
|
|
|
209
|
-
|
|
210
|
-
}
|
|
253
|
+
return false;
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
emitter.abort = () => {
|
|
257
|
+
if (currentRequest) {
|
|
258
|
+
currentRequest.once('error', () => {});
|
|
259
|
+
currentRequest.abort();
|
|
260
|
+
} else {
|
|
261
|
+
shouldAbort = true;
|
|
262
|
+
}
|
|
263
|
+
};
|
|
211
264
|
|
|
212
265
|
setImmediate(async () => {
|
|
213
266
|
try {
|
|
214
|
-
|
|
267
|
+
// Convert buffer to stream to receive upload progress events (#322)
|
|
268
|
+
const {body} = options;
|
|
269
|
+
if (is.buffer(body)) {
|
|
270
|
+
options.body = toReadableStream(body);
|
|
271
|
+
uploadBodySize = body.length;
|
|
272
|
+
} else {
|
|
273
|
+
uploadBodySize = await getBodySize(options);
|
|
274
|
+
}
|
|
215
275
|
|
|
216
276
|
if (is.undefined(options.headers['content-length']) && is.undefined(options.headers['transfer-encoding'])) {
|
|
217
|
-
if (uploadBodySize > 0 || options.method === 'PUT') {
|
|
277
|
+
if ((uploadBodySize > 0 || options.method === 'PUT') && !is.null(uploadBodySize)) {
|
|
218
278
|
options.headers['content-length'] = uploadBodySize;
|
|
219
279
|
}
|
|
220
280
|
}
|
|
@@ -224,6 +284,8 @@ module.exports = options => {
|
|
|
224
284
|
await hook(options);
|
|
225
285
|
}
|
|
226
286
|
|
|
287
|
+
requestUrl = options.href || (new URL(options.path, urlLib.format(options))).toString();
|
|
288
|
+
|
|
227
289
|
await get(options);
|
|
228
290
|
} catch (error) {
|
|
229
291
|
emitter.emit('error', error);
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const net = require('net');
|
|
3
|
+
|
|
4
|
+
class TimeoutError extends Error {
|
|
5
|
+
constructor(threshold, event) {
|
|
6
|
+
super(`Timeout awaiting '${event}' for ${threshold}ms`);
|
|
7
|
+
this.name = 'TimeoutError';
|
|
8
|
+
this.code = 'ETIMEDOUT';
|
|
9
|
+
this.event = event;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const reentry = Symbol('reentry');
|
|
14
|
+
|
|
15
|
+
const noop = () => {};
|
|
16
|
+
|
|
17
|
+
module.exports = (request, delays, options) => {
|
|
18
|
+
/* istanbul ignore next: this makes sure timed-out isn't called twice */
|
|
19
|
+
if (request[reentry]) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
request[reentry] = true;
|
|
24
|
+
|
|
25
|
+
let stopNewTimeouts = false;
|
|
26
|
+
|
|
27
|
+
const addTimeout = (delay, callback, ...args) => {
|
|
28
|
+
// An error had been thrown before. Going further would result in uncaught errors.
|
|
29
|
+
// See https://github.com/sindresorhus/got/issues/631#issuecomment-435675051
|
|
30
|
+
if (stopNewTimeouts) {
|
|
31
|
+
return noop;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Event loop order is timers, poll, immediates.
|
|
35
|
+
// The timed event may emit during the current tick poll phase, so
|
|
36
|
+
// defer calling the handler until the poll phase completes.
|
|
37
|
+
let immediate;
|
|
38
|
+
const timeout = setTimeout(() => {
|
|
39
|
+
immediate = setImmediate(callback, delay, ...args);
|
|
40
|
+
/* istanbul ignore next: added in node v9.7.0 */
|
|
41
|
+
if (immediate.unref) {
|
|
42
|
+
immediate.unref();
|
|
43
|
+
}
|
|
44
|
+
}, delay);
|
|
45
|
+
|
|
46
|
+
/* istanbul ignore next: in order to support electron renderer */
|
|
47
|
+
if (timeout.unref) {
|
|
48
|
+
timeout.unref();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const cancel = () => {
|
|
52
|
+
clearTimeout(timeout);
|
|
53
|
+
clearImmediate(immediate);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
cancelers.push(cancel);
|
|
57
|
+
|
|
58
|
+
return cancel;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const {host, hostname} = options;
|
|
62
|
+
const timeoutHandler = (delay, event) => {
|
|
63
|
+
request.emit('error', new TimeoutError(delay, event));
|
|
64
|
+
request.once('error', () => {}); // Ignore the `socket hung up` error made by request.abort()
|
|
65
|
+
|
|
66
|
+
request.abort();
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const cancelers = [];
|
|
70
|
+
const cancelTimeouts = () => {
|
|
71
|
+
stopNewTimeouts = true;
|
|
72
|
+
cancelers.forEach(cancelTimeout => cancelTimeout());
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
request.once('error', cancelTimeouts);
|
|
76
|
+
request.once('response', response => {
|
|
77
|
+
response.once('end', cancelTimeouts);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (delays.request !== undefined) {
|
|
81
|
+
addTimeout(delays.request, timeoutHandler, 'request');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (delays.socket !== undefined) {
|
|
85
|
+
request.setTimeout(delays.socket, () => {
|
|
86
|
+
timeoutHandler(delays.socket, 'socket');
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (delays.lookup !== undefined && !request.socketPath && !net.isIP(hostname || host)) {
|
|
91
|
+
request.once('socket', socket => {
|
|
92
|
+
/* istanbul ignore next: hard to test */
|
|
93
|
+
if (socket.connecting) {
|
|
94
|
+
const cancelTimeout = addTimeout(delays.lookup, timeoutHandler, 'lookup');
|
|
95
|
+
socket.once('lookup', cancelTimeout);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (delays.connect !== undefined) {
|
|
101
|
+
request.once('socket', socket => {
|
|
102
|
+
/* istanbul ignore next: hard to test */
|
|
103
|
+
if (socket.connecting) {
|
|
104
|
+
const timeConnect = () => addTimeout(delays.connect, timeoutHandler, 'connect');
|
|
105
|
+
|
|
106
|
+
if (request.socketPath || net.isIP(hostname || host)) {
|
|
107
|
+
socket.once('connect', timeConnect());
|
|
108
|
+
} else {
|
|
109
|
+
socket.once('lookup', error => {
|
|
110
|
+
if (error === null) {
|
|
111
|
+
socket.once('connect', timeConnect());
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (delays.secureConnect !== undefined && options.protocol === 'https:') {
|
|
120
|
+
request.once('socket', socket => {
|
|
121
|
+
/* istanbul ignore next: hard to test */
|
|
122
|
+
if (socket.connecting) {
|
|
123
|
+
socket.once('connect', () => {
|
|
124
|
+
const cancelTimeout = addTimeout(delays.secureConnect, timeoutHandler, 'secureConnect');
|
|
125
|
+
socket.once('secureConnect', cancelTimeout);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (delays.send !== undefined) {
|
|
132
|
+
request.once('socket', socket => {
|
|
133
|
+
const timeRequest = () => addTimeout(delays.send, timeoutHandler, 'send');
|
|
134
|
+
/* istanbul ignore next: hard to test */
|
|
135
|
+
if (socket.connecting) {
|
|
136
|
+
socket.once('connect', () => {
|
|
137
|
+
request.once('upload-complete', timeRequest());
|
|
138
|
+
});
|
|
139
|
+
} else {
|
|
140
|
+
request.once('upload-complete', timeRequest());
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (delays.response !== undefined) {
|
|
146
|
+
request.once('upload-complete', () => {
|
|
147
|
+
const cancelTimeout = addTimeout(delays.response, timeoutHandler, 'response');
|
|
148
|
+
request.once('response', cancelTimeout);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
module.exports.TimeoutError = TimeoutError;
|
|
File without changes
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
const merge = require('./merge');
|
|
3
|
-
const knownHookEvents = require('./known-hook-events');
|
|
4
|
-
|
|
5
|
-
module.exports = (instances, methods) => {
|
|
6
|
-
const handlers = instances.map(instance => instance.defaults.handler);
|
|
7
|
-
const size = instances.length - 1;
|
|
8
|
-
|
|
9
|
-
let options = {};
|
|
10
|
-
const hooks = {};
|
|
11
|
-
for (const instance of instances) {
|
|
12
|
-
options = merge({}, options, instance.defaults.options);
|
|
13
|
-
|
|
14
|
-
const instanceHooks = instance.defaults.options.hooks;
|
|
15
|
-
for (const name of knownHookEvents) {
|
|
16
|
-
if (hooks[name]) {
|
|
17
|
-
hooks[name] = hooks[name].concat(instanceHooks[name]);
|
|
18
|
-
} else {
|
|
19
|
-
hooks[name] = [...instanceHooks[name]];
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
options.hooks = hooks;
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
methods,
|
|
28
|
-
options,
|
|
29
|
-
handler: (options, next) => {
|
|
30
|
-
let iteration = -1;
|
|
31
|
-
const iterate = options => handlers[++iteration](options, iteration === size ? next : iterate);
|
|
32
|
-
|
|
33
|
-
return iterate(options);
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
};
|