Skip to content
Snippets Groups Projects
index.js 7.57 MiB
Newer Older
  • Learn to ignore specific revisions
  • Hugo NOUTS's avatar
    Hugo NOUTS committed
    10001 10002 10003 10004 10005 10006 10007 10008 10009 10010 10011 10012 10013 10014 10015 10016 10017 10018 10019 10020 10021 10022 10023 10024 10025 10026 10027 10028 10029 10030 10031 10032 10033 10034 10035 10036 10037 10038 10039 10040 10041 10042 10043 10044 10045 10046 10047 10048 10049 10050 10051 10052 10053 10054 10055 10056 10057 10058 10059 10060 10061 10062 10063 10064 10065 10066 10067 10068 10069 10070 10071 10072 10073 10074 10075 10076 10077 10078 10079 10080 10081 10082 10083 10084 10085 10086 10087 10088 10089 10090 10091 10092 10093 10094 10095 10096 10097 10098 10099 10100 10101 10102 10103 10104 10105 10106 10107 10108 10109 10110 10111 10112 10113 10114 10115 10116 10117 10118 10119 10120 10121 10122 10123 10124 10125 10126 10127 10128 10129 10130 10131 10132 10133 10134 10135 10136 10137 10138 10139 10140 10141 10142 10143 10144 10145 10146 10147 10148 10149 10150 10151 10152 10153 10154 10155 10156 10157 10158 10159 10160 10161 10162 10163 10164 10165 10166 10167 10168 10169 10170 10171 10172 10173 10174 10175 10176 10177 10178 10179 10180 10181 10182 10183 10184 10185 10186 10187 10188 10189 10190 10191 10192 10193 10194 10195 10196 10197 10198 10199 10200 10201 10202 10203 10204 10205 10206 10207 10208 10209 10210 10211 10212 10213 10214 10215 10216 10217 10218 10219 10220 10221 10222 10223 10224 10225 10226 10227 10228 10229 10230 10231 10232 10233 10234 10235 10236 10237 10238 10239 10240 10241 10242 10243 10244 10245 10246 10247 10248 10249 10250 10251 10252 10253 10254 10255 10256 10257 10258 10259 10260 10261 10262 10263 10264 10265 10266 10267 10268 10269 10270 10271 10272 10273 10274 10275 10276 10277 10278 10279 10280 10281 10282 10283 10284 10285 10286 10287 10288 10289 10290 10291 10292 10293 10294 10295 10296 10297 10298 10299 10300 10301 10302 10303 10304 10305 10306 10307 10308 10309 10310 10311 10312 10313 10314 10315 10316 10317 10318 10319 10320 10321 10322 10323 10324 10325 10326 10327 10328 10329 10330 10331 10332 10333 10334 10335 10336 10337 10338 10339 10340 10341 10342 10343 10344 10345 10346 10347 10348 10349 10350 10351 10352 10353 10354 10355 10356 10357 10358 10359 10360 10361 10362 10363 10364 10365 10366 10367 10368 10369 10370 10371 10372 10373 10374 10375 10376 10377 10378 10379 10380 10381 10382 10383 10384 10385 10386 10387 10388 10389 10390 10391 10392 10393 10394 10395 10396 10397 10398 10399 10400 10401 10402 10403 10404 10405 10406 10407 10408 10409 10410 10411 10412 10413
      if (this.idx[domain] && this.idx[domain][path] && this.idx[domain][path][key]) {
        delete this.idx[domain][path][key];
      }
      cb(null);
    };
    
    MemoryCookieStore.prototype.removeCookies = function(domain, path, cb) {
      if (this.idx[domain]) {
        if (path) {
          delete this.idx[domain][path];
        } else {
          delete this.idx[domain];
        }
      }
      return cb(null);
    };
    
    MemoryCookieStore.prototype.removeAllCookies = function(cb) {
      this.idx = {};
      return cb(null);
    }
    
    MemoryCookieStore.prototype.getAllCookies = function(cb) {
      var cookies = [];
      var idx = this.idx;
    
      var domains = Object.keys(idx);
      domains.forEach(function(domain) {
        var paths = Object.keys(idx[domain]);
        paths.forEach(function(path) {
          var keys = Object.keys(idx[domain][path]);
          keys.forEach(function(key) {
            if (key !== null) {
              cookies.push(idx[domain][path][key]);
            }
          });
        });
      });
    
      // Sort by creationIndex so deserializing retains the creation order.
      // When implementing your own store, this SHOULD retain the order too
      cookies.sort(function(a,b) {
        return (a.creationIndex||0) - (b.creationIndex||0);
      });
    
      cb(null, cookies);
    };
    
    
    /***/ }),
    /* 71 */
    /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
    
    "use strict";
    /*!
     * Copyright (c) 2015, Salesforce.com, Inc.
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice,
     * this list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form must reproduce the above copyright notice,
     * this list of conditions and the following disclaimer in the documentation
     * and/or other materials provided with the distribution.
     *
     * 3. Neither the name of Salesforce.com nor the names of its contributors may
     * be used to endorse or promote products derived from this software without
     * specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     * POSSIBILITY OF SUCH DAMAGE.
     */
    
    var pubsuffix = __webpack_require__(65);
    
    // Gives the permutation of all possible domainMatch()es of a given domain. The
    // array is in shortest-to-longest order.  Handy for indexing.
    function permuteDomain (domain) {
      var pubSuf = pubsuffix.getPublicSuffix(domain);
      if (!pubSuf) {
        return null;
      }
      if (pubSuf == domain) {
        return [domain];
      }
    
      var prefix = domain.slice(0, -(pubSuf.length + 1)); // ".example.com"
      var parts = prefix.split('.').reverse();
      var cur = pubSuf;
      var permutations = [cur];
      while (parts.length) {
        cur = parts.shift() + '.' + cur;
        permutations.push(cur);
      }
      return permutations;
    }
    
    exports.permuteDomain = permuteDomain;
    
    
    /***/ }),
    /* 72 */
    /***/ ((__unused_webpack_module, exports) => {
    
    "use strict";
    /*!
     * Copyright (c) 2015, Salesforce.com, Inc.
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice,
     * this list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form must reproduce the above copyright notice,
     * this list of conditions and the following disclaimer in the documentation
     * and/or other materials provided with the distribution.
     *
     * 3. Neither the name of Salesforce.com nor the names of its contributors may
     * be used to endorse or promote products derived from this software without
     * specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     * POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     * "A request-path path-matches a given cookie-path if at least one of the
     * following conditions holds:"
     */
    function pathMatch (reqPath, cookiePath) {
      // "o  The cookie-path and the request-path are identical."
      if (cookiePath === reqPath) {
        return true;
      }
    
      var idx = reqPath.indexOf(cookiePath);
      if (idx === 0) {
        // "o  The cookie-path is a prefix of the request-path, and the last
        // character of the cookie-path is %x2F ("/")."
        if (cookiePath.substr(-1) === "/") {
          return true;
        }
    
        // " o  The cookie-path is a prefix of the request-path, and the first
        // character of the request-path that is not included in the cookie- path
        // is a %x2F ("/") character."
        if (reqPath.substr(cookiePath.length, 1) === "/") {
          return true;
        }
      }
    
      return false;
    }
    
    exports.pathMatch = pathMatch;
    
    
    /***/ }),
    /* 73 */
    /***/ ((module) => {
    
    // generated by genversion
    module.exports = '2.5.0'
    
    
    /***/ }),
    /* 74 */
    /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
    
    "use strict";
    
    
    var jsonSafeStringify = __webpack_require__(75)
    var crypto = __webpack_require__(76)
    var Buffer = (__webpack_require__(77).Buffer)
    
    var defer = typeof setImmediate === 'undefined'
      ? process.nextTick
      : setImmediate
    
    function paramsHaveRequestBody (params) {
      return (
        params.body ||
        params.requestBodyStream ||
        (params.json && typeof params.json !== 'boolean') ||
        params.multipart
      )
    }
    
    function safeStringify (obj, replacer) {
      var ret
      try {
        ret = JSON.stringify(obj, replacer)
      } catch (e) {
        ret = jsonSafeStringify(obj, replacer)
      }
      return ret
    }
    
    function md5 (str) {
      return crypto.createHash('md5').update(str).digest('hex')
    }
    
    function isReadStream (rs) {
      return rs.readable && rs.path && rs.mode
    }
    
    function toBase64 (str) {
      return Buffer.from(str || '', 'utf8').toString('base64')
    }
    
    function copy (obj) {
      var o = {}
      Object.keys(obj).forEach(function (i) {
        o[i] = obj[i]
      })
      return o
    }
    
    function version () {
      var numbers = process.version.replace('v', '').split('.')
      return {
        major: parseInt(numbers[0], 10),
        minor: parseInt(numbers[1], 10),
        patch: parseInt(numbers[2], 10)
      }
    }
    
    exports.paramsHaveRequestBody = paramsHaveRequestBody
    exports.safeStringify = safeStringify
    exports.md5 = md5
    exports.isReadStream = isReadStream
    exports.toBase64 = toBase64
    exports.copy = copy
    exports.version = version
    exports.defer = defer
    
    
    /***/ }),
    /* 75 */
    /***/ ((module, exports) => {
    
    exports = module.exports = stringify
    exports.getSerialize = serializer
    
    function stringify(obj, replacer, spaces, cycleReplacer) {
      return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces)
    }
    
    function serializer(replacer, cycleReplacer) {
      var stack = [], keys = []
    
      if (cycleReplacer == null) cycleReplacer = function(key, value) {
        if (stack[0] === value) return "[Circular ~]"
        return "[Circular ~." + keys.slice(0, stack.indexOf(value)).join(".") + "]"
      }
    
      return function(key, value) {
        if (stack.length > 0) {
          var thisPos = stack.indexOf(this)
          ~thisPos ? stack.splice(thisPos + 1) : stack.push(this)
          ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key)
          if (~stack.indexOf(value)) value = cycleReplacer.call(this, key, value)
        }
        else stack.push(value)
    
        return replacer == null ? value : replacer.call(this, key, value)
      }
    }
    
    
    /***/ }),
    /* 76 */
    /***/ ((module) => {
    
    "use strict";
    module.exports = require("crypto");
    
    /***/ }),
    /* 77 */
    /***/ ((module, exports, __webpack_require__) => {
    
    /*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
    /* eslint-disable node/no-deprecated-api */
    var buffer = __webpack_require__(78)
    var Buffer = buffer.Buffer
    
    // alternative to using Object.keys for old browsers
    function copyProps (src, dst) {
      for (var key in src) {
        dst[key] = src[key]
      }
    }
    if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
      module.exports = buffer
    } else {
      // Copy properties from require('buffer')
      copyProps(buffer, exports)
      exports.Buffer = SafeBuffer
    }
    
    function SafeBuffer (arg, encodingOrOffset, length) {
      return Buffer(arg, encodingOrOffset, length)
    }
    
    SafeBuffer.prototype = Object.create(Buffer.prototype)
    
    // Copy static methods from Buffer
    copyProps(Buffer, SafeBuffer)
    
    SafeBuffer.from = function (arg, encodingOrOffset, length) {
      if (typeof arg === 'number') {
        throw new TypeError('Argument must not be a number')
      }
      return Buffer(arg, encodingOrOffset, length)
    }
    
    SafeBuffer.alloc = function (size, fill, encoding) {
      if (typeof size !== 'number') {
        throw new TypeError('Argument must be a number')
      }
      var buf = Buffer(size)
      if (fill !== undefined) {
        if (typeof encoding === 'string') {
          buf.fill(fill, encoding)
        } else {
          buf.fill(fill)
        }
      } else {
        buf.fill(0)
      }
      return buf
    }
    
    SafeBuffer.allocUnsafe = function (size) {
      if (typeof size !== 'number') {
        throw new TypeError('Argument must be a number')
      }
      return Buffer(size)
    }
    
    SafeBuffer.allocUnsafeSlow = function (size) {
      if (typeof size !== 'number') {
        throw new TypeError('Argument must be a number')
      }
      return buffer.SlowBuffer(size)
    }
    
    
    /***/ }),
    /* 78 */
    /***/ ((module) => {
    
    "use strict";
    module.exports = require("buffer");
    
    /***/ }),
    /* 79 */
    /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
    
    "use strict";
    
    
    var http = __webpack_require__(80)
    var https = __webpack_require__(81)
    var url = __webpack_require__(63)
    var util = __webpack_require__(64)
    var stream = __webpack_require__(82)
    var zlib = __webpack_require__(83)
    var aws2 = __webpack_require__(84)
    var aws4 = __webpack_require__(85)
    var httpSignature = __webpack_require__(88)
    var mime = __webpack_require__(139)
    var caseless = __webpack_require__(143)
    var ForeverAgent = __webpack_require__(144)
    var FormData = __webpack_require__(146)
    var extend = __webpack_require__(59)
    var isstream = __webpack_require__(161)
    var isTypedArray = (__webpack_require__(162).strict)
    var helpers = __webpack_require__(74)
    var cookies = __webpack_require__(60)
    var getProxyFromURI = __webpack_require__(163)
    var Querystring = (__webpack_require__(164).Querystring)
    var Har = (__webpack_require__(170).Har)
    var Auth = (__webpack_require__(239).Auth)
    var OAuth = (__webpack_require__(243).OAuth)
    var hawk = __webpack_require__(245)
    var Multipart = (__webpack_require__(246).Multipart)
    var Redirect = (__webpack_require__(247).Redirect)
    var Tunnel = (__webpack_require__(248).Tunnel)
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    var now = __webpack_require__(252)
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    10415 10416 10417 10418 10419 10420 10421 10422 10423 10424 10425 10426 10427 10428 10429 10430 10431 10432 10433 10434 10435 10436 10437 10438 10439 10440 10441 10442 10443 10444 10445 10446 10447 10448 10449 10450 10451 10452 10453 10454 10455 10456 10457 10458 10459 10460 10461 10462 10463 10464 10465 10466 10467 10468 10469 10470 10471 10472 10473 10474 10475 10476 10477 10478 10479 10480 10481 10482 10483 10484 10485 10486 10487 10488 10489 10490 10491 10492 10493 10494 10495 10496 10497 10498 10499 10500 10501 10502 10503 10504 10505 10506 10507 10508 10509 10510 10511 10512 10513 10514 10515 10516 10517 10518 10519 10520 10521 10522 10523 10524 10525 10526 10527 10528 10529 10530 10531 10532 10533 10534 10535 10536 10537 10538 10539 10540 10541 10542 10543 10544 10545 10546 10547 10548 10549 10550 10551 10552 10553 10554 10555 10556 10557 10558 10559 10560 10561 10562 10563 10564 10565 10566 10567 10568 10569 10570 10571 10572 10573 10574 10575 10576 10577 10578 10579 10580 10581 10582 10583 10584 10585 10586 10587 10588 10589 10590 10591 10592 10593 10594 10595 10596 10597 10598 10599 10600 10601 10602 10603 10604 10605 10606 10607 10608 10609 10610 10611 10612 10613 10614 10615 10616 10617 10618 10619 10620 10621 10622 10623 10624 10625 10626 10627 10628 10629 10630 10631 10632 10633 10634 10635 10636 10637 10638 10639 10640 10641 10642 10643 10644 10645 10646 10647 10648 10649 10650 10651 10652 10653 10654 10655 10656 10657 10658 10659 10660 10661 10662 10663 10664 10665 10666 10667 10668 10669 10670 10671 10672 10673 10674 10675 10676 10677 10678 10679 10680 10681 10682 10683 10684 10685 10686 10687 10688 10689 10690 10691 10692 10693 10694 10695 10696 10697 10698 10699 10700 10701 10702 10703 10704 10705 10706 10707 10708 10709 10710 10711 10712 10713 10714 10715 10716 10717 10718 10719 10720 10721 10722 10723 10724 10725 10726 10727 10728 10729 10730 10731 10732 10733 10734 10735 10736 10737 10738 10739 10740 10741 10742 10743 10744 10745 10746 10747 10748 10749 10750 10751 10752 10753 10754 10755 10756 10757 10758 10759 10760 10761 10762 10763 10764 10765 10766 10767 10768 10769 10770 10771 10772 10773 10774 10775 10776 10777 10778 10779 10780 10781 10782 10783 10784 10785 10786 10787 10788 10789 10790 10791 10792 10793 10794 10795 10796 10797 10798 10799 10800 10801 10802 10803 10804 10805 10806 10807 10808 10809 10810 10811 10812 10813 10814 10815 10816 10817 10818 10819 10820 10821 10822 10823 10824 10825 10826 10827 10828 10829 10830 10831 10832 10833 10834 10835 10836 10837 10838 10839 10840 10841 10842 10843 10844 10845 10846 10847 10848 10849 10850 10851 10852 10853 10854 10855 10856 10857 10858 10859 10860 10861 10862 10863 10864 10865 10866 10867 10868 10869 10870 10871 10872 10873 10874 10875 10876 10877 10878 10879 10880 10881 10882 10883 10884 10885 10886 10887 10888 10889 10890 10891 10892 10893 10894 10895 10896 10897 10898 10899 10900 10901 10902 10903 10904 10905 10906 10907 10908 10909 10910 10911 10912 10913 10914 10915 10916 10917 10918 10919 10920 10921 10922 10923 10924 10925 10926 10927 10928 10929 10930 10931 10932 10933 10934 10935 10936 10937 10938 10939 10940 10941 10942 10943 10944 10945 10946 10947 10948 10949 10950 10951 10952 10953 10954 10955 10956 10957 10958 10959 10960 10961 10962 10963 10964 10965 10966 10967 10968 10969 10970 10971 10972 10973 10974 10975 10976 10977 10978 10979 10980 10981 10982 10983 10984 10985 10986 10987 10988 10989 10990 10991 10992 10993 10994 10995 10996 10997 10998 10999 11000
    var Buffer = (__webpack_require__(77).Buffer)
    
    var safeStringify = helpers.safeStringify
    var isReadStream = helpers.isReadStream
    var toBase64 = helpers.toBase64
    var defer = helpers.defer
    var copy = helpers.copy
    var version = helpers.version
    var globalCookieJar = cookies.jar()
    
    var globalPool = {}
    
    function filterForNonReserved (reserved, options) {
      // Filter out properties that are not reserved.
      // Reserved values are passed in at call site.
    
      var object = {}
      for (var i in options) {
        var notReserved = (reserved.indexOf(i) === -1)
        if (notReserved) {
          object[i] = options[i]
        }
      }
      return object
    }
    
    function filterOutReservedFunctions (reserved, options) {
      // Filter out properties that are functions and are reserved.
      // Reserved values are passed in at call site.
    
      var object = {}
      for (var i in options) {
        var isReserved = !(reserved.indexOf(i) === -1)
        var isFunction = (typeof options[i] === 'function')
        if (!(isReserved && isFunction)) {
          object[i] = options[i]
        }
      }
      return object
    }
    
    // Return a simpler request object to allow serialization
    function requestToJSON () {
      var self = this
      return {
        uri: self.uri,
        method: self.method,
        headers: self.headers
      }
    }
    
    // Return a simpler response object to allow serialization
    function responseToJSON () {
      var self = this
      return {
        statusCode: self.statusCode,
        body: self.body,
        headers: self.headers,
        request: requestToJSON.call(self.request)
      }
    }
    
    function Request (options) {
      // if given the method property in options, set property explicitMethod to true
    
      // extend the Request instance with any non-reserved properties
      // remove any reserved functions from the options object
      // set Request instance to be readable and writable
      // call init
    
      var self = this
    
      // start with HAR, then override with additional options
      if (options.har) {
        self._har = new Har(self)
        options = self._har.options(options)
      }
    
      stream.Stream.call(self)
      var reserved = Object.keys(Request.prototype)
      var nonReserved = filterForNonReserved(reserved, options)
    
      extend(self, nonReserved)
      options = filterOutReservedFunctions(reserved, options)
    
      self.readable = true
      self.writable = true
      if (options.method) {
        self.explicitMethod = true
      }
      self._qs = new Querystring(self)
      self._auth = new Auth(self)
      self._oauth = new OAuth(self)
      self._multipart = new Multipart(self)
      self._redirect = new Redirect(self)
      self._tunnel = new Tunnel(self)
      self.init(options)
    }
    
    util.inherits(Request, stream.Stream)
    
    // Debugging
    Request.debug = process.env.NODE_DEBUG && /\brequest\b/.test(process.env.NODE_DEBUG)
    function debug () {
      if (Request.debug) {
        console.error('REQUEST %s', util.format.apply(util, arguments))
      }
    }
    Request.prototype.debug = debug
    
    Request.prototype.init = function (options) {
      // init() contains all the code to setup the request object.
      // the actual outgoing request is not started until start() is called
      // this function is called from both the constructor and on redirect.
      var self = this
      if (!options) {
        options = {}
      }
      self.headers = self.headers ? copy(self.headers) : {}
    
      // Delete headers with value undefined since they break
      // ClientRequest.OutgoingMessage.setHeader in node 0.12
      for (var headerName in self.headers) {
        if (typeof self.headers[headerName] === 'undefined') {
          delete self.headers[headerName]
        }
      }
    
      caseless.httpify(self, self.headers)
    
      if (!self.method) {
        self.method = options.method || 'GET'
      }
      if (!self.localAddress) {
        self.localAddress = options.localAddress
      }
    
      self._qs.init(options)
    
      debug(options)
      if (!self.pool && self.pool !== false) {
        self.pool = globalPool
      }
      self.dests = self.dests || []
      self.__isRequestRequest = true
    
      // Protect against double callback
      if (!self._callback && self.callback) {
        self._callback = self.callback
        self.callback = function () {
          if (self._callbackCalled) {
            return // Print a warning maybe?
          }
          self._callbackCalled = true
          self._callback.apply(self, arguments)
        }
        self.on('error', self.callback.bind())
        self.on('complete', self.callback.bind(self, null))
      }
    
      // People use this property instead all the time, so support it
      if (!self.uri && self.url) {
        self.uri = self.url
        delete self.url
      }
    
      // If there's a baseUrl, then use it as the base URL (i.e. uri must be
      // specified as a relative path and is appended to baseUrl).
      if (self.baseUrl) {
        if (typeof self.baseUrl !== 'string') {
          return self.emit('error', new Error('options.baseUrl must be a string'))
        }
    
        if (typeof self.uri !== 'string') {
          return self.emit('error', new Error('options.uri must be a string when using options.baseUrl'))
        }
    
        if (self.uri.indexOf('//') === 0 || self.uri.indexOf('://') !== -1) {
          return self.emit('error', new Error('options.uri must be a path when using options.baseUrl'))
        }
    
        // Handle all cases to make sure that there's only one slash between
        // baseUrl and uri.
        var baseUrlEndsWithSlash = self.baseUrl.lastIndexOf('/') === self.baseUrl.length - 1
        var uriStartsWithSlash = self.uri.indexOf('/') === 0
    
        if (baseUrlEndsWithSlash && uriStartsWithSlash) {
          self.uri = self.baseUrl + self.uri.slice(1)
        } else if (baseUrlEndsWithSlash || uriStartsWithSlash) {
          self.uri = self.baseUrl + self.uri
        } else if (self.uri === '') {
          self.uri = self.baseUrl
        } else {
          self.uri = self.baseUrl + '/' + self.uri
        }
        delete self.baseUrl
      }
    
      // A URI is needed by this point, emit error if we haven't been able to get one
      if (!self.uri) {
        return self.emit('error', new Error('options.uri is a required argument'))
      }
    
      // If a string URI/URL was given, parse it into a URL object
      if (typeof self.uri === 'string') {
        self.uri = url.parse(self.uri)
      }
    
      // Some URL objects are not from a URL parsed string and need href added
      if (!self.uri.href) {
        self.uri.href = url.format(self.uri)
      }
    
      // DEPRECATED: Warning for users of the old Unix Sockets URL Scheme
      if (self.uri.protocol === 'unix:') {
        return self.emit('error', new Error('`unix://` URL scheme is no longer supported. Please use the format `http://unix:SOCKET:PATH`'))
      }
    
      // Support Unix Sockets
      if (self.uri.host === 'unix') {
        self.enableUnixSocket()
      }
    
      if (self.strictSSL === false) {
        self.rejectUnauthorized = false
      }
    
      if (!self.uri.pathname) { self.uri.pathname = '/' }
    
      if (!(self.uri.host || (self.uri.hostname && self.uri.port)) && !self.uri.isUnix) {
        // Invalid URI: it may generate lot of bad errors, like 'TypeError: Cannot call method `indexOf` of undefined' in CookieJar
        // Detect and reject it as soon as possible
        var faultyUri = url.format(self.uri)
        var message = 'Invalid URI "' + faultyUri + '"'
        if (Object.keys(options).length === 0) {
          // No option ? This can be the sign of a redirect
          // As this is a case where the user cannot do anything (they didn't call request directly with this URL)
          // they should be warned that it can be caused by a redirection (can save some hair)
          message += '. This can be caused by a crappy redirection.'
        }
        // This error was fatal
        self.abort()
        return self.emit('error', new Error(message))
      }
    
      if (!self.hasOwnProperty('proxy')) {
        self.proxy = getProxyFromURI(self.uri)
      }
    
      self.tunnel = self._tunnel.isEnabled()
      if (self.proxy) {
        self._tunnel.setup(options)
      }
    
      self._redirect.onRequest(options)
    
      self.setHost = false
      if (!self.hasHeader('host')) {
        var hostHeaderName = self.originalHostHeaderName || 'host'
        self.setHeader(hostHeaderName, self.uri.host)
        // Drop :port suffix from Host header if known protocol.
        if (self.uri.port) {
          if ((self.uri.port === '80' && self.uri.protocol === 'http:') ||
              (self.uri.port === '443' && self.uri.protocol === 'https:')) {
            self.setHeader(hostHeaderName, self.uri.hostname)
          }
        }
        self.setHost = true
      }
    
      self.jar(self._jar || options.jar)
    
      if (!self.uri.port) {
        if (self.uri.protocol === 'http:') { self.uri.port = 80 } else if (self.uri.protocol === 'https:') { self.uri.port = 443 }
      }
    
      if (self.proxy && !self.tunnel) {
        self.port = self.proxy.port
        self.host = self.proxy.hostname
      } else {
        self.port = self.uri.port
        self.host = self.uri.hostname
      }
    
      if (options.form) {
        self.form(options.form)
      }
    
      if (options.formData) {
        var formData = options.formData
        var requestForm = self.form()
        var appendFormValue = function (key, value) {
          if (value && value.hasOwnProperty('value') && value.hasOwnProperty('options')) {
            requestForm.append(key, value.value, value.options)
          } else {
            requestForm.append(key, value)
          }
        }
        for (var formKey in formData) {
          if (formData.hasOwnProperty(formKey)) {
            var formValue = formData[formKey]
            if (formValue instanceof Array) {
              for (var j = 0; j < formValue.length; j++) {
                appendFormValue(formKey, formValue[j])
              }
            } else {
              appendFormValue(formKey, formValue)
            }
          }
        }
      }
    
      if (options.qs) {
        self.qs(options.qs)
      }
    
      if (self.uri.path) {
        self.path = self.uri.path
      } else {
        self.path = self.uri.pathname + (self.uri.search || '')
      }
    
      if (self.path.length === 0) {
        self.path = '/'
      }
    
      // Auth must happen last in case signing is dependent on other headers
      if (options.aws) {
        self.aws(options.aws)
      }
    
      if (options.hawk) {
        self.hawk(options.hawk)
      }
    
      if (options.httpSignature) {
        self.httpSignature(options.httpSignature)
      }
    
      if (options.auth) {
        if (Object.prototype.hasOwnProperty.call(options.auth, 'username')) {
          options.auth.user = options.auth.username
        }
        if (Object.prototype.hasOwnProperty.call(options.auth, 'password')) {
          options.auth.pass = options.auth.password
        }
    
        self.auth(
          options.auth.user,
          options.auth.pass,
          options.auth.sendImmediately,
          options.auth.bearer
        )
      }
    
      if (self.gzip && !self.hasHeader('accept-encoding')) {
        self.setHeader('accept-encoding', 'gzip, deflate')
      }
    
      if (self.uri.auth && !self.hasHeader('authorization')) {
        var uriAuthPieces = self.uri.auth.split(':').map(function (item) { return self._qs.unescape(item) })
        self.auth(uriAuthPieces[0], uriAuthPieces.slice(1).join(':'), true)
      }
    
      if (!self.tunnel && self.proxy && self.proxy.auth && !self.hasHeader('proxy-authorization')) {
        var proxyAuthPieces = self.proxy.auth.split(':').map(function (item) { return self._qs.unescape(item) })
        var authHeader = 'Basic ' + toBase64(proxyAuthPieces.join(':'))
        self.setHeader('proxy-authorization', authHeader)
      }
    
      if (self.proxy && !self.tunnel) {
        self.path = (self.uri.protocol + '//' + self.uri.host + self.path)
      }
    
      if (options.json) {
        self.json(options.json)
      }
      if (options.multipart) {
        self.multipart(options.multipart)
      }
    
      if (options.time) {
        self.timing = true
    
        // NOTE: elapsedTime is deprecated in favor of .timings
        self.elapsedTime = self.elapsedTime || 0
      }
    
      function setContentLength () {
        if (isTypedArray(self.body)) {
          self.body = Buffer.from(self.body)
        }
    
        if (!self.hasHeader('content-length')) {
          var length
          if (typeof self.body === 'string') {
            length = Buffer.byteLength(self.body)
          } else if (Array.isArray(self.body)) {
            length = self.body.reduce(function (a, b) { return a + b.length }, 0)
          } else {
            length = self.body.length
          }
    
          if (length) {
            self.setHeader('content-length', length)
          } else {
            self.emit('error', new Error('Argument error, options.body.'))
          }
        }
      }
      if (self.body && !isstream(self.body)) {
        setContentLength()
      }
    
      if (options.oauth) {
        self.oauth(options.oauth)
      } else if (self._oauth.params && self.hasHeader('authorization')) {
        self.oauth(self._oauth.params)
      }
    
      var protocol = self.proxy && !self.tunnel ? self.proxy.protocol : self.uri.protocol
      var defaultModules = {'http:': http, 'https:': https}
      var httpModules = self.httpModules || {}
    
      self.httpModule = httpModules[protocol] || defaultModules[protocol]
    
      if (!self.httpModule) {
        return self.emit('error', new Error('Invalid protocol: ' + protocol))
      }
    
      if (options.ca) {
        self.ca = options.ca
      }
    
      if (!self.agent) {
        if (options.agentOptions) {
          self.agentOptions = options.agentOptions
        }
    
        if (options.agentClass) {
          self.agentClass = options.agentClass
        } else if (options.forever) {
          var v = version()
          // use ForeverAgent in node 0.10- only
          if (v.major === 0 && v.minor <= 10) {
            self.agentClass = protocol === 'http:' ? ForeverAgent : ForeverAgent.SSL
          } else {
            self.agentClass = self.httpModule.Agent
            self.agentOptions = self.agentOptions || {}
            self.agentOptions.keepAlive = true
          }
        } else {
          self.agentClass = self.httpModule.Agent
        }
      }
    
      if (self.pool === false) {
        self.agent = false
      } else {
        self.agent = self.agent || self.getNewAgent()
      }
    
      self.on('pipe', function (src) {
        if (self.ntick && self._started) {
          self.emit('error', new Error('You cannot pipe to this stream after the outbound request has started.'))
        }
        self.src = src
        if (isReadStream(src)) {
          if (!self.hasHeader('content-type')) {
            self.setHeader('content-type', mime.lookup(src.path))
          }
        } else {
          if (src.headers) {
            for (var i in src.headers) {
              if (!self.hasHeader(i)) {
                self.setHeader(i, src.headers[i])
              }
            }
          }
          if (self._json && !self.hasHeader('content-type')) {
            self.setHeader('content-type', 'application/json')
          }
          if (src.method && !self.explicitMethod) {
            self.method = src.method
          }
        }
    
      // self.on('pipe', function () {
      //   console.error('You have already piped to this stream. Pipeing twice is likely to break the request.')
      // })
      })
    
      defer(function () {
        if (self._aborted) {
          return
        }
    
        var end = function () {
          if (self._form) {
            if (!self._auth.hasAuth) {
              self._form.pipe(self)
            } else if (self._auth.hasAuth && self._auth.sentAuth) {
              self._form.pipe(self)
            }
          }
          if (self._multipart && self._multipart.chunked) {
            self._multipart.body.pipe(self)
          }
          if (self.body) {
            if (isstream(self.body)) {
              self.body.pipe(self)
            } else {
              setContentLength()
              if (Array.isArray(self.body)) {
                self.body.forEach(function (part) {
                  self.write(part)
                })
              } else {
                self.write(self.body)
              }
              self.end()
            }
          } else if (self.requestBodyStream) {
            console.warn('options.requestBodyStream is deprecated, please pass the request object to stream.pipe.')
            self.requestBodyStream.pipe(self)
          } else if (!self.src) {
            if (self._auth.hasAuth && !self._auth.sentAuth) {
              self.end()
              return
            }
            if (self.method !== 'GET' && typeof self.method !== 'undefined') {
              self.setHeader('content-length', 0)
            }
            self.end()
          }
        }
    
        if (self._form && !self.hasHeader('content-length')) {
          // Before ending the request, we had to compute the length of the whole form, asyncly
          self.setHeader(self._form.getHeaders(), true)
          self._form.getLength(function (err, length) {
            if (!err && !isNaN(length)) {
              self.setHeader('content-length', length)
            }
            end()
          })
        } else {
          end()
        }
    
        self.ntick = true
      })
    }
    
    Request.prototype.getNewAgent = function () {
      var self = this
      var Agent = self.agentClass
      var options = {}
      if (self.agentOptions) {
        for (var i in self.agentOptions) {
          options[i] = self.agentOptions[i]
        }
      }
      if (self.ca) {
        options.ca = self.ca
      }
      if (self.ciphers) {
        options.ciphers = self.ciphers
      }
      if (self.secureProtocol) {
        options.secureProtocol = self.secureProtocol
      }
      if (self.secureOptions) {
        options.secureOptions = self.secureOptions
      }
      if (typeof self.rejectUnauthorized !== 'undefined') {
        options.rejectUnauthorized = self.rejectUnauthorized
      }
    
      if (self.cert && self.key) {
        options.key = self.key
        options.cert = self.cert
      }
    
      if (self.pfx) {
        options.pfx = self.pfx