mirror of
				https://scm.univ-tours.fr/22107988t/rappaurio-sae501_502.git
				synced 2025-11-04 10:25:21 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			669 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			669 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						|
 | 
						|
import utils from './../utils.js';
 | 
						|
import settle from './../core/settle.js';
 | 
						|
import buildFullPath from '../core/buildFullPath.js';
 | 
						|
import buildURL from './../helpers/buildURL.js';
 | 
						|
import {getProxyForUrl} from 'proxy-from-env';
 | 
						|
import http from 'http';
 | 
						|
import https from 'https';
 | 
						|
import util from 'util';
 | 
						|
import followRedirects from 'follow-redirects';
 | 
						|
import zlib from 'zlib';
 | 
						|
import {VERSION} from '../env/data.js';
 | 
						|
import transitionalDefaults from '../defaults/transitional.js';
 | 
						|
import AxiosError from '../core/AxiosError.js';
 | 
						|
import CanceledError from '../cancel/CanceledError.js';
 | 
						|
import platform from '../platform/index.js';
 | 
						|
import fromDataURI from '../helpers/fromDataURI.js';
 | 
						|
import stream from 'stream';
 | 
						|
import AxiosHeaders from '../core/AxiosHeaders.js';
 | 
						|
import AxiosTransformStream from '../helpers/AxiosTransformStream.js';
 | 
						|
import EventEmitter from 'events';
 | 
						|
import formDataToStream from "../helpers/formDataToStream.js";
 | 
						|
import readBlob from "../helpers/readBlob.js";
 | 
						|
import ZlibHeaderTransformStream from '../helpers/ZlibHeaderTransformStream.js';
 | 
						|
import callbackify from "../helpers/callbackify.js";
 | 
						|
 | 
						|
const zlibOptions = {
 | 
						|
  flush: zlib.constants.Z_SYNC_FLUSH,
 | 
						|
  finishFlush: zlib.constants.Z_SYNC_FLUSH
 | 
						|
};
 | 
						|
 | 
						|
const brotliOptions = {
 | 
						|
  flush: zlib.constants.BROTLI_OPERATION_FLUSH,
 | 
						|
  finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH
 | 
						|
}
 | 
						|
 | 
						|
const isBrotliSupported = utils.isFunction(zlib.createBrotliDecompress);
 | 
						|
 | 
						|
const {http: httpFollow, https: httpsFollow} = followRedirects;
 | 
						|
 | 
						|
const isHttps = /https:?/;
 | 
						|
 | 
						|
const supportedProtocols = platform.protocols.map(protocol => {
 | 
						|
  return protocol + ':';
 | 
						|
});
 | 
						|
 | 
						|
/**
 | 
						|
 * If the proxy or config beforeRedirects functions are defined, call them with the options
 | 
						|
 * object.
 | 
						|
 *
 | 
						|
 * @param {Object<string, any>} options - The options object that was passed to the request.
 | 
						|
 *
 | 
						|
 * @returns {Object<string, any>}
 | 
						|
 */
 | 
						|
