CoolFace
Apppublic

opusdev/vector-similarity-api

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes
http.js899 linesDownload Raw Back to adapters
1import utils from '../utils.js';2import settle from '../core/settle.js';3import buildFullPath from '../core/buildFullPath.js';4import buildURL from '../helpers/buildURL.js';5import proxyFromEnv from 'proxy-from-env';6import http from 'http';7import https from 'https';8import http2 from 'http2';9import util from 'util';10import followRedirects from 'follow-redirects';11import zlib from 'zlib';12import {VERSION} from '../env/data.js';13import transitionalDefaults from '../defaults/transitional.js';14import AxiosError from '../core/AxiosError.js';15import CanceledError from '../cancel/CanceledError.js';16import platform from '../platform/index.js';17import fromDataURI from '../helpers/fromDataURI.js';18import stream from 'stream';19import AxiosHeaders from '../core/AxiosHeaders.js';20import AxiosTransformStream from '../helpers/AxiosTransformStream.js';21import {EventEmitter} from 'events';22import formDataToStream from "../helpers/formDataToStream.js";23import readBlob from "../helpers/readBlob.js";24import ZlibHeaderTransformStream from '../helpers/ZlibHeaderTransformStream.js';25import callbackify from "../helpers/callbackify.js";26import {progressEventReducer, progressEventDecorator, asyncDecorator} from "../helpers/progressEventReducer.js";27import estimateDataURLDecodedBytes from '../helpers/estimateDataURLDecodedBytes.js';28 29const zlibOptions = {30  flush: zlib.constants.Z_SYNC_FLUSH,31  finishFlush: zlib.constants.Z_SYNC_FLUSH32};33 34const brotliOptions = {35  flush: zlib.constants.BROTLI_OPERATION_FLUSH,36  finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH37}38 39const isBrotliSupported = utils.isFunction(zlib.createBrotliDecompress);40 41const {http: httpFollow, https: httpsFollow} = followRedirects;42 43const isHttps = /https:?/;44 45const supportedProtocols = platform.protocols.map(protocol => {46  return protocol + ':';47});48 49 50const flushOnFinish = (stream, [throttled, flush]) => {51  stream52    .on('end', flush)53    .on('error', flush);54 55  return throttled;56}57 58class Http2Sessions {59  constructor() {60    this.sessions = Object.create(null);61  }62 63  getSession(authority, options) {64    options = Object.assign({65      sessionTimeout: 100066    }, options);67 68    let authoritySessions = this.sessions[authority];69 70    if (authoritySessions) {71      let len = authoritySessions.length;72 73      for (let i = 0; i < len; i++) {74        const [sessionHandle, sessionOptions] = authoritySessions[i];75        if (!sessionHandle.destroyed && !sessionHandle.closed && util.isDeepStrictEqual(sessionOptions, options)) {76          return sessionHandle;77        }78      }79    }80 81    const session = http2.connect(authority, options);82 83    let removed;84 85    const removeSession = () => {86      if (removed) {87        return;88      }89 90      removed = true;91 92      let entries = authoritySessions, len = entries.length, i = len;93 94      while (i--) {95        if (entries[i][0] === session) {96          if (len === 1) {97            delete this.sessions[authority];98          } else {99            entries.splice(i, 1);100          }101          return;102        }103      }104    };105 106    const originalRequestFn = session.request;107 108    const {sessionTimeout} = options;109 110    if(sessionTimeout != null) {111 112      let timer;113      let streamsCount = 0;114 115      session.request = function () {116        const stream = originalRequestFn.apply(this, arguments);117 118        streamsCount++;119 120        if (timer) {121          clearTimeout(timer);122          timer = null;123        }124 125        stream.once('close', () => {126          if (!--streamsCount) {127            timer = setTimeout(() => {128              timer = null;129              removeSession();130            }, sessionTimeout);131          }132        });133 134        return stream;135      }136    }137 138    session.once('close', removeSession);139 140    let entry = [141        session,142        options143      ];144 145    authoritySessions ? authoritySessions.push(entry) : authoritySessions =  this.sessions[authority] = [entry];146 147    return session;148  }149}150 151const http2Sessions = new Http2Sessions();152 153 154/**155 * If the proxy or config beforeRedirects functions are defined, call them with the options156 * object.157 *158 * @param {Object<string, any>} options - The options object that was passed to the request.159 *160 * @returns {Object<string, any>}161 */162function dispatchBeforeRedirect(options, responseDetails) {163  if (options.beforeRedirects.proxy) {164    options.beforeRedirects.proxy(options);165  }166  if (options.beforeRedirects.config) {167    options.beforeRedirects.config(options, responseDetails);168  }169}170 171/**172 * If the proxy or config afterRedirects functions are defined, call them with the options173 *174 * @param {http.ClientRequestArgs} options175 * @param {AxiosProxyConfig} configProxy configuration from Axios options object176 * @param {string} location177 *178 * @returns {http.ClientRequestArgs}179 */180function setProxy(options, configProxy, location) {181  let proxy = configProxy;182  if (!proxy && proxy !== false) {183    const proxyUrl = proxyFromEnv.getProxyForUrl(location);184    if (proxyUrl) {185      proxy = new URL(proxyUrl);186    }187  }188  if (proxy) {189    // Basic proxy authorization190    if (proxy.username) {191      proxy.auth = (proxy.username || '') + ':' + (proxy.password || '');192    }193 194    if (proxy.auth) {195      // Support proxy auth object form196      const validProxyAuth = Boolean(proxy.auth.username || proxy.auth.password);197 198      if (validProxyAuth) {199        proxy.auth = (proxy.auth.username || '') + ':' + (proxy.auth.password || '');200      } else if (typeof proxy.auth === 'object') {201        throw new AxiosError('Invalid proxy authorization', AxiosError.ERR_BAD_OPTION, { proxy });202      }203 204      const base64 = Buffer.from(proxy.auth, 'utf8').toString('base64');205 206      options.headers['Proxy-Authorization'] = 'Basic ' + base64;207    }208 209    options.headers.host = options.hostname + (options.port ? ':' + options.port : '');210    const proxyHost = proxy.hostname || proxy.host;211    options.hostname = proxyHost;212    // Replace 'host' since options is not a URL object213    options.host = proxyHost;214    options.port = proxy.port;215    options.path = location;216    if (proxy.protocol) {217      options.protocol = proxy.protocol.includes(':') ? proxy.protocol : `${proxy.protocol}:`;218    }219  }220 221  options.beforeRedirects.proxy = function beforeRedirect(redirectOptions) {222    // Configure proxy for redirected request, passing the original config proxy to apply223    // the exact same logic as if the redirected request was performed by axios directly.224    setProxy(redirectOptions, configProxy, redirectOptions.href);225  };226}227 228const isHttpAdapterSupported = typeof process !== 'undefined' && utils.kindOf(process) === 'process';229 230// temporary hotfix231 232const wrapAsync = (asyncExecutor) => {233  return new Promise((resolve, reject) => {234    let onDone;235    let isDone;236 237    const done = (value, isRejected) => {238      if (isDone) return;239      isDone = true;240      onDone && onDone(value, isRejected);241    }242 243    const _resolve = (value) => {244      done(value);245      resolve(value);246    };247 248    const _reject = (reason) => {249      done(reason, true);250      reject(reason);251    }252 253    asyncExecutor(_resolve, _reject, (onDoneHandler) => (onDone = onDoneHandler)).catch(_reject);254  })255};256 257const resolveFamily = ({address, family}) => {258  if (!utils.isString(address)) {259    throw TypeError('address must be a string');260  }261  return ({262    address,263    family: family || (address.indexOf('.') < 0 ? 6 : 4)264  });265}266 267const buildAddressEntry = (address, family) => resolveFamily(utils.isObject(address) ? address : {address, family});268 269const http2Transport = {270  request(options, cb) {271      const authority = options.protocol + '//' + options.hostname + ':' + (options.port ||(options.protocol === 'https:' ? 443 : 80));272 273 274      const {http2Options, headers} = options;275 276      const session = http2Sessions.getSession(authority, http2Options);277 278      const {279        HTTP2_HEADER_SCHEME,280        HTTP2_HEADER_METHOD,281        HTTP2_HEADER_PATH,282        HTTP2_HEADER_STATUS283      } = http2.constants;284 285      const http2Headers = {286        [HTTP2_HEADER_SCHEME]: options.protocol.replace(':', ''),287        [HTTP2_HEADER_METHOD]: options.method,288        [HTTP2_HEADER_PATH]: options.path,289      }290 291      utils.forEach(headers, (header, name) => {292        name.charAt(0) !== ':' && (http2Headers[name] = header);293      });294 295      const req = session.request(http2Headers);296 297      req.once('response', (responseHeaders) => {298        const response = req; //duplex299 300        responseHeaders = Object.assign({}, responseHeaders);301 302        const status = responseHeaders[HTTP2_HEADER_STATUS];303 304        delete responseHeaders[HTTP2_HEADER_STATUS];305 306        response.headers = responseHeaders;307 308        response.statusCode = +status;309 310        cb(response);311      })312 313      return req;314  }315}316 317/*eslint consistent-return:0*/318export default isHttpAdapterSupported && function httpAdapter(config) {319  return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {320    let {data, lookup, family, httpVersion = 1, http2Options} = config;321    const {responseType, responseEncoding} = config;322    const method = config.method.toUpperCase();323    let isDone;324    let rejected = false;325    let req;326 327    httpVersion = +httpVersion;328 329    if (Number.isNaN(httpVersion)) {330      throw TypeError(`Invalid protocol version: '${config.httpVersion}' is not a number`);331    }332 333    if (httpVersion !== 1 && httpVersion !== 2) {334      throw TypeError(`Unsupported protocol version '${httpVersion}'`);335    }336 337    const isHttp2 = httpVersion === 2;338 339    if (lookup) {340      const _lookup = callbackify(lookup, (value) => utils.isArray(value) ? value : [value]);341      // hotfix to support opt.all option which is required for node 20.x342      lookup = (hostname, opt, cb) => {343        _lookup(hostname, opt, (err, arg0, arg1) => {344          if (err) {345            return cb(err);346          }347 348          const addresses = utils.isArray(arg0) ? arg0.map(addr => buildAddressEntry(addr)) : [buildAddressEntry(arg0, arg1)];349 350          opt.all ? cb(err, addresses) : cb(err, addresses[0].address, addresses[0].family);351        });352      }353    }354 355    const abortEmitter = new EventEmitter();356 357    function abort(reason) {358      try {359        abortEmitter.emit('abort', !reason || reason.type ? new CanceledError(null, config, req) : reason);360      } catch(err) {361        console.warn('emit error', err);362      }363    }364 365    abortEmitter.once('abort', reject);366 367    const onFinished = () => {368      if (config.cancelToken) {369        config.cancelToken.unsubscribe(abort);370      }371 372      if (config.signal) {373        config.signal.removeEventListener('abort', abort);374      }375 376      abortEmitter.removeAllListeners();377    }378 379    if (config.cancelToken || config.signal) {380      config.cancelToken && config.cancelToken.subscribe(abort);381      if (config.signal) {382        config.signal.aborted ? abort() : config.signal.addEventListener('abort', abort);383      }384    }385 386    onDone((response, isRejected) => {387      isDone = true;388 389      if (isRejected) {390        rejected = true;391        onFinished();392        return;393      }394 395      const {data} = response;396 397      if (data instanceof stream.Readable || data instanceof stream.Duplex) {398        const offListeners = stream.finished(data, () => {399          offListeners();400          onFinished();401        });402      } else {403        onFinished();404      }405    });406 407 408 409 410 411    // Parse url412    const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);413    const parsed = new URL(fullPath, platform.hasBrowserEnv ? platform.origin : undefined);414    const protocol = parsed.protocol || supportedProtocols[0];415 416    if (protocol === 'data:') {417      // Apply the same semantics as HTTP: only enforce if a finite, non-negative cap is set.418      if (config.maxContentLength > -1) {419        // Use the exact string passed to fromDataURI (config.url); fall back to fullPath if needed.420        const dataUrl = String(config.url || fullPath || '');421        const estimated = estimateDataURLDecodedBytes(dataUrl);422 423        if (estimated > config.maxContentLength) {424          return reject(new AxiosError(425            'maxContentLength size of ' + config.maxContentLength + ' exceeded',426            AxiosError.ERR_BAD_RESPONSE,427            config428          ));429        }430      }431 432      let convertedData;433 434      if (method !== 'GET') {435        return settle(resolve, reject, {436          status: 405,437          statusText: 'method not allowed',438          headers: {},439          config440        });441      }442 443      try {444        convertedData = fromDataURI(config.url, responseType === 'blob', {445          Blob: config.env && config.env.Blob446        });447      } catch (err) {448        throw AxiosError.from(err, AxiosError.ERR_BAD_REQUEST, config);449      }450 451      if (responseType === 'text') {452        convertedData = convertedData.toString(responseEncoding);453 454        if (!responseEncoding || responseEncoding === 'utf8') {455          convertedData = utils.stripBOM(convertedData);456        }457      } else if (responseType === 'stream') {458        convertedData = stream.Readable.from(convertedData);459      }460 461      return settle(resolve, reject, {462        data: convertedData,463        status: 200,464        statusText: 'OK',465        headers: new AxiosHeaders(),466        config467      });468    }469 470    if (supportedProtocols.indexOf(protocol) === -1) {471      return reject(new AxiosError(472        'Unsupported protocol ' + protocol,473        AxiosError.ERR_BAD_REQUEST,474        config475      ));476    }477 478    const headers = AxiosHeaders.from(config.headers).normalize();479 480    // Set User-Agent (required by some servers)481    // See https://github.com/axios/axios/issues/69482    // User-Agent is specified; handle case where no UA header is desired483    // Only set header if it hasn't been set in config484    headers.set('User-Agent', 'axios/' + VERSION, false);485 486    const {onUploadProgress, onDownloadProgress} = config;487    const maxRate = config.maxRate;488    let maxUploadRate = undefined;489    let maxDownloadRate = undefined;490 491    // support for spec compliant FormData objects492    if (utils.isSpecCompliantForm(data)) {493      const userBoundary = headers.getContentType(/boundary=([-_\w\d]{10,70})/i);494 495      data = formDataToStream(data, (formHeaders) => {496        headers.set(formHeaders);497      }, {498        tag: `axios-${VERSION}-boundary`,499        boundary: userBoundary && userBoundary[1] || undefined500      });501      // support for https://www.npmjs.com/package/form-data api502    } else if (utils.isFormData(data) && utils.isFunction(data.getHeaders)) {503      headers.set(data.getHeaders());504 505      if (!headers.hasContentLength()) {506        try {507          const knownLength = await util.promisify(data.getLength).call(data);508          Number.isFinite(knownLength) && knownLength >= 0 && headers.setContentLength(knownLength);509          /*eslint no-empty:0*/510        } catch (e) {511        }512      }513    } else if (utils.isBlob(data) || utils.isFile(data)) {514      data.size && headers.setContentType(data.type || 'application/octet-stream');515      headers.setContentLength(data.size || 0);516      data = stream.Readable.from(readBlob(data));517    } else if (data && !utils.isStream(data)) {518      if (Buffer.isBuffer(data)) {519        // Nothing to do...520      } else if (utils.isArrayBuffer(data)) {521        data = Buffer.from(new Uint8Array(data));522      } else if (utils.isString(data)) {523        data = Buffer.from(data, 'utf-8');524      } else {525        return reject(new AxiosError(526          'Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream',527          AxiosError.ERR_BAD_REQUEST,528          config529        ));530      }531 532      // Add Content-Length header if data exists533      headers.setContentLength(data.length, false);534 535      if (config.maxBodyLength > -1 && data.length > config.maxBodyLength) {536        return reject(new AxiosError(537          'Request body larger than maxBodyLength limit',538          AxiosError.ERR_BAD_REQUEST,539          config540        ));541      }542    }543 544    const contentLength = utils.toFiniteNumber(headers.getContentLength());545 546    if (utils.isArray(maxRate)) {547      maxUploadRate = maxRate[0];548      maxDownloadRate = maxRate[1];549    } else {550      maxUploadRate = maxDownloadRate = maxRate;551    }552 553    if (data && (onUploadProgress || maxUploadRate)) {554      if (!utils.isStream(data)) {555        data = stream.Readable.from(data, {objectMode: false});556      }557 558      data = stream.pipeline([data, new AxiosTransformStream({559        maxRate: utils.toFiniteNumber(maxUploadRate)560      })], utils.noop);561 562      onUploadProgress && data.on('progress', flushOnFinish(563        data,564        progressEventDecorator(565          contentLength,566          progressEventReducer(asyncDecorator(onUploadProgress), false, 3)567        )568      ));569    }570 571    // HTTP basic authentication572    let auth = undefined;573    if (config.auth) {574      const username = config.auth.username || '';575      const password = config.auth.password || '';576      auth = username + ':' + password;577    }578 579    if (!auth && parsed.username) {580      const urlUsername = parsed.username;581      const urlPassword = parsed.password;582      auth = urlUsername + ':' + urlPassword;583    }584 585    auth && headers.delete('authorization');586 587    let path;588 589    try {590      path = buildURL(591        parsed.pathname + parsed.search,592        config.params,593        config.paramsSerializer594      ).replace(/^\?/, '');595    } catch (err) {596      const customErr = new Error(err.message);597      customErr.config = config;598      customErr.url = config.url;599      customErr.exists = true;600      return reject(customErr);601    }602 603    headers.set(604      'Accept-Encoding',605      'gzip, compress, deflate' + (isBrotliSupported ? ', br' : ''), false606      );607 608    const options = {609      path,610      method: method,611      headers: headers.toJSON(),612      agents: { http: config.httpAgent, https: config.httpsAgent },613      auth,614      protocol,615      family,616      beforeRedirect: dispatchBeforeRedirect,617      beforeRedirects: {},618      http2Options619    };620 621    // cacheable-lookup integration hotfix622    !utils.isUndefined(lookup) && (options.lookup = lookup);623 624    if (config.socketPath) {625      options.socketPath = config.socketPath;626    } else {627      options.hostname = parsed.hostname.startsWith("[") ? parsed.hostname.slice(1, -1) : parsed.hostname;628      options.port = parsed.port;629      setProxy(options, config.proxy, protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path);630    }631 632    let transport;633    const isHttpsRequest = isHttps.test(options.protocol);634    options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;635 636    if (isHttp2) {637       transport = http2Transport;638    } else {639      if (config.transport) {640        transport = config.transport;641      } else if (config.maxRedirects === 0) {642        transport = isHttpsRequest ? https : http;643      } else {644        if (config.maxRedirects) {645          options.maxRedirects = config.maxRedirects;646        }647        if (config.beforeRedirect) {648          options.beforeRedirects.config = config.beforeRedirect;649        }650        transport = isHttpsRequest ? httpsFollow : httpFollow;651      }652    }653 654    if (config.maxBodyLength > -1) {655      options.maxBodyLength = config.maxBodyLength;656    } else {657      // follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited658      options.maxBodyLength = Infinity;659    }660 661    if (config.insecureHTTPParser) {662      options.insecureHTTPParser = config.insecureHTTPParser;663    }664 665    // Create the request666    req = transport.request(options, function handleResponse(res) {667      if (req.destroyed) return;668 669      const streams = [res];670 671      const responseLength = utils.toFiniteNumber(res.headers['content-length']);672 673      if (onDownloadProgress || maxDownloadRate) {674        const transformStream = new AxiosTransformStream({675          maxRate: utils.toFiniteNumber(maxDownloadRate)676        });677 678        onDownloadProgress && transformStream.on('progress', flushOnFinish(679          transformStream,680          progressEventDecorator(681            responseLength,682            progressEventReducer(asyncDecorator(onDownloadProgress), true, 3)683          )684        ));685 686        streams.push(transformStream);687      }688 689      // decompress the response body transparently if required690      let responseStream = res;691 692      // return the last request in case of redirects693      const lastRequest = res.req || req;694 695      // if decompress disabled we should not decompress696      if (config.decompress !== false && res.headers['content-encoding']) {697        // if no content, but headers still say that it is encoded,698        // remove the header not confuse downstream operations699        if (method === 'HEAD' || res.statusCode === 204) {700          delete res.headers['content-encoding'];701        }702 703        switch ((res.headers['content-encoding'] || '').toLowerCase()) {704        /*eslint default-case:0*/705        case 'gzip':706        case 'x-gzip':707        case 'compress':708        case 'x-compress':709          // add the unzipper to the body stream processing pipeline710          streams.push(zlib.createUnzip(zlibOptions));711 712          // remove the content-encoding in order to not confuse downstream operations713          delete res.headers['content-encoding'];714          break;715        case 'deflate':716          streams.push(new ZlibHeaderTransformStream());717 718          // add the unzipper to the body stream processing pipeline719          streams.push(zlib.createUnzip(zlibOptions));720 721          // remove the content-encoding in order to not confuse downstream operations722          delete res.headers['content-encoding'];723          break;724        case 'br':725          if (isBrotliSupported) {726            streams.push(zlib.createBrotliDecompress(brotliOptions));727            delete res.headers['content-encoding'];728          }729        }730      }731 732      responseStream = streams.length > 1 ? stream.pipeline(streams, utils.noop) : streams[0];733 734 735 736      const response = {737        status: res.statusCode,738        statusText: res.statusMessage,739        headers: new AxiosHeaders(res.headers),740        config,741        request: lastRequest742      };743 744      if (responseType === 'stream') {745        response.data = responseStream;746        settle(resolve, reject, response);747      } else {748        const responseBuffer = [];749        let totalResponseBytes = 0;750 751        responseStream.on('data', function handleStreamData(chunk) {752          responseBuffer.push(chunk);753          totalResponseBytes += chunk.length;754 755          // make sure the content length is not over the maxContentLength if specified756          if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) {757            // stream.destroy() emit aborted event before calling reject() on Node.js v16758            rejected = true;759            responseStream.destroy();760            abort(new AxiosError('maxContentLength size of ' + config.maxContentLength + ' exceeded',761              AxiosError.ERR_BAD_RESPONSE, config, lastRequest));762          }763        });764 765        responseStream.on('aborted', function handlerStreamAborted() {766          if (rejected) {767            return;768          }769 770          const err = new AxiosError(771            'stream has been aborted',772            AxiosError.ERR_BAD_RESPONSE,773            config,774            lastRequest775          );776          responseStream.destroy(err);777          reject(err);778        });779 780        responseStream.on('error', function handleStreamError(err) {781          if (req.destroyed) return;782          reject(AxiosError.from(err, null, config, lastRequest));783        });784 785        responseStream.on('end', function handleStreamEnd() {786          try {787            let responseData = responseBuffer.length === 1 ? responseBuffer[0] : Buffer.concat(responseBuffer);788            if (responseType !== 'arraybuffer') {789              responseData = responseData.toString(responseEncoding);790              if (!responseEncoding || responseEncoding === 'utf8') {791                responseData = utils.stripBOM(responseData);792              }793            }794            response.data = responseData;795          } catch (err) {796            return reject(AxiosError.from(err, null, config, response.request, response));797          }798          settle(resolve, reject, response);799        });800      }801 802      abortEmitter.once('abort', err => {803        if (!responseStream.destroyed) {804          responseStream.emit('error', err);805          responseStream.destroy();806        }807      });808    });809 810    abortEmitter.once('abort', err => {811      if (req.close) {812        req.close();813      } else {814        req.destroy(err);815      }816    });817 818    // Handle errors819    req.on('error', function handleRequestError(err) {820      reject(AxiosError.from(err, null, config, req));821    });822 823    // set tcp keep alive to prevent drop connection by peer824    req.on('socket', function handleRequestSocket(socket) {825      // default interval of sending ack packet is 1 minute826      socket.setKeepAlive(true, 1000 * 60);827    });828 829    // Handle request timeout830    if (config.timeout) {831      // This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types.832      const timeout = parseInt(config.timeout, 10);833 834      if (Number.isNaN(timeout)) {835        abort(new AxiosError(836          'error trying to parse `config.timeout` to int',837          AxiosError.ERR_BAD_OPTION_VALUE,838          config,839          req840        ));841 842        return;843      }844 845      // Sometime, the response will be very slow, and does not respond, the connect event will be block by event loop system.846      // And timer callback will be fired, and abort() will be invoked before connection, then get "socket hang up" and code ECONNRESET.847      // 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.848      // And then these socket which be hang up will devouring CPU little by little.849      // ClientRequest.setTimeout will be fired on the specify milliseconds, and can make sure that abort() will be fired after connect.850      req.setTimeout(timeout, function handleRequestTimeout() {851        if (isDone) return;852        let timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded';853        const transitional = config.transitional || transitionalDefaults;854        if (config.timeoutErrorMessage) {855          timeoutErrorMessage = config.timeoutErrorMessage;856        }857        abort(new AxiosError(858          timeoutErrorMessage,859          transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,860          config,861          req862        ));863      });864    } else {865      // explicitly reset the socket timeout value for a possible `keep-alive` request866      req.setTimeout(0);867    }868 869 870    // Send the request871    if (utils.isStream(data)) {872      let ended = false;873      let errored = false;874 875      data.on('end', () => {876        ended = true;877      });878 879      data.once('error', err => {880        errored = true;881        req.destroy(err);882      });883 884      data.on('close', () => {885        if (!ended && !errored) {886          abort(new CanceledError('Request stream has been aborted', config, req));887        }888      });889 890      data.pipe(req);891    } else {892      data && req.write(data);893      req.end();894    }895  });896}897 898export const __setProxy = setProxy;899