axios 0.27.1 → 0.28.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.
Files changed (51) hide show
  1. package/CHANGELOG.md +127 -57
  2. package/README.md +271 -80
  3. package/SECURITY.md +3 -3
  4. package/UPGRADE_GUIDE.md +16 -15
  5. package/bin/check-build-version.js +19 -0
  6. package/bin/ssl_hotfix.js +22 -0
  7. package/dist/axios.js +1961 -4280
  8. package/dist/axios.js.map +1 -0
  9. package/dist/axios.min.js +2 -12
  10. package/dist/axios.min.js.map +1 -0
  11. package/dist/esm/axios.js +2354 -0
  12. package/dist/esm/axios.js.map +1 -0
  13. package/dist/esm/axios.min.js +2 -0
  14. package/dist/esm/axios.min.js.map +1 -0
  15. package/index.d.ts +104 -19
  16. package/lib/adapters/http.js +153 -114
  17. package/lib/adapters/xhr.js +20 -12
  18. package/lib/axios.js +5 -1
  19. package/lib/cancel/CancelToken.js +4 -5
  20. package/lib/cancel/CanceledError.js +4 -2
  21. package/lib/core/Axios.js +6 -1
  22. package/lib/core/AxiosError.js +12 -1
  23. package/lib/core/InterceptorManager.js +9 -0
  24. package/lib/core/dispatchRequest.js +7 -0
  25. package/lib/core/mergeConfig.js +3 -0
  26. package/lib/core/transformData.js +3 -2
  27. package/lib/defaults/index.js +42 -13
  28. package/lib/env/data.js +1 -1
  29. package/lib/helpers/AxiosURLSearchParams.js +42 -0
  30. package/lib/helpers/bind.js +1 -5
  31. package/lib/helpers/buildURL.js +14 -37
  32. package/lib/helpers/formDataToJSON.js +71 -0
  33. package/lib/helpers/fromDataURI.js +51 -0
  34. package/lib/helpers/isURLSameOrigin.js +12 -12
  35. package/lib/helpers/parseHeaders.js +2 -2
  36. package/lib/helpers/parseProtocol.js +6 -0
  37. package/lib/helpers/toFormData.js +141 -34
  38. package/lib/helpers/toURLEncodedForm.js +18 -0
  39. package/lib/platform/browser/classes/FormData.js +3 -0
  40. package/lib/platform/browser/classes/URLSearchParams.js +5 -0
  41. package/lib/platform/browser/index.js +11 -0
  42. package/lib/platform/index.js +3 -0
  43. package/lib/platform/node/classes/FormData.js +3 -0
  44. package/lib/platform/node/classes/URLSearchParams.js +5 -0
  45. package/lib/platform/node/index.js +11 -0
  46. package/lib/utils.js +68 -16
  47. package/package.json +18 -8
  48. package/rollup.config.js +60 -0
  49. package/dist/axios.map +0 -1
  50. package/dist/axios.min.map +0 -1
  51. /package/lib/{defaults/env → env/classes}/FormData.js +0 -0
@@ -4,43 +4,79 @@ var utils = require('./../utils');
4
4
  var settle = require('./../core/settle');
5
5
  var buildFullPath = require('../core/buildFullPath');
6
6
  var buildURL = require('./../helpers/buildURL');
7
+ var getProxyForUrl = require('proxy-from-env').getProxyForUrl;
7
8
  var http = require('http');
8
9
  var https = require('https');
9
- var httpFollow = require('follow-redirects').http;
10
- var httpsFollow = require('follow-redirects').https;
10
+ var httpFollow = require('follow-redirects/http');
11
+ var httpsFollow = require('follow-redirects/https');
11
12
  var url = require('url');
12
13
  var zlib = require('zlib');
13
14
  var VERSION = require('./../env/data').version;
14
15
  var transitionalDefaults = require('../defaults/transitional');
15
16
  var AxiosError = require('../core/AxiosError');
16
17
  var CanceledError = require('../cancel/CanceledError');
