UNPKG

@crawly/superagent

Version:

elegant & feature rich browser / node HTTP with a fluent API

1,393 lines (1,097 loc) 122 kB
"use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } /** * Module dependencies. */ // eslint-disable-next-line node/no-deprecated-api var _require = require('url'), parse = _require.parse, format = _require.format, resolve = _require.resolve; var Stream = require('stream'); var https = require('https'); var http = require('http'); var fs = require('fs'); var zlib = require('zlib'); var util = require('util'); var qs = require('qs'); var mime = require('mime'); var methods = require('methods'); var FormData = require('form-data'); var formidable = require('formidable'); var debug = require('debug')('superagent'); var CookieJar = require('cookiejar'); var semver = require('semver'); var safeStringify = require('fast-safe-stringify'); var utils = require('../utils'); var RequestBase = require('../request-base'); var _require2 = require('./unzip'), unzip = _require2.unzip; var Response = require('./response'); var http2; if (semver.gte(process.version, 'v10.10.0')) http2 = require('./http2wrapper'); function request(method, url) { // callback if (typeof url === 'function') { return new exports.Request('GET', method).end(url); } // url first if (arguments.length === 1) { return new exports.Request('GET', method); } return new exports.Request(method, url); } module.exports = request; exports = module.exports; /** * Expose `Request`. */ exports.Request = Request; /** * Expose the agent function */ exports.agent = require('./agent'); /** * Noop. */ function noop() {} /** * Expose `Response`. */ exports.Response = Response; /** * Define "form" mime type. */ mime.define({ 'application/x-www-form-urlencoded': ['form', 'urlencoded', 'form-data'] }, true); /** * Protocol map. */ exports.protocols = { 'http:': http, 'https:': https, 'http2:': http2 }; /** * Default serialization map. * * superagent.serialize['application/xml'] = function(obj){ * return 'generated xml here'; * }; * */ exports.serialize = { 'application/x-www-form-urlencoded': qs.stringify, 'application/json': safeStringify }; /** * Default parsers. * * superagent.parse['application/xml'] = function(res, fn){ * fn(null, res); * }; * */ exports.parse = require('./parsers'); /** * Default buffering map. Can be used to set certain * response types to buffer/not buffer. * * superagent.buffer['application/xml'] = true; */ exports.buffer = {}; /** * Initialize internal header tracking properties on a request instance. * * @param {Object} req the instance * @api private */ function _initHeaders(req) { req._header = {// coerces header names to lowercase }; req.header = {// preserves header name case }; } /** * Initialize a new `Request` with the given `method` and `url`. * * @param {String} method * @param {String|Object} url * @api public */ function Request(method, url) { Stream.call(this); if (typeof url !== 'string') url = format(url); this._enableHttp2 = Boolean(process.env.HTTP2_TEST); // internal only this._agent = false; this._formData = null; this.method = method; this.url = url; _initHeaders(this); this.writable = true; this._redirects = 0; this.redirects(method === 'HEAD' ? 0 : 5); this.cookies = ''; this.qs = {}; this._query = []; this.qsRaw = this._query; // Unused, for backwards compatibility only this._redirectList = []; this._streamRequest = false; this.once('end', this.clearTimeout.bind(this)); } /** * Inherit from `Stream` (which inherits from `EventEmitter`). * Mixin `RequestBase`. */ util.inherits(Request, Stream); // eslint-disable-next-line new-cap RequestBase(Request.prototype); /** * Enable or Disable http2. * * Enable http2. * * ``` js * request.get('http://localhost/') * .http2() * .end(callback); * * request.get('http://localhost/') * .http2(true) * .end(callback); * ``` * * Disable http2. * * ``` js * request = request.http2(); * request.get('http://localhost/') * .http2(false) * .end(callback); * ``` * * @param {Boolean} enable * @return {Request} for chaining * @api public */ Request.prototype.http2 = function (bool) { if (exports.protocols['http2:'] === undefined) { throw new Error('superagent: this version of Node.js does not support http2'); } this._enableHttp2 = bool === undefined ? true : bool; return this; }; /** * Queue the given `file` as an attachment to the specified `field`, * with optional `options` (or filename). * * ``` js * request.post('http://localhost/upload') * .attach('field', Buffer.from('<b>Hello world</b>'), 'hello.html') * .end(callback); * ``` * * A filename may also be used: * * ``` js * request.post('http://localhost/upload') * .attach('files', 'image.jpg') * .end(callback); * ``` * * @param {String} field * @param {String|fs.ReadStream|Buffer} file * @param {String|Object} options * @return {Request} for chaining * @api public */ Request.prototype.attach = function (field, file, options) { if (file) { if (this._data) { throw new Error("superagent can't mix .send() and .attach()"); } var o = options || {}; if (typeof options === 'string') { o = { filename: options }; } if (typeof file === 'string') { if (!o.filename) o.filename = file; debug('creating `fs.ReadStream` instance for file: %s', file); file = fs.createReadStream(file); } else if (!o.filename && file.path) { o.filename = file.path; } this._getFormData().append(field, file, o); } return this; }; Request.prototype._getFormData = function () { var _this = this; if (!this._formData) { this._formData = new FormData(); this._formData.on('error', function (err) { debug('FormData error', err); if (_this.called) { // The request has already finished and the callback was called. // Silently ignore the error. return; } _this.callback(err); _this.abort(); }); } return this._formData; }; /** * Gets/sets the `Agent` to use for this HTTP request. The default (if this * function is not called) is to opt out of connection pooling (`agent: false`). * * @param {http.Agent} agent * @return {http.Agent} * @api public */ Request.prototype.agent = function (agent) { if (arguments.length === 0) return this._agent; this._agent = agent; return this; }; /** * Set _Content-Type_ response header passed through `mime.getType()`. * * Examples: * * request.post('/') * .type('xml') * .send(xmlstring) * .end(callback); * * request.post('/') * .type('json') * .send(jsonstring) * .end(callback); * * request.post('/') * .type('application/json') * .send(jsonstring) * .end(callback); * * @param {String} type * @return {Request} for chaining * @api public */ Request.prototype.type = function (type) { return this.set('Content-Type', type.includes('/') ? type : mime.getType(type)); }; /** * Set _Accept_ response header passed through `mime.getType()`. * * Examples: * * superagent.types.json = 'application/json'; * * request.get('/agent') * .accept('json') * .end(callback); * * request.get('/agent') * .accept('application/json') * .end(callback); * * @param {String} accept * @return {Request} for chaining * @api public */ Request.prototype.accept = function (type) { return this.set('Accept', type.includes('/') ? type : mime.getType(type)); }; /** * Add query-string `val`. * * Examples: * * request.get('/shoes') * .query('size=10') * .query({ color: 'blue' }) * * @param {Object|String} val * @return {Request} for chaining * @api public */ Request.prototype.query = function (val) { if (typeof val === 'string') { this._query.push(val); } else { Object.assign(this.qs, val); } return this; }; /** * Write raw `data` / `encoding` to the socket. * * @param {Buffer|String} data * @param {String} encoding * @return {Boolean} * @api public */ Request.prototype.write = function (data, encoding) { var req = this.request(); if (!this._streamRequest) { this._streamRequest = true; } return req.write(data, encoding); }; /** * Pipe the request body to `stream`. * * @param {Stream} stream * @param {Object} options * @return {Stream} * @api public */ Request.prototype.pipe = function (stream, options) { this.piped = true; // HACK... this.buffer(false); this.end(); return this._pipeContinue(stream, options); }; Request.prototype._pipeContinue = function (stream, options) { var _this2 = this; this.req.once('response', function (res) { // redirect if (isRedirect(res.statusCode) && _this2._redirects++ !== _this2._maxRedirects) { return _this2._redirect(res) === _this2 ? _this2._pipeContinue(stream, options) : undefined; } _this2.res = res; _this2._emitResponse(); if (_this2._aborted) return; if (_this2._shouldUnzip(res)) { var unzipObj = zlib.createUnzip(); unzipObj.on('error', function (err) { if (err && err.code === 'Z_BUF_ERROR') { // unexpected end of file is ignored by browsers and curl stream.emit('end'); return; } stream.emit('error', err); }); res.pipe(unzipObj).pipe(stream, options); } else { res.pipe(stream, options); } res.once('end', function () { _this2.emit('end'); }); }); return stream; }; /** * Enable / disable buffering. * * @return {Boolean} [val] * @return {Request} for chaining * @api public */ Request.prototype.buffer = function (val) { this._buffer = val !== false; return this; }; /** * Redirect to `url * * @param {IncomingMessage} res * @return {Request} for chaining * @api private */ Request.prototype._redirect = function (res) { var url = res.headers.location; if (!url) { return this.callback(new Error('No location header for redirect'), res); } debug('redirect %s -> %s', this.url, url); // location url = resolve(this.url, url); // ensure the response is being consumed // this is required for Node v0.10+ res.resume(); var headers = this.req.getHeaders ? this.req.getHeaders() : this.req._headers; var changesOrigin = parse(url).host !== parse(this.url).host; // implementation of 302 following defacto standard if (res.statusCode === 301 || res.statusCode === 302) { // strip Content-* related fields // in case of POST etc headers = utils.cleanHeader(headers, changesOrigin); // force GET this.method = this.method === 'HEAD' ? 'HEAD' : 'GET'; // clear data this._data = null; } // 303 is always GET if (res.statusCode === 303) { // strip Content-* related fields // in case of POST etc headers = utils.cleanHeader(headers, changesOrigin); // force method this.method = 'GET'; // clear data this._data = null; } // 307 preserves method // 308 preserves method delete headers.host; delete this.req; delete this._formData; // remove all add header except User-Agent _initHeaders(this); // redirect this._endCalled = false; this.url = url; this.qs = {}; this._query.length = 0; this.set(headers); this.emit('redirect', res); this._redirectList.push(this.url); this.end(this._callback); return this; }; /** * Set Authorization field value with `user` and `pass`. * * Examples: * * .auth('tobi', 'learnboost') * .auth('tobi:learnboost') * .auth('tobi') * .auth(accessToken, { type: 'bearer' }) * * @param {String} user * @param {String} [pass] * @param {Object} [options] options with authorization type 'basic' or 'bearer' ('basic' is default) * @return {Request} for chaining * @api public */ Request.prototype.auth = function (user, pass, options) { if (arguments.length === 1) pass = ''; if (_typeof(pass) === 'object' && pass !== null) { // pass is optional and can be replaced with options options = pass; pass = ''; } if (!options) { options = { type: 'basic' }; } var encoder = function encoder(string) { return Buffer.from(string).toString('base64'); }; return this._auth(user, pass, options, encoder); }; /** * Set the certificate authority option for https request. * * @param {Buffer | Array} cert * @return {Request} for chaining * @api public */ Request.prototype.ca = function (cert) { this._ca = cert; return this; }; /** * Set the client certificate key option for https request. * * @param {Buffer | String} cert * @return {Request} for chaining * @api public */ Request.prototype.key = function (cert) { this._key = cert; return this; }; /** * Set the key, certificate, and CA certs of the client in PFX or PKCS12 format. * * @param {Buffer | String} cert * @return {Request} for chaining * @api public */ Request.prototype.pfx = function (cert) { if (_typeof(cert) === 'object' && !Buffer.isBuffer(cert)) { this._pfx = cert.pfx; this._passphrase = cert.passphrase; } else { this._pfx = cert; } return this; }; /** * Set the client certificate option for https request. * * @param {Buffer | String} cert * @return {Request} for chaining * @api public */ Request.prototype.cert = function (cert) { this._cert = cert; return this; }; /** * Do not reject expired or invalid TLS certs. * sets `rejectUnauthorized=true`. Be warned that this allows MITM attacks. * * @return {Request} for chaining * @api public */ Request.prototype.disableTLSCerts = function () { this._disableTLSCerts = true; return this; }; /** * Return an http[s] request. * * @return {OutgoingMessage} * @api private */ // eslint-disable-next-line complexity Request.prototype.request = function () { var _this3 = this; if (this.req) return this.req; var options = {}; try { var query = qs.stringify(this.qs, { indices: false, strictNullHandling: true }); if (query) { this.qs = {}; this._query.push(query); } this._finalizeQueryString(); } catch (err) { return this.emit('error', err); } var url = this.url; var retries = this._retries; // Capture backticks as-is from the final query string built above. // Note: this'll only find backticks entered in req.query(String) // calls, because qs.stringify unconditionally encodes backticks. var queryStringBackticks; if (url.includes('`')) { var queryStartIndex = url.indexOf('?'); if (queryStartIndex !== -1) { var queryString = url.slice(queryStartIndex + 1); queryStringBackticks = queryString.match(/`|%60/g); } } // default to http:// if (url.indexOf('http') !== 0) url = "http://".concat(url); url = parse(url); // See https://github.com/visionmedia/superagent/issues/1367 if (queryStringBackticks) { var i = 0; url.query = url.query.replace(/%60/g, function () { return queryStringBackticks[i++]; }); url.search = "?".concat(url.query); url.path = url.pathname + url.search; } // support unix sockets if (/^https?\+unix:/.test(url.protocol) === true) { // get the protocol url.protocol = "".concat(url.protocol.split('+')[0], ":"); // get the socket, path var unixParts = url.path.match(/^([^/]+)(.+)$/); options.socketPath = unixParts[1].replace(/%2F/g, '/'); url.path = unixParts[2]; } // Override IP address of a hostname if (this._connectOverride) { var _url = url, hostname = _url.hostname; var match = hostname in this._connectOverride ? this._connectOverride[hostname] : this._connectOverride['*']; if (match) { // backup the real host if (!this._header.host) { this.set('host', url.host); } var newHost; var newPort; if (_typeof(match) === 'object') { newHost = match.host; newPort = match.port; } else { newHost = match; newPort = url.port; } // wrap [ipv6] url.host = /:/.test(newHost) ? "[".concat(newHost, "]") : newHost; if (newPort) { url.host += ":".concat(newPort); url.port = newPort; } url.hostname = newHost; } } // options options.method = this.method; options.port = url.port; options.path = url.path; options.host = url.hostname; options.ca = this._ca; options.key = this._key; options.pfx = this._pfx; options.cert = this._cert; options.passphrase = this._passphrase; options.agent = this._agent; options.rejectUnauthorized = typeof this._disableTLSCerts === 'boolean' ? !this._disableTLSCerts : process.env.NODE_TLS_REJECT_UNAUTHORIZED !== '0'; // Allows request.get('https://1.2.3.4/').set('Host', 'example.com') if (this._header.host) { options.servername = this._header.host.replace(/:\d+$/, ''); } if (this._trustLocalhost && /^(?:localhost|127\.0\.0\.\d+|(0*:)+:0*1)$/.test(url.hostname)) { options.rejectUnauthorized = false; } // initiate request var mod = this._enableHttp2 ? exports.protocols['http2:'].setProtocol(url.protocol) : exports.protocols[url.protocol]; // request this.req = mod.request(options); var req = this.req; // set tcp no delay req.setNoDelay(true); if (options.method !== 'HEAD') { req.setHeader('Accept-Encoding', 'gzip, deflate'); } this.protocol = url.protocol; this.host = url.host; // expose events req.once('drain', function () { _this3.emit('drain'); }); req.on('error', function (err) { // flag abortion here for out timeouts // because node will emit a faux-error "socket hang up" // when request is aborted before a connection is made if (_this3._aborted) return; // if not the same, we are in the **old** (cancelled) request, // so need to continue (same as for above) if (_this3._retries !== retries) return; // if we've received a response then we don't want to let // an error in the request blow up the response if (_this3.response) return; _this3.callback(err); }); // auth if (url.auth) { var auth = url.auth.split(':'); this.auth(auth[0], auth[1]); } if (this.username && this.password) { this.auth(this.username, this.password); } for (var key in this.header) { if (Object.prototype.hasOwnProperty.call(this.header, key)) req.setHeader(key, this.header[key]); } // add cookies if (this.cookies) { if (Object.prototype.hasOwnProperty.call(this._header, 'cookie')) { // merge var tmpJar = new CookieJar.CookieJar(); tmpJar.setCookies(this._header.cookie.split(';')); tmpJar.setCookies(this.cookies.split(';')); req.setHeader('Cookie', tmpJar.getCookies(CookieJar.CookieAccessInfo.All).toValueString()); } else { req.setHeader('Cookie', this.cookies); } } return req; }; /** * Invoke the callback with `err` and `res` * and handle arity check. * * @param {Error} err * @param {Response} res * @api private */ Request.prototype.callback = function (err, res) { var _this4 = this; return new Promise(function (resolve) { var fnShouldRetry = function fnShouldRetry(shouldRetry) { if (shouldRetry) { _this4._retry().then(resolve).catch(function (err_) { err = err_; fnShouldRetry(false); }); return; } // Avoid the error which is emitted from 'socket hang up' to cause the fn undefined error on JS runtime. var fn = _this4._callback || noop; _this4.clearTimeout(); if (_this4.called) return; _this4.called = true; if (!err) { try { if (!_this4._isResponseOK(res)) { var msg = 'Unsuccessful HTTP response'; if (res) { msg = http.STATUS_CODES[res.status] || msg; } err = new Error(msg); err.status = res ? res.status : undefined; } } catch (err_) { err = err_; } } // It's important that the callback is called outside try/catch // to avoid double callback if (!err) { fn(null, res); return resolve(); } err.response = res; if (_this4._maxRetries) err.retries = _this4._retries - 1; // only emit error event if there is a listener // otherwise we assume the callback to `.end()` will get the error if (err && _this4.listeners('error').length > 0) { _this4.emit('error', err); } fn(err, res); return resolve(); }; _this4._shouldRetry(err, res).then(fnShouldRetry); }); }; /** * Check if `obj` is a host object, * * @param {Object} obj host object * @return {Boolean} is a host object * @api private */ Request.prototype._isHost = function (obj) { return Buffer.isBuffer(obj) || obj instanceof Stream || obj instanceof FormData; }; /** * Initiate request, invoking callback `fn(err, res)` * with an instanceof `Response`. * * @param {Function} fn * @return {Request} for chaining * @api public */ Request.prototype._emitResponse = function (body, files) { var response = new Response(this); this.response = response; response.redirects = this._redirectList; if (undefined !== body) { response.body = body; } response.files = files; if (this._endCalled) { response.pipe = function () { throw new Error("end() has already been called, so it's too late to start piping"); }; } this.emit('response', response); return response; }; Request.prototype.end = function (fn) { this.request(); debug('%s %s', this.method, this.url); if (this._endCalled) { throw new Error('.end() was called twice. This is not supported in superagent'); } this._endCalled = true; // store callback this._callback = fn || noop; this._end(); }; Request.prototype._end = function () { var _this5 = this; if (this._aborted) return this.callback(new Error('The request has been aborted even before .end() was called')); var data = this._data; var req = this.req; var method = this.method; this._setTimeouts(); // body if (method !== 'HEAD' && !req._headerSent) { // serialize stuff if (typeof data !== 'string') { var contentType = req.getHeader('Content-Type'); // Parse out just the content type from the header (ignore the charset) if (contentType) contentType = contentType.split(';')[0]; var serialize = this._serializer || exports.serialize[contentType]; if (!serialize && isJSON(contentType)) { serialize = exports.serialize['application/json']; } if (serialize) data = serialize(data); } // content-length if (data && !req.getHeader('Content-Length')) { req.setHeader('Content-Length', Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data)); } } // response // eslint-disable-next-line complexity req.once('response', function (res) { debug('%s %s -> %s', _this5.method, _this5.url, res.statusCode); if (_this5._responseTimeoutTimer) { clearTimeout(_this5._responseTimeoutTimer); } if (_this5.piped) { return; } var max = _this5._maxRedirects; var mime = utils.type(res.headers['content-type'] || '') || 'text/plain'; var type = mime.split('/')[0]; var multipart = type === 'multipart'; var redirect = isRedirect(res.statusCode); var responseType = _this5._responseType; _this5.res = res; // redirect if (redirect && _this5._redirects++ !== max) { return _this5._redirect(res); } if (_this5.method === 'HEAD') { _this5.emit('end'); _this5.callback(null, _this5._emitResponse()); return; } // zlib support if (_this5._shouldUnzip(res)) { unzip(req, res); } var buffer = _this5._buffer; if (buffer === undefined && mime in exports.buffer) { buffer = Boolean(exports.buffer[mime]); } var parser = _this5._parser; if (undefined === buffer) { if (parser) { console.warn("A custom superagent parser has been set, but buffering strategy for the parser hasn't been configured. Call `req.buffer(true or false)` or set `superagent.buffer[mime] = true or false`"); buffer = true; } } if (!parser) { if (responseType) { parser = exports.parse.image; // It's actually a generic Buffer buffer = true; } else if (multipart) { var form = new formidable.IncomingForm(); parser = form.parse.bind(form); buffer = true; } else if (isImageOrVideo(mime)) { parser = exports.parse.image; buffer = true; // For backwards-compatibility buffering default is ad-hoc MIME-dependent } else if (exports.parse[mime]) { parser = exports.parse[mime]; } else if (type === 'text') { parser = exports.parse.text; buffer = buffer !== false; // everyone wants their own white-labeled json } else if (isJSON(mime)) { parser = exports.parse['application/json']; buffer = buffer !== false; } else if (buffer) { parser = exports.parse.text; } else if (undefined === buffer) { parser = exports.parse.image; // It's actually a generic Buffer buffer = true; } } // by default only buffer text/*, json and messed up thing from hell if (undefined === buffer && isText(mime) || isJSON(mime)) { buffer = true; } _this5._resBuffered = buffer; var parserHandlesEnd = false; if (buffer) { // Protectiona against zip bombs and other nuisance var responseBytesLeft = _this5._maxResponseSize || 200000000; res.on('data', function (buf) { responseBytesLeft -= buf.byteLength || buf.length; if (responseBytesLeft < 0) { // This will propagate through error event var err = new Error('Maximum response size reached'); err.code = 'ETOOLARGE'; // Parsers aren't required to observe error event, // so would incorrectly report success parserHandlesEnd = false; // Will emit error event res.destroy(err); } }); } if (parser) { try { // Unbuffered parsers are supposed to emit response early, // which is weird BTW, because response.body won't be there. parserHandlesEnd = buffer; parser(res, function (err, obj, files) { if (_this5.timedout) { // Timeout has already handled all callbacks return; } // Intentional (non-timeout) abort is supposed to preserve partial response, // even if it doesn't parse. if (err && !_this5._aborted) { return _this5.callback(err); } if (parserHandlesEnd) { _this5.emit('end'); _this5.callback(null, _this5._emitResponse(obj, files)); } }); } catch (err) { _this5.callback(err); return; } } _this5.res = res; // unbuffered if (!buffer) { debug('unbuffered %s %s', _this5.method, _this5.url); _this5.callback(null, _this5._emitResponse()); if (multipart) return; // allow multipart to handle end event res.once('end', function () { debug('end %s %s', _this5.method, _this5.url); _this5.emit('end'); }); return; } // terminating events res.once('error', function (err) { parserHandlesEnd = false; _this5.callback(err, null); }); if (!parserHandlesEnd) res.once('end', function () { debug('end %s %s', _this5.method, _this5.url); // TODO: unless buffering emit earlier to stream _this5.emit('end'); _this5.callback(null, _this5._emitResponse()); }); }); this.emit('request', this); var getProgressMonitor = function getProgressMonitor() { var lengthComputable = true; var total = req.getHeader('Content-Length'); var loaded = 0; var progress = new Stream.Transform(); progress._transform = function (chunk, encoding, cb) { loaded += chunk.length; _this5.emit('progress', { direction: 'upload', lengthComputable: lengthComputable, loaded: loaded, total: total }); cb(null, chunk); }; return progress; }; var bufferToChunks = function bufferToChunks(buffer) { var chunkSize = 16 * 1024; // default highWaterMark value var chunking = new Stream.Readable(); var totalLength = buffer.length; var remainder = totalLength % chunkSize; var cutoff = totalLength - remainder; for (var i = 0; i < cutoff; i += chunkSize) { var chunk = buffer.slice(i, i + chunkSize); chunking.push(chunk); } if (remainder > 0) { var remainderBuffer = buffer.slice(-remainder); chunking.push(remainderBuffer); } chunking.push(null); // no more data return chunking; }; // if a FormData instance got created, then we send that as the request body var formData = this._formData; if (formData) { // set headers var headers = formData.getHeaders(); for (var i in headers) { if (Object.prototype.hasOwnProperty.call(headers, i)) { debug('setting FormData header: "%s: %s"', i, headers[i]); req.setHeader(i, headers[i]); } } // attempt to get "Content-Length" header // eslint-disable-next-line handle-callback-err formData.getLength(function (err, length) { // TODO: Add chunked encoding when no length (if err) debug('got FormData Content-Length: %s', length); if (typeof length === 'number') { req.setHeader('Content-Length', length); } formData.pipe(getProgressMonitor()).pipe(req); }); } else if (Buffer.isBuffer(data)) { bufferToChunks(data).pipe(getProgressMonitor()).pipe(req); } else { req.end(data); } }; // Check whether response has a non-0-sized gzip-encoded body Request.prototype._shouldUnzip = function (res) { if (res.statusCode === 204 || res.statusCode === 304) { // These aren't supposed to have any body return false; } // header content is a string, and distinction between 0 and no information is crucial if (res.headers['content-length'] === '0') { // We know that the body is empty (unfortunately, this check does not cover chunked encoding) return false; } // console.log(res); return /^\s*(?:deflate|gzip)\s*$/.test(res.headers['content-encoding']); }; /** * Overrides DNS for selected hostnames. Takes object mapping hostnames to IP addresses. * * When making a request to a URL with a hostname exactly matching a key in the object, * use the given IP address to connect, instead of using DNS to resolve the hostname. * * A special host `*` matches every hostname (keep redirects in mind!) * * request.connect({ * 'test.example.com': '127.0.0.1', * 'ipv6.example.com': '::1', * }) */ Request.prototype.connect = function (connectOverride) { if (typeof connectOverride === 'string') { this._connectOverride = { '*': connectOverride }; } else if (_typeof(connectOverride) === 'object') { this._connectOverride = connectOverride; } else { this._connectOverride = undefined; } return this; }; Request.prototype.trustLocalhost = function (toggle) { this._trustLocalhost = toggle === undefined ? true : toggle; return this; }; // generate HTTP verb methods if (!methods.includes('del')) { // create a copy so we don't cause conflicts with // other packages using the methods package and // npm 3.x methods = methods.slice(0); methods.push('del'); } methods.forEach(function (method) { var name = method; method = method === 'del' ? 'delete' : method; method = method.toUpperCase(); request[name] = function (url, data, fn) { var req = request(method, url); if (typeof data === 'function') { fn = data; data = null; } if (data) { if (method === 'GET' || method === 'HEAD') { req.query(data); } else { req.send(data); } } if (fn) req.end(fn); return req; }; }); /** * Check if `mime` is text and should be buffered. * * @param {String} mime * @return {Boolean} * @api public */ function isText(mime) { var parts = mime.split('/'); var type = parts[0]; var subtype = parts[1]; return type === 'text' || subtype === 'x-www-form-urlencoded'; } function isImageOrVideo(mime) { var type = mime.split('/')[0]; return type === 'image' || type === 'video'; } /** * Check if `mime` is json or has +json structured syntax suffix. * * @param {String} mime * @return {Boolean} * @api private */ function isJSON(mime) { // should match /json or +json // but not /json-seq return /[/+]json($|[^-\w])/.test(mime); } /** * Check if we should follow the redirect `code`. * * @param {Number} code * @return {Boolean} * @api private */ function isRedirect(code) { return [301, 302, 303, 305, 307, 308].includes(code); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ub2RlL2luZGV4LmpzIl0sIm5hbWVzIjpbInJlcXVpcmUiLCJwYXJzZSIsImZvcm1hdCIsInJlc29sdmUiLCJTdHJlYW0iLCJodHRwcyIsImh0dHAiLCJmcyIsInpsaWIiLCJ1dGlsIiwicXMiLCJtaW1lIiwibWV0aG9kcyIsIkZvcm1EYXRhIiwiZm9ybWlkYWJsZSIsImRlYnVnIiwiQ29va2llSmFyIiwic2VtdmVyIiwic2FmZVN0cmluZ2lmeSIsInV0aWxzIiwiUmVxdWVzdEJhc2UiLCJ1bnppcCIsIlJlc3BvbnNlIiwiaHR0cDIiLCJndGUiLCJwcm9jZXNzIiwidmVyc2lvbiIsInJlcXVlc3QiLCJtZXRob2QiLCJ1cmwiLCJleHBvcnRzIiwiUmVxdWVzdCIsImVuZCIsImFyZ3VtZW50cyIsImxlbmd0aCIsIm1vZHVsZSIsImFnZW50Iiwibm9vcCIsImRlZmluZSIsInByb3RvY29scyIsInNlcmlhbGl6ZSIsInN0cmluZ2lmeSIsImJ1ZmZlciIsIl9pbml0SGVhZGVycyIsInJlcSIsIl9oZWFkZXIiLCJoZWFkZXIiLCJjYWxsIiwiX2VuYWJsZUh0dHAyIiwiQm9vbGVhbiIsImVudiIsIkhUVFAyX1RFU1QiLCJfYWdlbnQiLCJfZm9ybURhdGEiLCJ3cml0YWJsZSIsIl9yZWRpcmVjdHMiLCJyZWRpcmVjdHMiLCJjb29raWVzIiwiX3F1ZXJ5IiwicXNSYXciLCJfcmVkaXJlY3RMaXN0IiwiX3N0cmVhbVJlcXVlc3QiLCJvbmNlIiwiY2xlYXJUaW1lb3V0IiwiYmluZCIsImluaGVyaXRzIiwicHJvdG90eXBlIiwiYm9vbCIsInVuZGVmaW5lZCIsIkVycm9yIiwiYXR0YWNoIiwiZmllbGQiLCJmaWxlIiwib3B0aW9ucyIsIl9kYXRhIiwibyIsImZpbGVuYW1lIiwiY3JlYXRlUmVhZFN0cmVhbSIsInBhdGgiLCJfZ2V0Rm9ybURhdGEiLCJhcHBlbmQiLCJvbiIsImVyciIsImNhbGxlZCIsImNhbGxiYWNrIiwiYWJvcnQiLCJ0eXBlIiwic2V0IiwiaW5jbHVkZXMiLCJnZXRUeXBlIiwiYWNjZXB0IiwicXVlcnkiLCJ2YWwiLCJwdXNoIiwiT2JqZWN0IiwiYXNzaWduIiwid3JpdGUiLCJkYXRhIiwiZW5jb2RpbmciLCJwaXBlIiwic3RyZWFtIiwicGlwZWQiLCJfcGlwZUNvbnRpbnVlIiwicmVzIiwiaXNSZWRpcmVjdCIsInN0YXR1c0NvZGUiLCJfbWF4UmVkaXJlY3RzIiwiX3JlZGlyZWN0IiwiX2VtaXRSZXNwb25zZSIsIl9hYm9ydGVkIiwiX3Nob3VsZFVuemlwIiwidW56aXBPYmoiLCJjcmVhdGVVbnppcCIsImNvZGUiLCJlbWl0IiwiX2J1ZmZlciIsImhlYWRlcnMiLCJsb2NhdGlvbiIsInJlc3VtZSIsImdldEhlYWRlcnMiLCJfaGVhZGVycyIsImNoYW5nZXNPcmlnaW4iLCJob3N0IiwiY2xlYW5IZWFkZXIiLCJfZW5kQ2FsbGVkIiwiX2NhbGxiYWNrIiwiYXV0aCIsInVzZXIiLCJwYXNzIiwiZW5jb2RlciIsInN0cmluZyIsIkJ1ZmZlciIsImZyb20iLCJ0b1N0cmluZyIsIl9hdXRoIiwiY2EiLCJjZXJ0IiwiX2NhIiwia2V5IiwiX2tleSIsInBmeCIsImlzQnVmZmVyIiwiX3BmeCIsIl9wYXNzcGhyYXNlIiwicGFzc3BocmFzZSIsIl9jZXJ0IiwiZGlzYWJsZVRMU0NlcnRzIiwiX2Rpc2FibGVUTFNDZXJ0cyIsImluZGljZXMiLCJzdHJpY3ROdWxsSGFuZGxpbmciLCJfZmluYWxpemVRdWVyeVN0cmluZyIsInJldHJpZXMiLCJfcmV0cmllcyIsInF1ZXJ5U3RyaW5nQmFja3RpY2tzIiwicXVlcnlTdGFydEluZGV4IiwiaW5kZXhPZiIsInF1ZXJ5U3RyaW5nIiwic2xpY2UiLCJtYXRjaCIsImkiLCJyZXBsYWNlIiwic2VhcmNoIiwicGF0aG5hbWUiLCJ0ZXN0IiwicHJvdG9jb2wiLCJzcGxpdCIsInVuaXhQYXJ0cyIsInNvY2tldFBhdGgiLCJfY29ubmVjdE92ZXJyaWRlIiwiaG9zdG5hbWUiLCJuZXdIb3N0IiwibmV3UG9ydCIsInBvcnQiLCJyZWplY3RVbmF1dGhvcml6ZWQiLCJOT0RFX1RMU19SRUpFQ1RfVU5BVVRIT1JJWkVEIiwic2VydmVybmFtZSIsIl90cnVzdExvY2FsaG9zdCIsIm1vZCIsInNldFByb3RvY29sIiwic2V0Tm9EZWxheSIsInNldEhlYWRlciIsInJlc3BvbnNlIiwidXNlcm5hbWUiLCJwYXNzd29yZCIsImhhc093blByb3BlcnR5IiwidG1wSmFyIiwic2V0Q29va2llcyIsImNvb2tpZSIsImdldENvb2tpZXMiLCJDb29raWVBY2Nlc3NJbmZvIiwiQWxsIiwidG9WYWx1ZVN0cmluZyIsIlByb21pc2UiLCJmblNob3VsZFJldHJ5Iiwic2hvdWxkUmV0cnkiLCJfcmV0cnkiLCJ0aGVuIiwiY2F0Y2giLCJlcnJfIiwiZm4iLCJfaXNSZXNwb25zZU9LIiwibXNnIiwiU1RBVFVTX0NPREVTIiwic3RhdHVzIiwiX21heFJldHJpZXMiLCJsaXN0ZW5lcnMiLCJfc2hvdWxkUmV0cnkiLCJfaXNIb3N0Iiwib2JqIiwiYm9keSIsImZpbGVzIiwiX2VuZCIsIl9zZXRUaW1lb3V0cyIsIl9oZWFkZXJTZW50IiwiY29udGVudFR5cGUiLCJnZXRIZWFkZXIiLCJfc2VyaWFsaXplciIsImlzSlNPTiIsImJ5dGVMZW5ndGgiLCJfcmVzcG9uc2VUaW1lb3V0VGltZXIiLCJtYXgiLCJtdWx0aXBhcnQiLCJyZWRpcmVjdCIsInJlc3BvbnNlVHlwZSIsIl9yZXNwb25zZVR5cGUiLCJwYXJzZXIiLCJfcGFyc2VyIiwiY29uc29sZSIsIndhcm4iLCJpbWFnZSIsImZvcm0iLCJJbmNvbWluZ0Zvcm0iLCJpc0ltYWdlT3JWaWRlbyIsInRleHQiLCJpc1RleHQiLCJfcmVzQnVmZmVyZWQiLCJwYXJzZXJIYW5kbGVzRW5kIiwicmVzcG9uc2VCeXRlc0xlZnQiLCJfbWF4UmVzcG9uc2VTaXplIiwiYnVmIiwiZGVzdHJveSIsInRpbWVkb3V0IiwiZ2V0UHJvZ3Jlc3NNb25pdG9yIiwibGVuZ3RoQ29tcHV0YWJsZSIsInRvdGFsIiwibG9hZGVkIiwicHJvZ3Jlc3MiLCJUcmFuc2Zvcm0iLCJfdHJhbnNmb3JtIiwiY2h1bmsiLCJjYiIsImRpcmVjdGlvbiIsImJ1ZmZlclRvQ2h1bmtzIiwiY2h1bmtTaXplIiwiY2h1bmtpbmciLCJSZWFkYWJsZSIsInRvdGFsTGVuZ3RoIiwicmVtYWluZGVyIiwiY3V0b2ZmIiwicmVtYWluZGVyQnVmZmVyIiwiZm9ybURhdGEiLCJnZXRMZW5ndGgiLCJjb25uZWN0IiwiY29ubmVjdE92ZXJyaWRlIiwidHJ1c3RMb2NhbGhvc3QiLCJ0b2dnbGUiLCJmb3JFYWNoIiwibmFtZSIsInRvVXBwZXJDYXNlIiwic2VuZCIsInBhcnRzIiwic3VidHlwZSJdLCJtYXBwaW5ncyI6Ijs7OztBQUFBOzs7QUFJQTtlQUNtQ0EsT0FBTyxDQUFDLEtBQUQsQztJQUFsQ0MsSyxZQUFBQSxLO0lBQU9DLE0sWUFBQUEsTTtJQUFRQyxPLFlBQUFBLE87O0FBQ3ZCLElBQU1DLE1BQU0sR0FBR0osT0FBTyxDQUFDLFFBQUQsQ0FBdEI7O0FBQ0EsSUFBTUssS0FBSyxHQUFHTCxPQUFPLENBQUMsT0FBRCxDQUFyQjs7QUFDQSxJQUFNTSxJQUFJLEdBQUdOLE9BQU8sQ0FBQyxNQUFELENBQXBCOztBQUNBLElBQU1PLEVBQUUsR0FBR1AsT0FBTyxDQUFDLElBQUQsQ0FBbEI7O0FBQ0EsSUFBTVEsSUFBSSxHQUFHUixPQUFPLENBQUMsTUFBRCxDQUFwQjs7QUFDQSxJQUFNUyxJQUFJLEdBQUdULE9BQU8sQ0FBQyxNQUFELENBQXBCOztBQUNBLElBQU1VLEVBQUUsR0FBR1YsT0FBTyxDQUFDLElBQUQsQ0FBbEI7O0FBQ0EsSUFBTVcsSUFBSSxHQUFHWCxPQUFPLENBQUMsTUFBRCxDQUFwQjs7QUFDQSxJQUFJWSxPQUFPLEdBQUdaLE9BQU8sQ0FBQyxTQUFELENBQXJCOztBQUNBLElBQU1hLFFBQVEsR0FBR2IsT0FBTyxDQUFDLFdBQUQsQ0FBeEI7O0FBQ0EsSUFBTWMsVUFBVSxHQUFHZCxPQUFPLENBQUMsWUFBRCxDQUExQjs7QUFDQSxJQUFNZSxLQUFL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