axios 1.0.0-alpha.1 → 1.1.0
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.
Potentially problematic release.
This version of axios might be problematic. Click here for more details.
- package/CHANGELOG.md +74 -1
- package/README.md +59 -48
- package/SECURITY.md +3 -2
- package/bin/ssl_hotfix.js +1 -1
- package/dist/axios.js +1564 -981
- package/dist/axios.js.map +1 -1
- package/dist/axios.min.js +1 -1
- package/dist/axios.min.js.map +1 -1
- package/dist/esm/axios.js +1472 -866
- package/dist/esm/axios.js.map +1 -1
- package/dist/esm/axios.min.js +1 -1
- package/dist/esm/axios.min.js.map +1 -1
- package/dist/node/axios.cjs +3761 -0
- package/dist/node/axios.cjs.map +1 -0
- package/gulpfile.js +88 -0
- package/index.d.ts +213 -67
- package/index.js +2 -1
- package/karma.conf.cjs +250 -0
- package/lib/adapters/http.js +256 -131
- package/lib/adapters/index.js +33 -0
- package/lib/adapters/xhr.js +79 -56
- package/lib/axios.js +41 -25
- package/lib/cancel/CancelToken.js +91 -88
- package/lib/cancel/CanceledError.js +5 -4
- package/lib/cancel/isCancel.js +2 -2
- package/lib/core/Axios.js +127 -100
- package/lib/core/AxiosError.js +10 -7
- package/lib/core/AxiosHeaders.js +274 -0
- package/lib/core/InterceptorManager.js +61 -53
- package/lib/core/buildFullPath.js +5 -4
- package/lib/core/dispatchRequest.js +21 -39
- package/lib/core/mergeConfig.js +8 -7
- package/lib/core/settle.js +6 -4
- package/lib/core/transformData.js +15 -10
- package/lib/defaults/index.js +46 -39
- package/lib/defaults/transitional.js +1 -1
- package/lib/env/classes/FormData.js +2 -2
- package/lib/env/data.js +1 -3
- package/lib/helpers/AxiosTransformStream.js +191 -0
- package/lib/helpers/AxiosURLSearchParams.js +23 -7
- package/lib/helpers/bind.js +2 -2
- package/lib/helpers/buildURL.js +16 -7
- package/lib/helpers/combineURLs.js +3 -2
- package/lib/helpers/cookies.js +43 -44
- package/lib/helpers/deprecatedMethod.js +4 -2
- package/lib/helpers/formDataToJSON.js +36 -15
- package/lib/helpers/fromDataURI.js +15 -13
- package/lib/helpers/isAbsoluteURL.js +3 -2
- package/lib/helpers/isAxiosError.js +4 -3
- package/lib/helpers/isURLSameOrigin.js +55 -56
- package/lib/helpers/null.js +1 -1
- package/lib/helpers/parseHeaders.js +24 -22
- package/lib/helpers/parseProtocol.js +3 -3
- package/lib/helpers/speedometer.js +55 -0
- package/lib/helpers/spread.js +3 -2
- package/lib/helpers/throttle.js +33 -0
- package/lib/helpers/toFormData.js +68 -18
- package/lib/helpers/toURLEncodedForm.js +5 -5
- package/lib/helpers/validator.js +20 -15
- package/lib/platform/browser/classes/FormData.js +1 -1
- package/lib/platform/browser/classes/URLSearchParams.js +2 -3
- package/lib/platform/browser/index.js +38 -6
- package/lib/platform/index.js +2 -2
- package/lib/platform/node/classes/FormData.js +2 -2
- package/lib/platform/node/classes/URLSearchParams.js +2 -3
- package/lib/platform/node/index.js +5 -4
- package/lib/utils.js +294 -192
- package/package.json +55 -22
- package/rollup.config.js +37 -7
- package/lib/helpers/normalizeHeaderName.js +0 -12
package/lib/adapters/http.js
CHANGED
@@ -1,30 +1,43 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
3
|
+
import utils from './../utils.js';
|
4
|
+
import settle from './../core/settle.js';
|
5
|
+
import buildFullPath from '../core/buildFullPath.js';
|
6
|
+
import buildURL from './../helpers/buildURL.js';
|
7
|
+
import {getProxyForUrl} from 'proxy-from-env';
|
8
|
+
import http from 'http';
|
9
|
+
import https from 'https';
|
10
|
+
import followRedirects from 'follow-redirects';
|
11
|
+
import zlib from 'zlib';
|
12
|
+
import {VERSION} from '../env/data.js';
|
13
|
+
import transitionalDefaults from '../defaults/transitional.js';
|
14
|
+
import AxiosError from '../core/AxiosError.js';
|
15
|
+
import CanceledError from '../cancel/CanceledError.js';
|
16
|
+
import platform from '../platform/index.js';
|
17
|
+
import fromDataURI from '../helpers/fromDataURI.js';
|
18
|
+
import stream from 'stream';
|
19
|
+
import AxiosHeaders from '../core/AxiosHeaders.js';
|
20
|
+
import AxiosTransformStream from '../helpers/AxiosTransformStream.js';
|
21
|
+
import EventEmitter from 'events';
|
22
|
+
|
23
|
+
const isBrotliSupported = utils.isFunction(zlib.createBrotliDecompress);
|
24
|
+
|
25
|
+
const {http: httpFollow, https: httpsFollow} = followRedirects;
|
26
|
+
|
27
|
+
const isHttps = /https:?/;
|
28
|
+
|
29
|
+
const supportedProtocols = platform.protocols.map(protocol => {
|
25
30
|
return protocol + ':';
|
26
31
|
});
|
27
32
|
|
33
|
+
/**
|
34
|
+
* If the proxy or config beforeRedirects functions are defined, call them with the options
|
35
|
+
* object.
|
36
|
+
*
|
37
|
+
* @param {Object<string, any>} options - The options object that was passed to the request.
|
38
|
+
*
|
39
|
+
* @returns {Object<string, any>}
|
40
|
+
*/
|
28
41
|
function dispatchBeforeRedirect(options) {
|
29
42
|
if (options.beforeRedirects.proxy) {
|
30
43
|
options.beforeRedirects.proxy(options);
|
@@ -35,37 +48,43 @@ function dispatchBeforeRedirect(options) {
|
|
35
48
|
}
|
36
49
|
|
37
50
|
/**
|
51
|
+
* If the proxy or config afterRedirects functions are defined, call them with the options
|
38
52
|
*
|
39
53
|
* @param {http.ClientRequestArgs} options
|
40
54
|
* @param {AxiosProxyConfig} configProxy
|
41
55
|
* @param {string} location
|
56
|
+
*
|
57
|
+
* @returns {http.ClientRequestArgs}
|
42
58
|
*/
|
43
59
|
function setProxy(options, configProxy, location) {
|
44
|
-
|
60
|
+
let proxy = configProxy;
|
45
61
|
if (!proxy && proxy !== false) {
|
46
|
-
|
62
|
+
const proxyUrl = getProxyForUrl(location);
|
47
63
|
if (proxyUrl) {
|
48
|
-
proxy =
|
49
|
-
// replace 'host' since the proxy object is not a URL object
|
50
|
-
proxy.host = proxy.hostname;
|
64
|
+
proxy = new URL(proxyUrl);
|
51
65
|
}
|
52
66
|
}
|
53
67
|
if (proxy) {
|
54
68
|
// Basic proxy authorization
|
69
|
+
if (proxy.username) {
|
70
|
+
proxy.auth = (proxy.username || '') + ':' + (proxy.password || '');
|
71
|
+
}
|
72
|
+
|
55
73
|
if (proxy.auth) {
|
56
74
|
// Support proxy auth object form
|
57
75
|
if (proxy.auth.username || proxy.auth.password) {
|
58
76
|
proxy.auth = (proxy.auth.username || '') + ':' + (proxy.auth.password || '');
|
59
77
|
}
|
60
|
-
|
78
|
+
const base64 = Buffer
|
61
79
|
.from(proxy.auth, 'utf8')
|
62
80
|
.toString('base64');
|
63
81
|
options.headers['Proxy-Authorization'] = 'Basic ' + base64;
|
64
82
|
}
|
65
83
|
|
66
84
|
options.headers.host = options.hostname + (options.port ? ':' + options.port : '');
|
67
|
-
options.hostname = proxy.
|
68
|
-
|
85
|
+
options.hostname = proxy.hostname;
|
86
|
+
// Replace 'host' since options is not a URL object
|
87
|
+
options.host = proxy.hostname;
|
69
88
|
options.port = proxy.port;
|
70
89
|
options.path = location;
|
71
90
|
if (proxy.protocol) {
|
@@ -81,47 +100,83 @@ function setProxy(options, configProxy, location) {
|
|
81
100
|
}
|
82
101
|
|
83
102
|
/*eslint consistent-return:0*/
|
84
|
-
|
103
|
+
export default function httpAdapter(config) {
|
85
104
|
return new Promise(function dispatchHttpRequest(resolvePromise, rejectPromise) {
|
86
|
-
|
87
|
-
|
105
|
+
let data = config.data;
|
106
|
+
const responseType = config.responseType;
|
107
|
+
const responseEncoding = config.responseEncoding;
|
108
|
+
const method = config.method.toUpperCase();
|
109
|
+
let isFinished;
|
110
|
+
let isDone;
|
111
|
+
let rejected = false;
|
112
|
+
let req;
|
113
|
+
|
114
|
+
// temporary internal emitter until the AxiosRequest class will be implemented
|
115
|
+
const emitter = new EventEmitter();
|
116
|
+
|
117
|
+
function onFinished() {
|
118
|
+
if (isFinished) return;
|
119
|
+
isFinished = true;
|
120
|
+
|
88
121
|
if (config.cancelToken) {
|
89
|
-
config.cancelToken.unsubscribe(
|
122
|
+
config.cancelToken.unsubscribe(abort);
|
90
123
|
}
|
91
124
|
|
92
125
|
if (config.signal) {
|
93
|
-
config.signal.removeEventListener('abort',
|
126
|
+
config.signal.removeEventListener('abort', abort);
|
94
127
|
}
|
128
|
+
|
129
|
+
emitter.removeAllListeners();
|
95
130
|
}
|
96
|
-
|
97
|
-
|
98
|
-
|
131
|
+
|
132
|
+
function done(value, isRejected) {
|
133
|
+
if (isDone) return;
|
134
|
+
|
135
|
+
isDone = true;
|
136
|
+
|
137
|
+
if (isRejected) {
|
138
|
+
rejected = true;
|
139
|
+
onFinished();
|
140
|
+
}
|
141
|
+
|
142
|
+
isRejected ? rejectPromise(value) : resolvePromise(value);
|
143
|
+
}
|
144
|
+
|
145
|
+
const resolve = function resolve(value) {
|
146
|
+
done(value);
|
99
147
|
};
|
100
|
-
|
101
|
-
|
102
|
-
done();
|
103
|
-
rejected = true;
|
104
|
-
rejectPromise(value);
|
148
|
+
|
149
|
+
const reject = function reject(value) {
|
150
|
+
done(value, true);
|
105
151
|
};
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
152
|
+
|
153
|
+
function abort(reason) {
|
154
|
+
emitter.emit('abort', !reason || reason.type ? new CanceledError(null, config, req) : reason);
|
155
|
+
}
|
156
|
+
|
157
|
+
emitter.once('abort', reject);
|
158
|
+
|
159
|
+
if (config.cancelToken || config.signal) {
|
160
|
+
config.cancelToken && config.cancelToken.subscribe(abort);
|
161
|
+
if (config.signal) {
|
162
|
+
config.signal.aborted ? abort() : config.signal.addEventListener('abort', abort);
|
163
|
+
}
|
164
|
+
}
|
110
165
|
|
111
166
|
// Parse url
|
112
|
-
|
113
|
-
|
114
|
-
|
167
|
+
const fullPath = buildFullPath(config.baseURL, config.url);
|
168
|
+
const parsed = new URL(fullPath);
|
169
|
+
const protocol = parsed.protocol || supportedProtocols[0];
|
115
170
|
|
116
171
|
if (protocol === 'data:') {
|
117
|
-
|
172
|
+
let convertedData;
|
118
173
|
|
119
174
|
if (method !== 'GET') {
|
120
175
|
return settle(resolve, reject, {
|
121
176
|
status: 405,
|
122
177
|
statusText: 'method not allowed',
|
123
178
|
headers: {},
|
124
|
-
config
|
179
|
+
config
|
125
180
|
});
|
126
181
|
}
|
127
182
|
|
@@ -148,7 +203,7 @@ module.exports = function httpAdapter(config) {
|
|
148
203
|
status: 200,
|
149
204
|
statusText: 'OK',
|
150
205
|
headers: {},
|
151
|
-
config
|
206
|
+
config
|
152
207
|
});
|
153
208
|
}
|
154
209
|
|
@@ -160,29 +215,23 @@ module.exports = function httpAdapter(config) {
|
|
160
215
|
));
|
161
216
|
}
|
162
217
|
|
163
|
-
|
164
|
-
var headerNames = {};
|
165
|
-
|
166
|
-
Object.keys(headers).forEach(function storeLowerName(name) {
|
167
|
-
headerNames[name.toLowerCase()] = name;
|
168
|
-
});
|
218
|
+
const headers = AxiosHeaders.from(config.headers).normalize();
|
169
219
|
|
170
220
|
// Set User-Agent (required by some servers)
|
171
221
|
// See https://github.com/axios/axios/issues/69
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
}
|
222
|
+
// User-Agent is specified; handle case where no UA header is desired
|
223
|
+
// Only set header if it hasn't been set in config
|
224
|
+
headers.set('User-Agent', 'axios/' + VERSION, false);
|
225
|
+
|
226
|
+
const onDownloadProgress = config.onDownloadProgress;
|
227
|
+
const onUploadProgress = config.onUploadProgress;
|
228
|
+
const maxRate = config.maxRate;
|
229
|
+
let maxUploadRate = undefined;
|
230
|
+
let maxDownloadRate = undefined;
|
182
231
|
|
183
232
|
// support for https://www.npmjs.com/package/form-data api
|
184
233
|
if (utils.isFormData(data) && utils.isFunction(data.getHeaders)) {
|
185
|
-
|
234
|
+
headers.set(data.getHeaders());
|
186
235
|
} else if (data && !utils.isStream(data)) {
|
187
236
|
if (Buffer.isBuffer(data)) {
|
188
237
|
// Nothing to do...
|
@@ -198,6 +247,9 @@ module.exports = function httpAdapter(config) {
|
|
198
247
|
));
|
199
248
|
}
|
200
249
|
|
250
|
+
// Add Content-Length header if data exists
|
251
|
+
headers.set('Content-Length', data.length, false);
|
252
|
+
|
201
253
|
if (config.maxBodyLength > -1 && data.length > config.maxBodyLength) {
|
202
254
|
return reject(new AxiosError(
|
203
255
|
'Request body larger than maxBodyLength limit',
|
@@ -205,49 +257,75 @@ module.exports = function httpAdapter(config) {
|
|
205
257
|
config
|
206
258
|
));
|
207
259
|
}
|
260
|
+
}
|
208
261
|
|
209
|
-
|
210
|
-
|
211
|
-
|
262
|
+
const contentLength = +headers.getContentLength();
|
263
|
+
|
264
|
+
if (utils.isArray(maxRate)) {
|
265
|
+
maxUploadRate = maxRate[0];
|
266
|
+
maxDownloadRate = maxRate[1];
|
267
|
+
} else {
|
268
|
+
maxUploadRate = maxDownloadRate = maxRate;
|
269
|
+
}
|
270
|
+
|
271
|
+
if (data && (onUploadProgress || maxUploadRate)) {
|
272
|
+
if (!utils.isStream(data)) {
|
273
|
+
data = stream.Readable.from(data, {objectMode: false});
|
212
274
|
}
|
275
|
+
|
276
|
+
data = stream.pipeline([data, new AxiosTransformStream({
|
277
|
+
length: utils.toFiniteNumber(contentLength),
|
278
|
+
maxRate: utils.toFiniteNumber(maxUploadRate)
|
279
|
+
})], utils.noop);
|
280
|
+
|
281
|
+
onUploadProgress && data.on('progress', progress => {
|
282
|
+
onUploadProgress(Object.assign(progress, {
|
283
|
+
upload: true
|
284
|
+
}));
|
285
|
+
});
|
213
286
|
}
|
214
287
|
|
215
288
|
// HTTP basic authentication
|
216
|
-
|
289
|
+
let auth = undefined;
|
217
290
|
if (config.auth) {
|
218
|
-
|
219
|
-
|
291
|
+
const username = config.auth.username || '';
|
292
|
+
const password = config.auth.password || '';
|
220
293
|
auth = username + ':' + password;
|
221
294
|
}
|
222
295
|
|
223
|
-
if (!auth && parsed.
|
224
|
-
|
225
|
-
|
226
|
-
var urlPassword = urlAuth[1] || '';
|
296
|
+
if (!auth && parsed.username) {
|
297
|
+
const urlUsername = parsed.username;
|
298
|
+
const urlPassword = parsed.password;
|
227
299
|
auth = urlUsername + ':' + urlPassword;
|
228
300
|
}
|
229
301
|
|
230
|
-
|
231
|
-
|
232
|
-
|
302
|
+
auth && headers.delete('authorization');
|
303
|
+
|
304
|
+
let path;
|
233
305
|
|
234
306
|
try {
|
235
|
-
|
307
|
+
path = buildURL(
|
308
|
+
parsed.pathname + parsed.search,
|
309
|
+
config.params,
|
310
|
+
config.paramsSerializer
|
311
|
+
).replace(/^\?/, '');
|
236
312
|
} catch (err) {
|
237
|
-
|
313
|
+
const customErr = new Error(err.message);
|
238
314
|
customErr.config = config;
|
239
315
|
customErr.url = config.url;
|
240
316
|
customErr.exists = true;
|
241
|
-
reject(customErr);
|
317
|
+
return reject(customErr);
|
242
318
|
}
|
243
319
|
|
244
|
-
|
245
|
-
|
320
|
+
headers.set('Accept-Encoding', 'gzip, deflate, br', false);
|
321
|
+
|
322
|
+
const options = {
|
323
|
+
path,
|
246
324
|
method: method,
|
247
|
-
headers: headers,
|
325
|
+
headers: headers.toJSON(),
|
248
326
|
agents: { http: config.httpAgent, https: config.httpsAgent },
|
249
|
-
auth
|
250
|
-
protocol
|
327
|
+
auth,
|
328
|
+
protocol,
|
251
329
|
beforeRedirect: dispatchBeforeRedirect,
|
252
330
|
beforeRedirects: {}
|
253
331
|
};
|
@@ -260,8 +338,8 @@ module.exports = function httpAdapter(config) {
|
|
260
338
|
setProxy(options, config.proxy, protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path);
|
261
339
|
}
|
262
340
|
|
263
|
-
|
264
|
-
|
341
|
+
let transport;
|
342
|
+
const isHttpsRequest = isHttps.test(options.protocol);
|
265
343
|
options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;
|
266
344
|
if (config.transport) {
|
267
345
|
transport = config.transport;
|
@@ -289,14 +367,16 @@ module.exports = function httpAdapter(config) {
|
|
289
367
|
}
|
290
368
|
|
291
369
|
// Create the request
|
292
|
-
|
293
|
-
if (req.
|
370
|
+
req = transport.request(options, function handleResponse(res) {
|
371
|
+
if (req.destroyed) return;
|
372
|
+
|
373
|
+
const streams = [res];
|
294
374
|
|
295
375
|
// uncompress the response body transparently if required
|
296
|
-
|
376
|
+
let responseStream = res;
|
297
377
|
|
298
378
|
// return the last request in case of redirects
|
299
|
-
|
379
|
+
const lastRequest = res.req || req;
|
300
380
|
|
301
381
|
// if decompress disabled we should not decompress
|
302
382
|
if (config.decompress !== false) {
|
@@ -312,19 +392,48 @@ module.exports = function httpAdapter(config) {
|
|
312
392
|
case 'compress':
|
313
393
|
case 'deflate':
|
314
394
|
// add the unzipper to the body stream processing pipeline
|
315
|
-
|
395
|
+
streams.push(zlib.createUnzip());
|
316
396
|
|
317
397
|
// remove the content-encoding in order to not confuse downstream operations
|
318
398
|
delete res.headers['content-encoding'];
|
319
399
|
break;
|
400
|
+
case 'br':
|
401
|
+
if (isBrotliSupported) {
|
402
|
+
streams.push(zlib.createBrotliDecompress());
|
403
|
+
delete res.headers['content-encoding'];
|
404
|
+
}
|
320
405
|
}
|
321
406
|
}
|
322
407
|
|
323
|
-
|
408
|
+
if (onDownloadProgress) {
|
409
|
+
const responseLength = +res.headers['content-length'];
|
410
|
+
|
411
|
+
const transformStream = new AxiosTransformStream({
|
412
|
+
length: utils.toFiniteNumber(responseLength),
|
413
|
+
maxRate: utils.toFiniteNumber(maxDownloadRate)
|
414
|
+
});
|
415
|
+
|
416
|
+
onDownloadProgress && transformStream.on('progress', progress => {
|
417
|
+
onDownloadProgress(Object.assign(progress, {
|
418
|
+
download: true
|
419
|
+
}));
|
420
|
+
});
|
421
|
+
|
422
|
+
streams.push(transformStream);
|
423
|
+
}
|
424
|
+
|
425
|
+
responseStream = streams.length > 1 ? stream.pipeline(streams, utils.noop) : streams[0];
|
426
|
+
|
427
|
+
const offListeners = stream.finished(responseStream, () => {
|
428
|
+
offListeners();
|
429
|
+
onFinished();
|
430
|
+
});
|
431
|
+
|
432
|
+
const response = {
|
324
433
|
status: res.statusCode,
|
325
434
|
statusText: res.statusMessage,
|
326
|
-
headers: res.headers,
|
327
|
-
config
|
435
|
+
headers: new AxiosHeaders(res.headers),
|
436
|
+
config,
|
328
437
|
request: lastRequest
|
329
438
|
};
|
330
439
|
|
@@ -332,8 +441,9 @@ module.exports = function httpAdapter(config) {
|
|
332
441
|
response.data = responseStream;
|
333
442
|
settle(resolve, reject, response);
|
334
443
|
} else {
|
335
|
-
|
336
|
-
|
444
|
+
const responseBuffer = [];
|
445
|
+
let totalResponseBytes = 0;
|
446
|
+
|
337
447
|
responseStream.on('data', function handleStreamData(chunk) {
|
338
448
|
responseBuffer.push(chunk);
|
339
449
|
totalResponseBytes += chunk.length;
|
@@ -352,23 +462,25 @@ module.exports = function httpAdapter(config) {
|
|
352
462
|
if (rejected) {
|
353
463
|
return;
|
354
464
|
}
|
355
|
-
|
356
|
-
|
465
|
+
|
466
|
+
const err = new AxiosError(
|
357
467
|
'maxContentLength size of ' + config.maxContentLength + ' exceeded',
|
358
468
|
AxiosError.ERR_BAD_RESPONSE,
|
359
469
|
config,
|
360
470
|
lastRequest
|
361
|
-
)
|
471
|
+
);
|
472
|
+
responseStream.destroy(err);
|
473
|
+
reject(err);
|
362
474
|
});
|
363
475
|
|
364
476
|
responseStream.on('error', function handleStreamError(err) {
|
365
|
-
if (req.
|
477
|
+
if (req.destroyed) return;
|
366
478
|
reject(AxiosError.from(err, null, config, lastRequest));
|
367
479
|
});
|
368
480
|
|
369
481
|
responseStream.on('end', function handleStreamEnd() {
|
370
482
|
try {
|
371
|
-
|
483
|
+
let responseData = responseBuffer.length === 1 ? responseBuffer[0] : Buffer.concat(responseBuffer);
|
372
484
|
if (responseType !== 'arraybuffer') {
|
373
485
|
responseData = responseData.toString(responseEncoding);
|
374
486
|
if (!responseEncoding || responseEncoding === 'utf8') {
|
@@ -382,6 +494,18 @@ module.exports = function httpAdapter(config) {
|
|
382
494
|
settle(resolve, reject, response);
|
383
495
|
});
|
384
496
|
}
|
497
|
+
|
498
|
+
emitter.once('abort', err => {
|
499
|
+
if (!responseStream.destroyed) {
|
500
|
+
responseStream.emit('error', err);
|
501
|
+
responseStream.destroy();
|
502
|
+
}
|
503
|
+
});
|
504
|
+
});
|
505
|
+
|
506
|
+
emitter.once('abort', err => {
|
507
|
+
reject(err);
|
508
|
+
req.destroy(err);
|
385
509
|
});
|
386
510
|
|
387
511
|
// Handle errors
|
@@ -400,7 +524,7 @@ module.exports = function httpAdapter(config) {
|
|
400
524
|
// Handle request timeout
|
401
525
|
if (config.timeout) {
|
402
526
|
// This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types.
|
403
|
-
|
527
|
+
const timeout = parseInt(config.timeout, 10);
|
404
528
|
|
405
529
|
if (isNaN(timeout)) {
|
406
530
|
reject(new AxiosError(
|
@@ -419,9 +543,9 @@ module.exports = function httpAdapter(config) {
|
|
419
543
|
// And then these socket which be hang up will devouring CPU little by little.
|
420
544
|
// ClientRequest.setTimeout will be fired on the specify milliseconds, and can make sure that abort() will be fired after connect.
|
421
545
|
req.setTimeout(timeout, function handleRequestTimeout() {
|
422
|
-
|
423
|
-
|
424
|
-
|
546
|
+
if (isDone) return;
|
547
|
+
let timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded';
|
548
|
+
const transitional = config.transitional || transitionalDefaults;
|
425
549
|
if (config.timeoutErrorMessage) {
|
426
550
|
timeoutErrorMessage = config.timeoutErrorMessage;
|
427
551
|
}
|
@@ -431,33 +555,34 @@ module.exports = function httpAdapter(config) {
|
|
431
555
|
config,
|
432
556
|
req
|
433
557
|
));
|
558
|
+
abort();
|
434
559
|
});
|
435
560
|
}
|
436
561
|
|
437
|
-
if (config.cancelToken || config.signal) {
|
438
|
-
// Handle cancellation
|
439
|
-
// eslint-disable-next-line func-names
|
440
|
-
onCanceled = function(cancel) {
|
441
|
-
if (req.aborted) return;
|
442
562
|
|
443
|
-
|
444
|
-
|
445
|
-
|
563
|
+
// Send the request
|
564
|
+
if (utils.isStream(data)) {
|
565
|
+
let ended = false;
|
566
|
+
let errored = false;
|
446
567
|
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
}
|
451
|
-
}
|
568
|
+
data.on('end', () => {
|
569
|
+
ended = true;
|
570
|
+
});
|
452
571
|
|
572
|
+
data.once('error', err => {
|
573
|
+
errored = true;
|
574
|
+
req.destroy(err);
|
575
|
+
});
|
453
576
|
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
})
|
577
|
+
data.on('close', () => {
|
578
|
+
if (!ended && !errored) {
|
579
|
+
abort(new CanceledError('Request stream has been aborted', config, req));
|
580
|
+
}
|
581
|
+
});
|
582
|
+
|
583
|
+
data.pipe(req);
|
459
584
|
} else {
|
460
585
|
req.end(data);
|
461
586
|
}
|
462
587
|
});
|
463
|
-
}
|
588
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import utils from '../utils.js';
|
2
|
+
import httpAdapter from './http.js';
|
3
|
+
import xhrAdapter from './xhr.js';
|
4
|
+
|
5
|
+
const adapters = {
|
6
|
+
http: httpAdapter,
|
7
|
+
xhr: xhrAdapter
|
8
|
+
}
|
9
|
+
|
10
|
+
export default {
|
11
|
+
getAdapter: (nameOrAdapter) => {
|
12
|
+
if(utils.isString(nameOrAdapter)){
|
13
|
+
const adapter = adapters[nameOrAdapter];
|
14
|
+
|
15
|
+
if (!nameOrAdapter) {
|
16
|
+
throw Error(
|
17
|
+
utils.hasOwnProp(nameOrAdapter) ?
|
18
|
+
`Adapter '${nameOrAdapter}' is not available in the build` :
|
19
|
+
`Can not resolve adapter '${nameOrAdapter}'`
|
20
|
+
);
|
21
|
+
}
|
22
|
+
|
23
|
+
return adapter
|
24
|
+
}
|
25
|
+
|
26
|
+
if (!utils.isFunction(nameOrAdapter)) {
|
27
|
+
throw new TypeError('adapter is not a function');
|
28
|
+
}
|
29
|
+
|
30
|
+
return nameOrAdapter;
|
31
|
+
},
|
32
|
+
adapters
|
33
|
+
}
|