18
+ var platform = require('../platform');
19
+ var fromDataURI = require('../helpers/fromDataURI');
20
+ var stream = require('stream');
17
21
 
18
22
  var isHttps = /https:?/;
19
23
 
20
- var supportedProtocols = [ 'http:', 'https:', 'file:' ];
24
+ var supportedProtocols = platform.protocols.map(function(protocol) {
25
+ return protocol + ':';
26
+ });
27
+
28
+ function dispatchBeforeRedirect(options) {
29
+ if (options.beforeRedirects.proxy) {
30
+ options.beforeRedirects.proxy(options);
31
+ }
32
+ if (options.beforeRedirects.config) {
33
+ options.beforeRedirects.config(options);
34
+ }
35
+ }
21
36
 
22
37
  /**
23
38
  *
24
39
  * @param {http.ClientRequestArgs} options
25
- * @param {AxiosProxyConfig} proxy
40
+ * @param {AxiosProxyConfig} configProxy
26
41
  * @param {string} location
27
42
  */
28
- function setProxy(options, proxy, location) {
29
- options.hostname = proxy.host;
30
- options.host = proxy.host;
31
- options.port = proxy.port;
32
- options.path = location;
33
-
34
- // Basic proxy authorization
35
- if (proxy.auth) {
36
- var base64 = Buffer.from(proxy.auth.username + ':' + proxy.auth.password, 'utf8').toString('base64');
37
- options.headers['Proxy-Authorization'] = 'Basic ' + base64;
43
+ function setProxy(options, configProxy, location) {
44
+ var proxy = configProxy;
45
+ if (!proxy && proxy !== false) {
46
+ var proxyUrl = getProxyForUrl(location);
47
+ if (proxyUrl) {
48
+ proxy = url.parse(proxyUrl);
49
+ // replace 'host' since the proxy object is not a URL object
50
+ proxy.host = proxy.hostname;
51
+ }
52
+ }
53
+ if (proxy) {
54
+ // Basic proxy authorization
55
+ if (proxy.auth) {
56
+ // Support proxy auth object form
57
+ if (proxy.auth.username || proxy.auth.password) {
58
+ proxy.auth = (proxy.auth.username || '') + ':' + (proxy.auth.password || '');
59
+ }
60
+ var base64 = Buffer
61
+ .from(proxy.auth, 'utf8')
62
+ .toString('base64');
63
+ options.headers['Proxy-Authorization'] = 'Basic ' + base64;
64
+ }
65
+
66
+ options.headers.host = options.hostname + (options.port ? ':' + options.port : '');
67
+ options.hostname = proxy.host;
68
+ options.host = proxy.host;
69
+ options.port = proxy.port;
70
+ options.path = location;
71
+ if (proxy.protocol) {
72
+ options.protocol = proxy.protocol;
73
+ }
38
74
  }
39
75
 
40
- // If a proxy is used, any redirects must also pass through the proxy
41
- options.beforeRedirect = function beforeRedirect(redirection) {
42
- redirection.headers.host = redirection.host;
43
- setProxy(redirection, proxy, redirection.href);
76
+ options.beforeRedirects.proxy = function beforeRedirect(redirectOptions) {
77
+ // Configure proxy for redirected request, passing the original config proxy to apply
78
+ // the exact same logic as if the redirected request was performed by axios directly.
79
+ setProxy(redirectOptions, configProxy, redirectOptions.href);
44
80
  };
45
81
  }
46
82
 
@@ -68,6 +104,62 @@ module.exports = function httpAdapter(config) {
68
104
  rejectPromise(value);
69
105
  };
70
106
  var data = config.data;
107
+ var responseType = config.responseType;
108
+ var responseEncoding = config.responseEncoding;
109
+ var method = config.method.toUpperCase();
110
+
111
+ // Parse url
112
+ var fullPath = buildFullPath(config.baseURL, config.url);
113
+ var parsed = url.parse(fullPath);
114
+ var protocol = parsed.protocol || supportedProtocols[0];
115
+
116
+ if (protocol === 'data:') {
117
+ var convertedData;
118
+
119
+ if (method !== 'GET') {
120
+ return settle(resolve, reject, {
121
+ status: 405,
122
+ statusText: 'method not allowed',
123
+ headers: {},
124
+ config: config
125
+ });
126
+ }
127
+
128
+ try {
129
+ convertedData = fromDataURI(config.url, responseType === 'blob', {
130
+ Blob: config.env && config.env.Blob
131
+ });
132
+ } catch (err) {
133
+ throw AxiosError.from(err, AxiosError.ERR_BAD_REQUEST, config);
134
+ }
135
+
136
+ if (responseType === 'text') {
137
+ convertedData = convertedData.toString(responseEncoding);
138
+
139
+ if (!responseEncoding || responseEncoding === 'utf8') {
140
+ data = utils.stripBOM(convertedData);
141
+ }
142
+ } else if (responseType === 'stream') {
143
+ convertedData = stream.Readable.from(convertedData);
144
+ }
145
+
146
+ return settle(resolve, reject, {
147
+ data: convertedData,
148
+ status: 200,
149
+ statusText: 'OK',
150
+ headers: {},
151
+ config: config
152
+ });
153
+ }
154
+
155
+ if (supportedProtocols.indexOf(protocol) === -1) {
156
+ return reject(new AxiosError(
157
+ 'Unsupported protocol ' + protocol,
158
+ AxiosError.ERR_BAD_REQUEST,
159
+ config
160
+ ));
161
+ }
162
+
71
163
  var headers = config.headers;
72
164
  var headerNames = {};
73
165
 
@@ -128,19 +220,6 @@ module.exports = function httpAdapter(config) {
128
220
  auth = username + ':' + password;
129
221
  }
130
222
 
131
- // Parse url
132
- var fullPath = buildFullPath(config.baseURL, config.url);
133
- var parsed = url.parse(fullPath);
134
- var protocol = parsed.protocol || supportedProtocols[0];
135
-
136
- if (supportedProtocols.indexOf(protocol) === -1) {
137
- return reject(new AxiosError(
138
- 'Unsupported protocol ' + protocol,
139
- AxiosError.ERR_BAD_REQUEST,
140
- config
141
- ));
142
- }
143
-
144
223
  if (!auth && parsed.auth) {
145
224
  var urlAuth = parsed.auth.split(':');
146
225
  var urlUsername = urlAuth[0] || '';
@@ -152,9 +231,6 @@ module.exports = function httpAdapter(config) {
152
231
  delete headers[headerNames.authorization];
153
232
  }
154
233
 
155
- var isHttpsRequest = isHttps.test(protocol);
156
- var agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;
157
-
158
234
  try {
159
235
  buildURL(parsed.path, config.params, config.paramsSerializer).replace(/^\?/, '');
160
236
  } catch (err) {
@@ -167,11 +243,13 @@ module.exports = function httpAdapter(config) {
167
243
 
168
244
  var options = {
169
245
  path: buildURL(parsed.path, config.params, config.paramsSerializer).replace(/^\?/, ''),
170
- method: config.method.toUpperCase(),
246
+ method: method,
171
247
  headers: headers,
172
- agent: agent,
173
248
  agents: { http: config.httpAgent, https: config.httpsAgent },
174
- auth: auth
249
+ auth: auth,
250
+ protocol: protocol,
251
+ beforeRedirect: dispatchBeforeRedirect,
252
+ beforeRedirects: {}
175
253
  };
176
254
 
177
255
  if (config.socketPath) {
@@ -179,79 +257,31 @@ module.exports = function httpAdapter(config) {
179
257
  } else {
180
258
  options.hostname = parsed.hostname;
181
259
  options.port = parsed.port;
182
- }
183
-
184
- var proxy = config.proxy;
185
- if (!proxy && proxy !== false) {
186
- var proxyEnv = protocol.slice(0, -1) + '_proxy';
187
- var proxyUrl = process.env[proxyEnv] || process.env[proxyEnv.toUpperCase()];
188
- if (proxyUrl) {
189
- var parsedProxyUrl = url.parse(proxyUrl);
190
- var noProxyEnv = process.env.no_proxy || process.env.NO_PROXY;
191
- var shouldProxy = true;
192
-
193
- if (noProxyEnv) {
194
- var noProxy = noProxyEnv.split(',').map(function trim(s) {
195
- return s.trim();
196
- });
197
-
198
- shouldProxy = !noProxy.some(function proxyMatch(proxyElement) {
199
- if (!proxyElement) {
200
- return false;
201
- }
202
- if (proxyElement === '*') {
203
- return true;
204
- }
205
- if (proxyElement[0] === '.' &&
206
- parsed.hostname.substr(parsed.hostname.length - proxyElement.length) === proxyElement) {
207
- return true;
208
- }
209
-
210
- return parsed.hostname === proxyElement;
211
- });
212
- }
213
-
214
- if (shouldProxy) {
215
- proxy = {
216
- host: parsedProxyUrl.hostname,
217
- port: parsedProxyUrl.port,
218
- protocol: parsedProxyUrl.protocol
219
- };
220
-
221
- if (parsedProxyUrl.auth) {
222
- var proxyUrlAuth = parsedProxyUrl.auth.split(':');
223
- proxy.auth = {
224
- username: proxyUrlAuth[0],
225
- password: proxyUrlAuth[1]
226
- };
227
- }
228
- }
229
- }
230
- }
231
-
232
- if (proxy) {
233
- options.headers.host = parsed.hostname + (parsed.port ? ':' + parsed.port : '');
234
- setProxy(options, proxy, protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path);
260
+ setProxy(options, config.proxy, protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path);
235
261
  }
236
262
 
237
263
  var transport;
238
- var isHttpsProxy = isHttpsRequest && (proxy ? isHttps.test(proxy.protocol) : true);
264
+ var isHttpsRequest = isHttps.test(options.protocol);
265
+ options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;
239
266
  if (config.transport) {
240
267
  transport = config.transport;
241
268
  } else if (config.maxRedirects === 0) {
242
- transport = isHttpsProxy ? https : http;
269
+ transport = isHttpsRequest ? https : http;
243
270
  } else {
244
271
  if (config.maxRedirects) {
245
272
  options.maxRedirects = config.maxRedirects;
246
273
  }
247
274
  if (config.beforeRedirect) {
248
- options.beforeRedirect = config.beforeRedirect;
275
+ options.beforeRedirects.config = config.beforeRedirect;
249
276
  }
250
- transport = isHttpsProxy ? httpsFollow : httpFollow;
277
+ transport = isHttpsRequest ? httpsFollow : httpFollow;
251
278
  }
252
279
 
253
280
  if (config.maxBodyLength > -1) {
254
281
  options.maxBodyLength = config.maxBodyLength;
282
+ } else {
283
+ // follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited
284
+ options.maxBodyLength = Infinity;
255
285
  }
256
286
 
257
287
  if (config.insecureHTTPParser) {
@@ -263,21 +293,26 @@ module.exports = function httpAdapter(config) {
263
293
  if (req.aborted) return;
264
294
 
265
295
  // uncompress the response body transparently if required
266
- var stream = res;
296
+ var responseStream = res;
267
297
 
268
298
  // return the last request in case of redirects
269
299
  var lastRequest = res.req || req;
270
300
 
301
+ // if decompress disabled we should not decompress
302
+ if (config.decompress !== false) {
303
+ // if no content, but headers still say that it is encoded,
304
+ // remove the header not confuse downstream operations
305
+ if (data && data.length === 0 && res.headers['content-encoding']) {
306
+ delete res.headers['content-encoding'];
307
+ }
271
308
 
272
- // if no content, is HEAD request or decompress disabled we should not decompress
273
- if (res.statusCode !== 204 && lastRequest.method !== 'HEAD' && config.decompress !== false) {
274
309
  switch (res.headers['content-encoding']) {
275
310
  /*eslint default-case:0*/
276
311
  case 'gzip':
277
312
  case 'compress':
278
313
  case 'deflate':
279
- // add the unzipper to the body stream processing pipeline
280
- stream = stream.pipe(zlib.createUnzip());
314
+ // add the unzipper to the body stream processing pipeline
315
+ responseStream = responseStream.pipe(zlib.createUnzip());
281
316
 
282
317
  // remove the content-encoding in order to not confuse downstream operations
283
318
  delete res.headers['content-encoding'];
@@ -293,31 +328,31 @@ module.exports = function httpAdapter(config) {
293
328
  request: lastRequest
294
329
  };
295
330
 
296
- if (config.responseType === 'stream') {
297
- response.data = stream;
331
+ if (responseType === 'stream') {
332
+ response.data = responseStream;
298
333
  settle(resolve, reject, response);
299
334
  } else {
300
335
  var responseBuffer = [];
301
336
  var totalResponseBytes = 0;
302
- stream.on('data', function handleStreamData(chunk) {
337
+ responseStream.on('data', function handleStreamData(chunk) {
303
338
  responseBuffer.push(chunk);
304
339
  totalResponseBytes += chunk.length;
305
340
 
306
341
  // make sure the content length is not over the maxContentLength if specified
307
342
  if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) {
308
- // stream.destoy() emit aborted event before calling reject() on Node.js v16
343
+ // stream.destroy() emit aborted event before calling reject() on Node.js v16
309
344
  rejected = true;
310
- stream.destroy();
345
+ responseStream.destroy();
311
346
  reject(new AxiosError('maxContentLength size of ' + config.maxContentLength + ' exceeded',
312
347
  AxiosError.ERR_BAD_RESPONSE, config, lastRequest));
313
348
  }
314
349
  });
315
350
 
316
- stream.on('aborted', function handlerStreamAborted() {
351
+ responseStream.on('aborted', function handlerStreamAborted() {
317
352
  if (rejected) {
318
353
  return;
319
354
  }
320
- stream.destroy();
355
+ responseStream.destroy();
321
356
  reject(new AxiosError(
322
357
  'maxContentLength size of ' + config.maxContentLength + ' exceeded',
323
358
  AxiosError.ERR_BAD_RESPONSE,
@@ -326,17 +361,17 @@ module.exports = function httpAdapter(config) {
326
361
  ));
327
362
  });
328
363
 
329
- stream.on('error', function handleStreamError(err) {
364
+ responseStream.on('error', function handleStreamError(err) {
330
365
  if (req.aborted) return;
331
366
  reject(AxiosError.from(err, null, config, lastRequest));
332
367
  });
333
368
 
334
- stream.on('end', function handleStreamEnd() {
369
+ responseStream.on('end', function handleStreamEnd() {
335
370
  try {
336
371
  var responseData = responseBuffer.length === 1 ? responseBuffer[0] : Buffer.concat(responseBuffer);
337
- if (config.responseType !== 'arraybuffer') {
338
- responseData = responseData.toString(config.responseEncoding);
339
- if (!config.responseEncoding || config.responseEncoding === 'utf8') {
372
+ if (responseType !== 'arraybuffer') {
373
+ responseData = responseData.toString(responseEncoding);
374
+ if (!responseEncoding || responseEncoding === 'utf8') {
340
375
  responseData = utils.stripBOM(responseData);
341
376
  }
342
377
  }
@@ -381,13 +416,17 @@ module.exports = function httpAdapter(config) {
381
416
  // Sometime, the response will be very slow, and does not respond, the connect event will be block by event loop system.
382
417
  // And timer callback will be fired, and abort() will be invoked before connection, then get "socket hang up" and code ECONNRESET.
383
418
  // At this time, if we have a large number of request, nodejs will hang up some socket on background. and the number will up and up.
384
- // And then these socket which be hang up will devoring CPU little by little.
419
+ // And then these socket which be hang up will devouring CPU little by little.
385
420
  // ClientRequest.setTimeout will be fired on the specify milliseconds, and can make sure that abort() will be fired after connect.
386
421
  req.setTimeout(timeout, function handleRequestTimeout() {
387
422
  req.abort();
423
+ var timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded';
388
424
  var transitional = config.transitional || transitionalDefaults;
425
+ if (config.timeoutErrorMessage) {
426
+ timeoutErrorMessage = config.timeoutErrorMessage;
427
+ }
389
428
  reject(new AxiosError(
390
- 'timeout of ' + timeout + 'ms exceeded',
429
+ timeoutErrorMessage,
391
430
  transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,
392
431
  config,
393
432
  req
@@ -402,7 +441,7 @@ module.exports = function httpAdapter(config) {
402
441
  if (req.aborted) return;
403
442
 
404
443
  req.abort();
405
- reject(!cancel || (cancel && cancel.type) ? new CanceledError() : cancel);
444
+ reject(!cancel || cancel.type ? new CanceledError(null, config, req) : cancel);
406
445
  };
407
446
 
408
447
  config.cancelToken && config.cancelToken.subscribe(onCanceled);
@@ -10,12 +10,15 @@ var isURLSameOrigin = require('./../helpers/isURLSameOrigin');
10
10
  var transitionalDefaults = require('../defaults/transitional');
11
11
  var AxiosError = require('../core/AxiosError');
12
12
  var CanceledError = require('../cancel/CanceledError');
13
+ var parseProtocol = require('../helpers/parseProtocol');
14
+ var platform = require('../platform');
13
15
 
14
16
  module.exports = function xhrAdapter(config) {
15
17
  return new Promise(function dispatchXhrRequest(resolve, reject) {
16
18
  var requestData = config.data;
17
19
  var requestHeaders = config.headers;
18
20
  var responseType = config.responseType;
21
+ var withXSRFToken = config.withXSRFToken;
19
22
  var onCanceled;
20
23
  function done() {
21
24
  if (config.cancelToken) {
@@ -27,6 +30,10 @@ module.exports = function xhrAdapter(config) {
27
30
  }
28
31
  }
29
32
 
33
+ if (utils.isFormData(requestData) && utils.isStandardBrowserEnv()) {
34
+ delete requestHeaders['Content-Type']; // Let the browser set it
35
+ }
36
+
30
37
  var request = new XMLHttpRequest();
31
38
 
32
39
  // HTTP basic authentication
@@ -111,7 +118,7 @@ module.exports = function xhrAdapter(config) {
111
118
  request.onerror = function handleError() {
112
119
  // Real errors are hidden from us by the browser
113
120
  // onerror should only fire if it's a network error
114
- reject(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request, request));
121
+ reject(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request));
115
122
 
116
123
  // Clean up request
117
124
  request = null;
@@ -139,12 +146,13 @@ module.exports = function xhrAdapter(config) {
139
146
  // Specifically not if we're in a web worker, or react-native.
140
147
  if (utils.isStandardBrowserEnv()) {
141
148
  // Add xsrf header
142
- var xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath)) && config.xsrfCookieName ?
143
- cookies.read(config.xsrfCookieName) :
144
- undefined;
145
-
146
- if (xsrfValue) {
147
- requestHeaders[config.xsrfHeaderName] = xsrfValue;
149
+ withXSRFToken && utils.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(config));
150
+ if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(fullPath))) {
151
+ // Add xsrf header
152
+ var xsrfValue = config.xsrfHeaderName && config.xsrfCookieName && cookies.read(config.xsrfCookieName);
153
+ if (xsrfValue) {
154
+ requestHeaders[config.xsrfHeaderName] = xsrfValue;
155
+ }
148
156
  }
149
157
  }
150
158
 
@@ -188,7 +196,7 @@ module.exports = function xhrAdapter(config) {
188
196
  if (!request) {
189
197
  return;
190
198
  }
191
- reject(!cancel || (cancel && cancel.type) ? new CanceledError() : cancel);
199
+ reject(!cancel || cancel.type ? new CanceledError(null, config, req) : cancel);
192
200
  request.abort();
193
201
  request = null;
194
202
  };
@@ -199,14 +207,14 @@ module.exports = function xhrAdapter(config) {
199
207
  }
200
208
  }
201
209
 
202
- if (!requestData) {
210
+ // false, 0 (zero number), and '' (empty string) are valid JSON values
211
+ if (!requestData && requestData !== false && requestData !== 0 && requestData !== '') {
203
212
  requestData = null;
204
213
  }
205
214
 
206
- var tokens = fullPath.split(':', 2);
207
- var protocol = tokens.length > 1 && tokens[0];
215
+ var protocol = parseProtocol(fullPath);
208
216
 
209
- if (protocol && [ 'http', 'https', 'file' ].indexOf(protocol) === -1) {
217
+ if (protocol && platform.protocols.indexOf(protocol) === -1) {
210
218
  reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config));
211
219
  return;
212
220
  }
package/lib/axios.js CHANGED
@@ -5,7 +5,7 @@ var bind = require('./helpers/bind');
5
5
  var Axios = require('./core/Axios');
6
6
  var mergeConfig = require('./core/mergeConfig');
7
7
  var defaults = require('./defaults');
8
-
8
+ var formDataToJSON = require('./helpers/formDataToJSON');
9
9
  /**
10
10
  * Create an instance of Axios
11
11
  *
@@ -58,6 +58,10 @@ axios.spread = require('./helpers/spread');
58
58
  // Expose isAxiosError
59
59
  axios.isAxiosError = require('./helpers/isAxiosError');
60
60
 
61
+ axios.formToJSON = function(thing) {
62
+ return formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);
63
+ };
64
+
61
65
  module.exports = axios;
62
66
 
63
67
  // Allow use of default import syntax in TypeScript
@@ -25,10 +25,9 @@ function CancelToken(executor) {
25
25
  this.promise.then(function(cancel) {
26
26
  if (!token._listeners) return;
27
27
 
28
- var i;
29
- var l = token._listeners.length;
28
+ var i = token._listeners.length;
30
29
 
31
- for (i = 0; i < l; i++) {
30
+ while (i-- > 0) {
32
31
  token._listeners[i](cancel);
33
32
  }
34
33
  token._listeners = null;
@@ -50,13 +49,13 @@ function CancelToken(executor) {
50
49
  return promise;
51
50
  };
52
51
 
53
- executor(function cancel(message) {
52
+ executor(function cancel(message, config, request) {
54
53
  if (token.reason) {
55
54
  // Cancellation has already been requested
56
55
  return;
57
56
  }
58
57
 
59
- token.reason = new CanceledError(message);
58
+ token.reason = new CanceledError(message, config, request);
60
59
  resolvePromise(token.reason);
61
60
  });
62
61
  }
@@ -8,10 +8,12 @@ var utils = require('../utils');
8
8
  *
9
9
  * @class
10
10
  * @param {string=} message The message.
11
+ * @param {Object=} config The config.
12
+ * @param {Object=} request The request.
11
13
  */
12
- function CanceledError(message) {
14
+ function CanceledError(message, config, request) {
13
15
  // eslint-disable-next-line no-eq-null,eqeqeq
14
- AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED);
16
+ AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request);
15
17
  this.name = 'CanceledError';
16
18
  }
17
19
 
package/lib/core/Axios.js CHANGED
@@ -25,7 +25,8 @@ function Axios(instanceConfig) {
25
25
  /**
26
26
  * Dispatch a request
27
27
  *
28
- * @param {Object} config The config specific for this request (merged with this.defaults)
28
+ * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults)
29
+ * @param {?Object} config
29
30
  */
30
31
  Axios.prototype.request = function request(configOrUrl, config) {
31
32
  /*eslint no-param-reassign:0*/
@@ -58,6 +59,10 @@ Axios.prototype.request = function request(configOrUrl, config) {
58
59
  }, false);
59
60
  }
60
61
 
62
+ var paramsSerializer = config.paramsSerializer;
63
+
64
+ utils.isFunction(paramsSerializer) && (config.paramsSerializer = {serialize: paramsSerializer});
65
+
61
66
  // filter out skipped interceptors
62
67
  var requestInterceptorChain = [];
63
68
  var synchronousRequestInterceptors = true;
@@ -14,6 +14,13 @@ var utils = require('../utils');
14
14
  */
15
15
  function AxiosError(message, code, config, request, response) {
16
16
  Error.call(this);
17
+
18
+ if (Error.captureStackTrace) {
19
+ Error.captureStackTrace(this, this.constructor);
20
+ } else {
21
+ this.stack = (new Error()).stack;
22
+ }
23
+
17
24
  this.message = message;
18
25
  this.name = 'AxiosError';
19
26
  code && (this.code = code);
@@ -57,7 +64,9 @@ var descriptors = {};
57
64
  'ERR_DEPRECATED',
58
65
  'ERR_BAD_RESPONSE',
59
66
  'ERR_BAD_REQUEST',
60
- 'ERR_CANCELED'
67
+ 'ERR_CANCELED',
68
+ 'ERR_NOT_SUPPORT',
69
+ 'ERR_INVALID_URL'
61
70
  // eslint-disable-next-line func-names
62
71
  ].forEach(function(code) {
63
72
  descriptors[code] = {value: code};
@@ -76,6 +85,8 @@ AxiosError.from = function(error, code, config, request, response, customProps)
76
85
 
77
86
  AxiosError.call(axiosError, error.message, code, config, request, response);
78
87
 
88
+ axiosError.cause = error;
89
+
79
90
  axiosError.name = error.name;
80
91
 
81
92
  customProps && Object.assign(axiosError, customProps);
@@ -35,6 +35,15 @@ InterceptorManager.prototype.eject = function eject(id) {
35
35
  }
36
36
  };
37
37
 
38
+ /**
39
+ * Clear all interceptors from the stack
40
+ */
41
+ InterceptorManager.prototype.clear = function clear() {
42
+ if (this.handlers) {
43
+ this.handlers = [];
44
+ }
45
+ };
46
+
38
47
  /**
39
48
  * Iterate over all the registered interceptors
40
49
  *
@@ -5,6 +5,7 @@ var transformData = require('./transformData');
5
5
  var isCancel = require('../cancel/isCancel');
6
6
  var defaults = require('../defaults');
7
7
  var CanceledError = require('../cancel/CanceledError');
8
+ var normalizeHeaderName = require('../helpers/normalizeHeaderName');
8
9
 
9
10
  /**
10
11
  * Throws a `CanceledError` if cancellation has been requested.
@@ -36,9 +37,13 @@ module.exports = function dispatchRequest(config) {
36
37
  config,
37
38
  config.data,
38
39
  config.headers,
40
+ null,
39
41
  config.transformRequest
40
42
  );
41
43
 
44
+ normalizeHeaderName(config.headers, 'Accept');
45
+ normalizeHeaderName(config.headers, 'Content-Type');
46
+
42
47
  // Flatten headers
43
48
  config.headers = utils.merge(
44
49
  config.headers.common || {},
@@ -63,6 +68,7 @@ module.exports = function dispatchRequest(config) {
63
68
  config,
64
69
  response.data,
65
70
  response.headers,
71
+ response.status,
66
72
  config.transformResponse
67
73
  );
68
74
 
@@ -77,6 +83,7 @@ module.exports = function dispatchRequest(config) {
77
83
  config,
78
84
  reason.response.data,
79
85
  reason.response.headers,
86
+ reason.response.status,
80
87
  config.transformResponse
81
88
  );
82
89
  }