function dispatchBeforeRedirect(options) {
 | 
						|
  if (options.beforeRedirects.proxy) {
 | 
						|
    options.beforeRedirects.proxy(options);
 | 
						|
  }
 | 
						|
  if (options.beforeRedirects.config) {
 | 
						|
    options.beforeRedirects.config(options);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * If the proxy or config afterRedirects functions are defined, call them with the options
 | 
						|
 *
 | 
						|
 * @param {http.ClientRequestArgs} options
 | 
						|
 * @param {AxiosProxyConfig} configProxy configuration from Axios options object
 | 
						|
 * @param {string} location
 | 
						|
 *
 | 
						|
 * @returns {http.ClientRequestArgs}
 | 
						|
 */
 | 
						|
function setProxy(options, configProxy, location) {
 | 
						|
  let proxy = configProxy;
 | 
						|
  if (!proxy && proxy !== false) {
 | 
						|
    const proxyUrl = getProxyForUrl(location);
 | 
						|
    if (proxyUrl) {
 | 
						|
      proxy = new URL(proxyUrl);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (proxy) {
 | 
						|
    // Basic proxy authorization
 | 
						|
    if (proxy.username) {
 | 
						|
      proxy.auth = (proxy.username || '') + ':' + (proxy.password || '');
 | 
						|
    }
 | 
						|
 | 
						|
    if (proxy.auth) {
 | 
						|
      // Support proxy auth object form
 | 
						|
      if (proxy.auth.username || proxy.auth.password) {
 | 
						|
        proxy.auth = (proxy.auth.username || '') + ':' + (proxy.auth.password || '');
 | 
						|
      }
 | 
						|
      const base64 = Buffer
 | 
						|
        .from(proxy.auth, 'utf8')
 | 
						|
        .toString('base64');
 | 
						|
      options.headers['Proxy-Authorization'] = 'Basic ' + base64;
 | 
						|
    }
 | 
						|
 | 
						|
    options.headers.host = options.hostname + (options.port ? ':' + options.port : '');
 | 
						|
    const proxyHost = proxy.hostname || proxy.host;
 | 
						|
    options.hostname = proxyHost;
 | 
						|
    // Replace 'host' since options is not a URL object
 | 
						|
    options.host = proxyHost;
 | 
						|
    options.port = proxy.port;
 | 
						|
    options.path = location;
 | 
						|
    if (proxy.protocol) {
 | 
						|
      options.protocol = proxy.protocol.includes(':') ? proxy.protocol : `${proxy.protocol}:`;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  options.beforeRedirects.proxy = function beforeRedirect(redirectOptions) {
 | 
						|
    // Configure proxy for redirected request, passing the original config proxy to apply
 | 
						|
    // the exact same logic as if the redirected request was performed by axios directly.
 | 
						|
    setProxy(redirectOptions, configProxy, redirectOptions.href);
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
const isHttpAdapterSupported = typeof process !== 'undefined' && utils.kindOf(process) === 'process';
 | 
						|
 | 
						|
// temporary hotfix
 | 
						|
 | 
						|
const wrapAsync = (asyncExecutor) => {
 | 
						|
  return new Promise((resolve, reject) => {
 | 
						|
    let onDone;
 | 
						|
    let isDone;
 | 
						|
 | 
						|
    const done = (value, isRejected) => {
 | 
						|
      if (isDone) return;
 | 
						|
      isDone = true;
 | 
						|
      onDone && onDone(value, isRejected);
 | 
						|
    }
 | 
						|
 | 
						|
    const _resolve = (value) => {
 | 
						|
      done(value);
 | 
						|
      resolve(value);
 | 
						|
    };
 | 
						|
 | 
						|
    const _reject = (reason) => {
 | 
						|
      done(reason, true);
 | 
						|
      reject(reason);
 | 
						|
    }
 | 
						|
 | 
						|
    asyncExecutor(_resolve, _reject, (onDoneHandler) => (onDone = onDoneHandler)).catch(_reject);
 | 
						|
  })
 | 
						|
};
 | 
						|
 | 
						|
/*eslint consistent-return:0*/
 | 
						|
export default isHttpAdapterSupported && function httpAdapter(config) {
 | 
						|
  return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {
 | 
						|
    let {data, lookup, family} = config;
 | 
						|
    const {responseType, responseEncoding} = config;
 | 
						|
    const method = config.method.toUpperCase();
 | 
						|
    let isDone;
 | 
						|
    let rejected = false;
 | 
						|
    let req;
 | 
						|
 | 
						|
    if (lookup && utils.isAsyncFn(lookup)) {
 | 
						|
      lookup = callbackify(lookup, (entry) => {
 | 
						|
        if(utils.isString(entry)) {
 | 
						|
          entry = [entry, entry.indexOf('.') < 0 ? 6 : 4]
 | 
						|
        } else if (!utils.isArray(entry)) {
 | 
						|
          throw new TypeError('lookup async function must return an array [ip: string, family: number]]')
 | 
						|
        }
 | 
						|
        return entry;
 | 
						|
      })
 | 
						|
    }
 | 
						|
 | 
						|
    // temporary internal emitter until the AxiosRequest class will be implemented
 | 
						|
    const emitter = new EventEmitter();
 | 
						|
 | 
						|
    const onFinished = () => {
 | 
						|
      if (config.cancelToken) {
 | 
						|
        config.cancelToken.unsubscribe(abort);
 | 
						|
      }
 | 
						|
 | 
						|
      if (config.signal) {
 | 
						|
        config.signal.removeEventListener('abort', abort);
 | 
						|
      }
 | 
						|
 | 
						|
      emitter.removeAllListeners();
 | 
						|
    }
 | 
						|
 | 
						|
    onDone((value, isRejected) => {
 | 
						|
      isDone = true;
 | 
						|
      if (isRejected) {
 | 
						|
        rejected = true;
 | 
						|
        onFinished();
 | 
						|
      }
 | 
						|
    });
 | 
						|
 | 
						|
    function abort(reason) {
 | 
						|
      emitter.emit('abort', !reason || reason.type ? new CanceledError(null, config, req) : reason);
 | 
						|
    }
 | 
						|
 | 
						|
    emitter.once('abort', reject);
 | 
						|
 | 
						|
    if (config.cancelToken || config.signal) {
 | 
						|
      config.cancelToken && config.cancelToken.subscribe(abort);
 | 
						|
      if (config.signal) {
 | 
						|
        config.signal.aborted ? abort() : config.signal.addEventListener('abort', abort);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    // Parse url
 | 
						|
    const fullPath = buildFullPath(config.baseURL, config.url);
 | 
						|
    const parsed = new URL(fullPath, 'http://localhost');
 | 
						|
    const protocol = parsed.protocol || supportedProtocols[0];
 | 
						|
 | 
						|
    if (protocol === 'data:') {
 | 
						|
      let convertedData;
 | 
						|
 | 
						|
      if (method !== 'GET') {
 | 
						|
        return settle(resolve, reject, {
 | 
						|
          status: 405,
 | 
						|
          statusText: 'method not allowed',
 | 
						|
          headers: {},
 | 
						|
          config
 | 
						|
        });
 | 
						|
      }
 | 
						|
 | 
						|
      try {
 | 
						|
        convertedData = fromDataURI(config.url, responseType === 'blob', {
 | 
						|
          Blob: config.env && config.env.Blob
 | 
						|
        });
 | 
						|
      } catch (err) {
 | 
						|
        throw AxiosError.from(err, AxiosError.ERR_BAD_REQUEST, config);
 | 
						|
      }
 | 
						|
 | 
						|
      if (responseType === 'text') {
 | 
						|
        convertedData = convertedData.toString(responseEncoding);
 | 
						|
 | 
						|
        if (!responseEncoding || responseEncoding === 'utf8') {
 | 
						|
          convertedData = utils.stripBOM(convertedData);
 | 
						|
        }
 | 
						|
      } else if (responseType === 'stream') {
 | 
						|
        convertedData = stream.Readable.from(convertedData);
 | 
						|
      }
 | 
						|
 | 
						|
      return settle(resolve, reject, {
 | 
						|
        data: convertedData,
 | 
						|
        status: 200,
 | 
						|
        statusText: 'OK',
 | 
						|
        headers: new AxiosHeaders(),
 | 
						|
        config
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    if (supportedProtocols.indexOf(protocol) === -1) {
 | 
						|
      return reject(new AxiosError(
 | 
						|
        'Unsupported protocol ' + protocol,
 | 
						|
        AxiosError.ERR_BAD_REQUEST,
 | 
						|
        config
 | 
						|
      ));
 | 
						|
    }
 | 
						|
 | 
						|
    const headers = AxiosHeaders.from(config.headers).normalize();
 | 
						|
 | 
						|
    // Set User-Agent (required by some servers)
 | 
						|
    // See https://github.com/axios/axios/issues/69
 | 
						|
    // User-Agent is specified; handle case where no UA header is desired
 | 
						|
    // Only set header if it hasn't been set in config
 | 
						|
    headers.set('User-Agent', 'axios/' + VERSION, false);
 | 
						|
 | 
						|
    const onDownloadProgress = config.onDownloadProgress;
 | 
						|
    const onUploadProgress = config.onUploadProgress;
 | 
						|
    const maxRate = config.maxRate;
 | 
						|
    let maxUploadRate = undefined;
 | 
						|
    let maxDownloadRate = undefined;
 | 
						|
 | 
						|
    // support for spec compliant FormData objects
 | 
						|
    if (utils.isSpecCompliantForm(data)) {
 | 
						|
      const userBoundary = headers.getContentType(/boundary=([-_\w\d]{10,70})/i);
 | 
						|
 | 
						|
      data = formDataToStream(data, (formHeaders) => {
 | 
						|
        headers.set(formHeaders);
 | 
						|
      }, {
 | 
						|
        tag: `axios-${VERSION}-boundary`,
 | 
						|
        boundary: userBoundary && userBoundary[1] || undefined
 | 
						|
      });
 | 
						|
      // support for https://www.npmjs.com/package/form-data api
 | 
						|
    } else if (utils.isFormData(data) && utils.isFunction(data.getHeaders)) {
 | 
						|
      headers.set(data.getHeaders());
 | 
						|
 | 
						|
      if (!headers.hasContentLength()) {
 | 
						|
        try {
 | 
						|
          const knownLength = await util.promisify(data.getLength).call(data);
 | 
						|
          Number.isFinite(knownLength) && knownLength >= 0 && headers.setContentLength(knownLength);
 | 
						|
          /*eslint no-empty:0*/
 | 
						|
        } catch (e) {
 | 
						|
        }
 | 
						|
      }
 | 
						|
    } else if (utils.isBlob(data)) {
 | 
						|
      data.size && headers.setContentType(data.type || 'application/octet-stream');
 | 
						|
      headers.setContentLength(data.size || 0);
 | 
						|
      data = stream.Readable.from(readBlob(data));
 | 
						|
    } else if (data && !utils.isStream(data)) {
 | 
						|
      if (Buffer.isBuffer(data)) {
 | 
						|
        // Nothing to do...
 | 
						|
      } else if (utils.isArrayBuffer(data)) {
 | 
						|
        data = Buffer.from(new Uint8Array(data));
 | 
						|
      } else if (utils.isString(data)) {
 | 
						|
        data = Buffer.from(data, 'utf-8');
 | 
						|
      } else {
 | 
						|
        return reject(new AxiosError(
 | 
						|
          'Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream',
 | 
						|
          AxiosError.ERR_BAD_REQUEST,
 | 
						|
          config
 | 
						|
        ));
 | 
						|
      }
 | 
						|
 | 
						|
      // Add Content-Length header if data exists
 | 
						|
      headers.setContentLength(data.length, false);
 | 
						|
 | 
						|
      if (config.maxBodyLength > -1 && data.length > config.maxBodyLength) {
 | 
						|
        return reject(new AxiosError(
 | 
						|
          'Request body larger than maxBodyLength limit',
 | 
						|
          AxiosError.ERR_BAD_REQUEST,
 | 
						|
          config
 | 
						|
        ));
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    const contentLength = utils.toFiniteNumber(headers.getContentLength());
 | 
						|
 | 
						|
    if (utils.isArray(maxRate)) {
 | 
						|
      maxUploadRate = maxRate[0];
 | 
						|
      maxDownloadRate = maxRate[1];
 | 
						|
    } else {
 | 
						|
      maxUploadRate = maxDownloadRate = maxRate;
 | 
						|
    }
 | 
						|
 | 
						|
    if (data && (onUploadProgress || maxUploadRate)) {
 | 
						|
      if (!utils.isStream(data)) {
 | 
						|
        data = stream.Readable.from(data, {objectMode: false});
 | 
						|
      }
 | 
						|
 | 
						|
      data = stream.pipeline([data, new AxiosTransformStream({
 | 
						|
        length: contentLength,
 | 
						|
        maxRate: utils.toFiniteNumber(maxUploadRate)
 | 
						|
      })], utils.noop);
 | 
						|
 | 
						|
      onUploadProgress && data.on('progress', progress => {
 | 
						|
        onUploadProgress(Object.assign(progress, {
 | 
						|
          upload: true
 | 
						|
        }));
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    // HTTP basic authentication
 | 
						|
    let auth = undefined;
 | 
						|
    if (config.auth) {
 | 
						|
      const username = config.auth.username || '';
 | 
						|
      const password = config.auth.password || '';
 | 
						|
      auth = username + ':' + password;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!auth && parsed.username) {
 | 
						|
      const urlUsername = parsed.username;
 | 
						|
      const urlPassword = parsed.password;
 | 
						|
      auth = urlUsername + ':' + urlPassword;
 | 
						|
    }
 | 
						|
 | 
						|
    auth && headers.delete('authorization');
 | 
						|
 | 
						|
    let path;
 | 
						|
 | 
						|
    try {
 | 
						|
      path = buildURL(
 | 
						|
        parsed.pathname + parsed.search,
 | 
						|
        config.params,
 | 
						|
        config.paramsSerializer
 | 
						|
      ).replace(/^\?/, '');
 | 
						|
    } catch (err) {
 | 
						|
      const customErr = new Error(err.message);
 | 
						|
      customErr.config = config;
 | 
						|
      customErr.url = config.url;
 | 
						|
      customErr.exists = true;
 | 
						|
      return reject(customErr);
 | 
						|
    }
 | 
						|
 | 
						|
    headers.set(
 | 
						|
      'Accept-Encoding',
 | 
						|
      'gzip, compress, deflate' + (isBrotliSupported ? ', br' : ''), false
 | 
						|
      );
 | 
						|
 | 
						|
    const options = {
 | 
						|
      path,
 | 
						|
      method: method,
 | 
						|
      headers: headers.toJSON(),
 | 
						|
      agents: { http: config.httpAgent, https: config.httpsAgent },
 | 
						|
      auth,
 | 
						|
      protocol,
 | 
						|
      family,
 | 
						|
      beforeRedirect: dispatchBeforeRedirect,
 | 
						|
      beforeRedirects: {}
 | 
						|
    };
 | 
						|
 | 
						|
    // cacheable-lookup integration hotfix
 | 
						|
    !utils.isUndefined(lookup) && (options.lookup = lookup);
 | 
						|
 | 
						|
    if (config.socketPath) {
 | 
						|
      options.socketPath = config.socketPath;
 | 
						|
    } else {
 | 
						|
      options.hostname = parsed.hostname;
 | 
						|
      options.port = parsed.port;
 | 
						|
      setProxy(options, config.proxy, protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path);
 | 
						|
    }
 | 
						|
 | 
						|
    let transport;
 | 
						|
    const isHttpsRequest = isHttps.test(options.protocol);
 | 
						|
    options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;
 | 
						|
    if (config.transport) {
 | 
						|
      transport = config.transport;
 | 
						|
    } else if (config.maxRedirects === 0) {
 | 
						|
      transport = isHttpsRequest ? https : http;
 | 
						|
    } else {
 | 
						|
      if (config.maxRedirects) {
 | 
						|
        options.maxRedirects = config.maxRedirects;
 | 
						|
      }
 | 
						|
      if (config.beforeRedirect) {
 | 
						|
        options.beforeRedirects.config = config.beforeRedirect;
 | 
						|
      }
 | 
						|
      transport = isHttpsRequest ? httpsFollow : httpFollow;
 | 
						|
    }
 | 
						|
 | 
						|
    if (config.maxBodyLength > -1) {
 | 
						|
      options.maxBodyLength = config.maxBodyLength;
 | 
						|
    } else {
 | 
						|
      // follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited
 | 
						|
      options.maxBodyLength = Infinity;
 | 
						|
    }
 | 
						|
 | 
						|
    if (config.insecureHTTPParser) {
 | 
						|
      options.insecureHTTPParser = config.insecureHTTPParser;
 | 
						|
    }
 | 
						|
 | 
						|
    // Create the request
 | 
						|
    req = transport.request(options, function handleResponse(res) {
 | 
						|
      if (req.destroyed) return;
 | 
						|
 | 
						|
      const streams = [res];
 | 
						|
 | 
						|
      const responseLength = +res.headers['content-length'];
 | 
						|
 | 
						|
      if (onDownloadProgress) {
 | 
						|
        const transformStream = new AxiosTransformStream({
 | 
						|
          length: utils.toFiniteNumber(responseLength),
 | 
						|
          maxRate: utils.toFiniteNumber(maxDownloadRate)
 | 
						|
        });
 | 
						|
 | 
						|
        onDownloadProgress && transformStream.on('progress', progress => {
 | 
						|
          onDownloadProgress(Object.assign(progress, {
 | 
						|
            download: true
 | 
						|
          }));
 | 
						|
        });
 | 
						|
 | 
						|
        streams.push(transformStream);
 | 
						|
      }
 | 
						|
 | 
						|
      // decompress the response body transparently if required
 | 
						|
      let responseStream = res;
 | 
						|
 | 
						|
      // return the last request in case of redirects
 | 
						|
      const lastRequest = res.req || req;
 | 
						|
 | 
						|
      // if decompress disabled we should not decompress
 | 
						|
      if (config.decompress !== false && res.headers['content-encoding']) {
 | 
						|
        // if no content, but headers still say that it is encoded,
 | 
						|
        // remove the header not confuse downstream operations
 | 
						|
        if (method === 'HEAD' || res.statusCode === 204) {
 | 
						|
          delete res.headers['content-encoding'];
 | 
						|
        }
 | 
						|
 | 
						|
        switch (res.headers['content-encoding']) {
 | 
						|
        /*eslint default-case:0*/
 | 
						|
        case 'gzip':
 | 
						|
        case 'x-gzip':
 | 
						|
        case 'compress':
 | 
						|
        case 'x-compress':
 | 
						|
          // add the unzipper to the body stream processing pipeline
 | 
						|
          streams.push(zlib.createUnzip(zlibOptions));
 | 
						|
 | 
						|
          // remove the content-encoding in order to not confuse downstream operations
 | 
						|
          delete res.headers['content-encoding'];
 | 
						|
          break;
 | 
						|
        case 'deflate':
 | 
						|
          streams.push(new ZlibHeaderTransformStream());
 | 
						|
 | 
						|
          // add the unzipper to the body stream processing pipeline
 | 
						|
          streams.push(zlib.createUnzip(zlibOptions));
 | 
						|
 | 
						|
          // remove the content-encoding in order to not confuse downstream operations
 | 
						|
          delete res.headers['content-encoding'];
 | 
						|
          break;
 | 
						|
        case 'br':
 | 
						|
          if (isBrotliSupported) {
 | 
						|
            streams.push(zlib.createBrotliDecompress(brotliOptions));
 | 
						|
            delete res.headers['content-encoding'];
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      responseStream = streams.length > 1 ? stream.pipeline(streams, utils.noop) : streams[0];
 | 
						|
 | 
						|
      const offListeners = stream.finished(responseStream, () => {
 | 
						|
        offListeners();
 | 
						|
        onFinished();
 | 
						|
      });
 | 
						|
 | 
						|
      const response = {
 | 
						|
        status: res.statusCode,
 | 
						|
        statusText: res.statusMessage,
 | 
						|
        headers: new AxiosHeaders(res.headers),
 | 
						|
        config,
 | 
						|
        request: lastRequest
 | 
						|
      };
 | 
						|
 | 
						|
      if (responseType === 'stream') {
 | 
						|
        response.data = responseStream;
 | 
						|
        settle(resolve, reject, response);
 | 
						|
      } else {
 | 
						|
        const responseBuffer = [];
 | 
						|
        let totalResponseBytes = 0;
 | 
						|
 | 
						|
        responseStream.on('data', function handleStreamData(chunk) {
 | 
						|
          responseBuffer.push(chunk);
 | 
						|
          totalResponseBytes += chunk.length;
 | 
						|
 | 
						|
          // make sure the content length is not over the maxContentLength if specified
 | 
						|
          if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) {
 | 
						|
            // stream.destroy() emit aborted event before calling reject() on Node.js v16
 | 
						|
            rejected = true;
 | 
						|
            responseStream.destroy();
 | 
						|
            reject(new AxiosError('maxContentLength size of ' + config.maxContentLength + ' exceeded',
 | 
						|
              AxiosError.ERR_BAD_RESPONSE, config, lastRequest));
 | 
						|
          }
 | 
						|
        });
 | 
						|
 | 
						|
        responseStream.on('aborted', function handlerStreamAborted() {
 | 
						|
          if (rejected) {
 | 
						|
            return;
 | 
						|
          }
 | 
						|
 | 
						|
          const err = new AxiosError(
 | 
						|
            'maxContentLength size of ' + config.maxContentLength + ' exceeded',
 | 
						|
            AxiosError.ERR_BAD_RESPONSE,
 | 
						|
            config,
 | 
						|
            lastRequest
 | 
						|
          );
 | 
						|
          responseStream.destroy(err);
 | 
						|
          reject(err);
 | 
						|
        });
 | 
						|
 | 
						|
        responseStream.on('error', function handleStreamError(err) {
 | 
						|
          if (req.destroyed) return;
 | 
						|
          reject(AxiosError.from(err, null, config, lastRequest));
 | 
						|
        });
 | 
						|
 | 
						|
        responseStream.on('end', function handleStreamEnd() {
 | 
						|
          try {
 | 
						|
            let responseData = responseBuffer.length === 1 ? responseBuffer[0] : Buffer.concat(responseBuffer);
 | 
						|
            if (responseType !== 'arraybuffer') {
 | 
						|
              responseData = responseData.toString(responseEncoding);
 | 
						|
              if (!responseEncoding || responseEncoding === 'utf8') {
 | 
						|
                responseData = utils.stripBOM(responseData);
 | 
						|
              }
 | 
						|
            }
 | 
						|
            response.data = responseData;
 | 
						|
          } catch (err) {
 | 
						|
            reject(AxiosError.from(err, null, config, response.request, response));
 | 
						|
          }
 | 
						|
          settle(resolve, reject, response);
 | 
						|
        });
 | 
						|
      }
 | 
						|
 | 
						|
      emitter.once('abort', err => {
 | 
						|
        if (!responseStream.destroyed) {
 | 
						|
          responseStream.emit('error', err);
 | 
						|
          responseStream.destroy();
 | 
						|
        }
 | 
						|
      });
 | 
						|
    });
 | 
						|
 | 
						|
    emitter.once('abort', err => {
 | 
						|
      reject(err);
 | 
						|
      req.destroy(err);
 | 
						|
    });
 | 
						|
 | 
						|
    // Handle errors
 | 
						|
    req.on('error', function handleRequestError(err) {
 | 
						|
      // @todo remove
 | 
						|
      // if (req.aborted && err.code !== AxiosError.ERR_FR_TOO_MANY_REDIRECTS) return;
 | 
						|
      reject(AxiosError.from(err, null, config, req));
 | 
						|
    });
 | 
						|
 | 
						|
    // set tcp keep alive to prevent drop connection by peer
 | 
						|
    req.on('socket', function handleRequestSocket(socket) {
 | 
						|
      // default interval of sending ack packet is 1 minute
 | 
						|
      socket.setKeepAlive(true, 1000 * 60);
 | 
						|
    });
 | 
						|
 | 
						|
    // Handle request timeout
 | 
						|
    if (config.timeout) {
 | 
						|
      // This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types.
 | 
						|
      const timeout = parseInt(config.timeout, 10);
 | 
						|
 | 
						|
      if (isNaN(timeout)) {
 | 
						|
        reject(new AxiosError(
 | 
						|
          'error trying to parse `config.timeout` to int',
 | 
						|
          AxiosError.ERR_BAD_OPTION_VALUE,
 | 
						|
          config,
 | 
						|
          req
 | 
						|
        ));
 | 
						|
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      // Sometime, the response will be very slow, and does not respond, the connect event will be block by event loop system.
 | 
						|
      // And timer callback will be fired, and abort() will be invoked before connection, then get "socket hang up" and code ECONNRESET.
 | 
						|
      // 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.
 | 
						|
      // And then these socket which be hang up will devouring CPU little by little.
 | 
						|
      // ClientRequest.setTimeout will be fired on the specify milliseconds, and can make sure that abort() will be fired after connect.
 | 
						|
      req.setTimeout(timeout, function handleRequestTimeout() {
 | 
						|
        if (isDone) return;
 | 
						|
        let timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded';
 | 
						|
        const transitional = config.transitional || transitionalDefaults;
 | 
						|
        if (config.timeoutErrorMessage) {
 | 
						|
          timeoutErrorMessage = config.timeoutErrorMessage;
 | 
						|
        }
 | 
						|
        reject(new AxiosError(
 | 
						|
          timeoutErrorMessage,
 | 
						|
          transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,
 | 
						|
          config,
 | 
						|
          req
 | 
						|
        ));
 | 
						|
        abort();
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    // Send the request
 | 
						|
    if (utils.isStream(data)) {
 | 
						|
      let ended = false;
 | 
						|
      let errored = false;
 | 
						|
 | 
						|
      data.on('end', () => {
 | 
						|
        ended = true;
 | 
						|
      });
 | 
						|
 | 
						|
      data.once('error', err => {
 | 
						|
        errored = true;
 | 
						|
        req.destroy(err);
 | 
						|
      });
 | 
						|
 | 
						|
      data.on('close', () => {
 | 
						|
        if (!ended && !errored) {
 | 
						|
          abort(new CanceledError('Request stream has been aborted', config, req));
 | 
						|
        }
 | 
						|
      });
 | 
						|
 | 
						|
      data.pipe(req);
 | 
						|
    } else {
 | 
						|
      req.end(data);
 | 
						|
    }
 | 
						|
  });
 | 
						|
}
 | 
						|
 | 
						|
export const __setProxy = setProxy;
 |