Skip to content
Snippets Groups Projects
index.js 8.75 MiB
Newer Older
  • Learn to ignore specific revisions
  • Romain CREY's avatar
    Romain CREY committed
        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;
    
    
    /***/ }),
    
    Romain CREY's avatar
    Romain CREY committed
    /***/ (function(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.
     */
    
    /*
     * "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;
    
    
    /***/ }),
    
    /* 91 */
    /***/ (function(module, exports) {
    
    // generated by genversion
    module.exports = '2.5.0'
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    /***/ }),
    
    Romain CREY's avatar
    Romain CREY committed
    /***/ (function(module, exports, __webpack_require__) {
    
    "use strict";
    
    
    
    var jsonSafeStringify = __webpack_require__(7)
    var crypto = __webpack_require__(93)
    var Buffer = __webpack_require__(94).Buffer
    
    Romain CREY's avatar
    Romain CREY committed
    
    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
    
    
    /***/ }),
    
    Romain CREY's avatar
    Romain CREY committed
    /***/ (function(module, exports) {
    
    module.exports = require("crypto");
    
    /***/ }),
    
    Romain CREY's avatar
    Romain CREY committed
    /***/ (function(module, exports, __webpack_require__) {
    
    /* eslint-disable node/no-deprecated-api */
    
    var buffer = __webpack_require__(95)
    
    Romain CREY's avatar
    Romain CREY committed
    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)
    }
    
    // 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)
    }
    
    
    /***/ }),
    
    Romain CREY's avatar
    Romain CREY committed
    /***/ (function(module, exports) {
    
    module.exports = require("buffer");
    
    /***/ }),
    
    Romain CREY's avatar
    Romain CREY committed
    /***/ (function(module, exports, __webpack_require__) {
    
    "use strict";
    
    
    
    var http = __webpack_require__(97)
    var https = __webpack_require__(98)
    var url = __webpack_require__(82)
    var util = __webpack_require__(9)
    var stream = __webpack_require__(99)
    var zlib = __webpack_require__(100)
    var aws2 = __webpack_require__(101)
    var aws4 = __webpack_require__(102)
    var httpSignature = __webpack_require__(105)
    var mime = __webpack_require__(156)
    var caseless = __webpack_require__(160)
    var ForeverAgent = __webpack_require__(161)
    var FormData = __webpack_require__(163)
    var extend = __webpack_require__(78)
    var isstream = __webpack_require__(182)
    var isTypedArray = __webpack_require__(183).strict
    var helpers = __webpack_require__(92)
    var cookies = __webpack_require__(79)
    var getProxyFromURI = __webpack_require__(184)
    var Querystring = __webpack_require__(185).Querystring
    var Har = __webpack_require__(191).Har
    var Auth = __webpack_require__(260).Auth
    var OAuth = __webpack_require__(264).OAuth
    var hawk = __webpack_require__(266)
    var Multipart = __webpack_require__(267).Multipart
    var Redirect = __webpack_require__(268).Redirect
    var Tunnel = __webpack_require__(269).Tunnel
    var now = __webpack_require__(272)
    var Buffer = __webpack_require__(94).Buffer
    
    Romain CREY's avatar
    Romain CREY committed
    12283 12284 12285 12286 12287 12288 12289 12290 12291 12292 12293 12294 12295 12296 12297 12298 12299 12300 12301 12302 12303 12304 12305 12306 12307 12308 12309 12310 12311 12312 12313 12314 12315 12316 12317 12318 12319 12320 12321 12322 12323 12324 12325 12326 12327 12328 12329 12330 12331 12332 12333 12334 12335 12336 12337 12338 12339 12340 12341 12342 12343 12344 12345 12346 12347 12348 12349 12350 12351 12352 12353 12354 12355 12356 12357 12358 12359 12360 12361 12362 12363 12364 12365 12366 12367 12368 12369 12370 12371 12372 12373 12374 12375 12376 12377 12378 12379 12380 12381 12382 12383 12384 12385 12386 12387 12388 12389 12390 12391 12392 12393 12394 12395 12396 12397 12398 12399 12400 12401 12402 12403 12404 12405 12406 12407 12408 12409 12410 12411 12412 12413 12414 12415 12416 12417 12418 12419 12420 12421 12422 12423 12424 12425 12426 12427 12428 12429 12430 12431 12432 12433 12434 12435 12436 12437 12438 12439 12440 12441 12442 12443 12444 12445 12446 12447 12448 12449 12450 12451 12452 12453 12454 12455 12456 12457 12458 12459 12460 12461 12462 12463 12464 12465 12466 12467 12468 12469 12470 12471 12472 12473 12474 12475 12476 12477 12478 12479 12480 12481 12482 12483 12484 12485 12486 12487 12488 12489 12490 12491 12492 12493 12494 12495 12496 12497 12498 12499 12500 12501 12502 12503 12504 12505 12506 12507 12508 12509 12510 12511 12512 12513 12514 12515 12516 12517 12518 12519 12520 12521 12522 12523 12524 12525 12526 12527 12528 12529 12530 12531 12532 12533 12534 12535 12536 12537 12538 12539 12540 12541 12542 12543 12544 12545 12546 12547 12548 12549 12550 12551 12552 12553 12554 12555 12556 12557 12558 12559 12560 12561 12562 12563 12564 12565 12566 12567 12568 12569 12570 12571 12572 12573 12574 12575 12576 12577 12578 12579 12580 12581 12582 12583 12584 12585 12586 12587 12588 12589 12590 12591 12592 12593 12594 12595 12596 12597 12598 12599 12600 12601 12602 12603 12604 12605 12606 12607 12608 12609 12610 12611 12612 12613 12614 12615 12616 12617 12618 12619 12620 12621 12622 12623 12624 12625 12626 12627 12628 12629 12630 12631 12632 12633 12634 12635 12636 12637 12638 12639 12640 12641 12642 12643 12644 12645 12646 12647 12648 12649 12650 12651 12652 12653 12654 12655 12656 12657 12658 12659 12660 12661 12662 12663 12664 12665 12666 12667 12668 12669 12670 12671 12672 12673 12674 12675 12676 12677 12678 12679 12680 12681 12682 12683 12684 12685 12686 12687 12688 12689 12690 12691 12692 12693 12694 12695 12696 12697 12698 12699 12700 12701 12702 12703 12704 12705 12706 12707 12708 12709 12710 12711 12712 12713 12714 12715 12716 12717 12718 12719 12720 12721 12722 12723 12724 12725 12726 12727 12728 12729 12730 12731 12732 12733 12734 12735 12736 12737 12738 12739 12740 12741 12742 12743 12744 12745 12746 12747 12748 12749 12750 12751 12752 12753 12754 12755 12756 12757 12758 12759 12760 12761 12762 12763 12764 12765 12766 12767 12768 12769 12770 12771 12772 12773 12774 12775 12776 12777 12778 12779 12780 12781 12782 12783 12784 12785 12786 12787 12788 12789 12790 12791 12792 12793 12794 12795 12796 12797 12798 12799 12800 12801 12802 12803 12804 12805 12806 12807 12808 12809 12810 12811 12812 12813 12814 12815 12816 12817 12818 12819 12820 12821 12822 12823 12824 12825 12826 12827 12828 12829 12830 12831 12832 12833 12834 12835 12836 12837 12838 12839 12840 12841 12842 12843 12844 12845 12846 12847 12848 12849 12850 12851 12852 12853 12854 12855 12856 12857 12858 12859 12860 12861 12862 12863 12864 12865 12866 12867 12868 12869 12870 12871 12872 12873 12874 12875 12876 12877 12878 12879 12880 12881 12882 12883 12884 12885 12886 12887 12888 12889 12890 12891 12892 12893 12894 12895 12896 12897 12898 12899 12900 12901 12902 12903 12904 12905 12906 12907 12908 12909 12910 12911 12912 12913 12914 12915 12916 12917 12918 12919 12920 12921 12922 12923 12924 12925 12926 12927 12928 12929 12930 12931 12932 12933 12934 12935 12936 12937 12938 12939 12940 12941 12942 12943 12944 12945 12946 12947 12948 12949 12950 12951 12952 12953 12954 12955 12956 12957 12958 12959 12960 12961 12962 12963 12964 12965 12966 12967 12968 12969 12970 12971 12972 12973 12974 12975 12976 12977 12978 12979 12980 12981 12982 12983 12984 12985 12986 12987 12988 12989 12990 12991 12992 12993 12994 12995 12996 12997 12998 12999 13000
    
    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
      }
    
      if (self.passphrase) {
        options.passphrase = self.passphrase
      }
    
      var poolKey = ''
    
      // different types of agents are in different pools
      if (Agent !== self.httpModule.Agent) {
        poolKey += Agent.name
      }
    
      // ca option is only relevant if proxy or destination are https
      var proxy = self.proxy
      if (typeof proxy === 'string') {
        proxy = url.parse(proxy)
      }
      var isHttps = (proxy && proxy.protocol === 'https:') || this.uri.protocol === 'https:'
    
      if (isHttps) {
        if (options.ca) {
          if (poolKey) {
            poolKey += ':'
          }
          poolKey += options.ca
        }
    
        if (typeof options.rejectUnauthorized !== 'undefined') {
          if (poolKey) {
            poolKey += ':'
          }
          poolKey += options.rejectUnauthorized
        }
    
        if (options.cert) {
          if (poolKey) {
            poolKey += ':'
          }
          poolKey += options.cert.toString('ascii') + options.key.toString('ascii')
        }
    
        if (options.pfx) {
          if (poolKey) {
            poolKey += ':'
          }
          poolKey += options.pfx.toString('ascii')
        }
    
        if (options.ciphers) {
          if (poolKey) {
            poolKey += ':'
          }
          poolKey += options.ciphers
        }
    
        if (options.secureProtocol) {
          if (poolKey) {
            poolKey += ':'
          }
          poolKey += options.secureProtocol
        }
    
        if (options.secureOptions) {
          if (poolKey) {
            poolKey += ':'
          }
          poolKey += options.secureOptions
        }
      }
    
      if (self.pool === globalPool && !poolKey && Object.keys(options).length === 0 && self.httpModule.globalAgent) {
        // not doing anything special.  Use the globalAgent
        return self.httpModule.globalAgent
      }
    
      // we're using a stored agent.  Make sure it's protocol-specific
      poolKey = self.uri.protocol + poolKey
    
      // generate a new agent for this setting if none yet exists
      if (!self.pool[poolKey]) {
        self.pool[poolKey] = new Agent(options)
        // properly set maxSockets on new agents
        if (self.pool.maxSockets) {
          self.pool[poolKey].maxSockets = self.pool.maxSockets
        }
      }
    
      return self.pool[poolKey]
    }
    
    Request.prototype.start = function () {
      // start() is called once we are ready to send the outgoing HTTP request.
      // this is usually called on the first write(), end() or on nextTick()
      var self = this
    
      if (self.timing) {
        // All timings will be relative to this request's startTime.  In order to do this,
        // we need to capture the wall-clock start time (via Date), immediately followed
        // by the high-resolution timer (via now()).  While these two won't be set
        // at the _exact_ same time, they should be close enough to be able to calculate
        // high-resolution, monotonically non-decreasing timestamps relative to startTime.
        var startTime = new Date().getTime()
        var startTimeNow = now()
      }
    
      if (self._aborted) {
        return
      }
    
      self._started = true
      self.method = self.method || 'GET'
      self.href = self.uri.href
    
      if (self.src && self.src.stat && self.src.stat.size && !self.hasHeader('content-length')) {
        self.setHeader('content-length', self.src.stat.size)
      }
      if (self._aws) {
        self.aws(self._aws, true)
      }
    
      // We have a method named auth, which is completely different from the http.request
      // auth option.  If we don't remove it, we're gonna have a bad time.
      var reqOptions = copy(self)
      delete reqOptions.auth
    
      debug('make request', self.uri.href)
    
      // node v6.8.0 now supports a `timeout` value in `http.request()`, but we
      // should delete it for now since we handle timeouts manually for better
      // consistency with node versions before v6.8.0
      delete reqOptions.timeout