Spaces:
Runtime error
Runtime error
| /** | |
| * Root reference for iframes. | |
| */ | |
| var root; | |
| if (typeof window !== 'undefined') { // Browser window | |
| root = window; | |
| } else if (typeof self !== 'undefined') { // Web Worker | |
| root = self; | |
| } else { // Other environments | |
| console.warn("Using browser-only version of superagent in non-browser environment"); | |
| root = this; | |
| } | |
| var Emitter = require('component-emitter'); | |
| var RequestBase = require('./request-base'); | |
| var isObject = require('./is-object'); | |
| var isFunction = require('./is-function'); | |
| var ResponseBase = require('./response-base'); | |
| var shouldRetry = require('./should-retry'); | |
| /** | |
| * Noop. | |
| */ | |
| function noop(){}; | |
| /** | |
| * Expose `request`. | |
| */ | |
| var request = exports = module.exports = function(method, url) { | |
| // callback | |
| if ('function' == typeof url) { | |
| return new exports.Request('GET', method).end(url); | |
| } | |
| // url first | |
| if (1 == arguments.length) { | |
| return new exports.Request('GET', method); | |
| } | |
| return new exports.Request(method, url); | |
| } | |
| exports.Request = Request; | |
| /** | |
| * Determine XHR. | |
| */ | |
| request.getXHR = function () { | |
| if (root.XMLHttpRequest | |
| && (!root.location || 'file:' != root.location.protocol | |
| || !root.ActiveXObject)) { | |
| return new XMLHttpRequest; | |
| } else { | |
| try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {} | |
| try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {} | |
| try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {} | |
| try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {} | |
| } | |
| throw Error("Browser-only verison of superagent could not find XHR"); | |
| }; | |
| /** | |
| * Removes leading and trailing whitespace, added to support IE. | |
| * | |
| * @param {String} s | |
| * @return {String} | |
| * @api private | |
| */ | |
| var trim = ''.trim | |
| ? function(s) { return s.trim(); } | |
| : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); }; | |
| /** | |
| * Serialize the given `obj`. | |
| * | |
| * @param {Object} obj | |
| * @return {String} | |
| * @api private | |
| */ | |
| function serialize(obj) { | |
| if (!isObject(obj)) return obj; | |
| var pairs = []; | |
| for (var key in obj) { | |
| pushEncodedKeyValuePair(pairs, key, obj[key]); | |
| } | |
| return pairs.join('&'); | |
| } | |
| /** | |
| * Helps 'serialize' with serializing arrays. | |
| * Mutates the pairs array. | |
| * | |
| * @param {Array} pairs | |
| * @param {String} key | |
| * @param {Mixed} val | |
| */ | |
| function pushEncodedKeyValuePair(pairs, key, val) { | |
| if (val != null) { | |
| if (Array.isArray(val)) { | |
| val.forEach(function(v) { | |
| pushEncodedKeyValuePair(pairs, key, v); | |
| }); | |
| } else if (isObject(val)) { | |
| for(var subkey in val) { | |
| pushEncodedKeyValuePair(pairs, key + '[' + subkey + ']', val[subkey]); | |
| } | |
| } else { | |
| pairs.push(encodeURIComponent(key) | |
| + '=' + encodeURIComponent(val)); | |
| } | |
| } else if (val === null) { | |
| pairs.push(encodeURIComponent(key)); | |
| } | |
| } | |
| /** | |
| * Expose serialization method. | |
| */ | |
| request.serializeObject = serialize; | |
| /** | |
| * Parse the given x-www-form-urlencoded `str`. | |
| * | |
| * @param {String} str | |
| * @return {Object} | |
| * @api private | |
| */ | |
| function parseString(str) { | |
| var obj = {}; | |
| var pairs = str.split('&'); | |
| var pair; | |
| var pos; | |
| for (var i = 0, len = pairs.length; i < len; ++i) { | |
| pair = pairs[i]; | |
| pos = pair.indexOf('='); | |
| if (pos == -1) { | |
| obj[decodeURIComponent(pair)] = ''; | |
| } else { | |
| obj[decodeURIComponent(pair.slice(0, pos))] = | |
| decodeURIComponent(pair.slice(pos + 1)); | |
| } | |
| } | |
| return obj; | |
| } | |
| /** | |
| * Expose parser. | |
| */ | |
| request.parseString = parseString; | |
| /** | |
| * Default MIME type map. | |
| * | |
| * superagent.types.xml = 'application/xml'; | |
| * | |
| */ | |
| request.types = { | |
| html: 'text/html', | |
| json: 'application/json', | |
| xml: 'application/xml', | |
| urlencoded: 'application/x-www-form-urlencoded', | |
| 'form': 'application/x-www-form-urlencoded', | |
| 'form-data': 'application/x-www-form-urlencoded' | |
| }; | |
| /** | |
| * Default serialization map. | |
| * | |
| * superagent.serialize['application/xml'] = function(obj){ | |
| * return 'generated xml here'; | |
| * }; | |
| * | |
| */ | |
| request.serialize = { | |
| 'application/x-www-form-urlencoded': serialize, | |
| 'application/json': JSON.stringify | |
| }; | |
| /** | |
| * Default parsers. | |
| * | |
| * superagent.parse['application/xml'] = function(str){ | |
| * return { object parsed from str }; | |
| * }; | |
| * | |
| */ | |
| request.parse = { | |
| 'application/x-www-form-urlencoded': parseString, | |
| 'application/json': JSON.parse | |
| }; | |
| /** | |
| * Parse the given header `str` into | |
| * an object containing the mapped fields. | |
| * | |
| * @param {String} str | |
| * @return {Object} | |
| * @api private | |
| */ | |
| function parseHeader(str) { | |
| var lines = str.split(/\r?\n/); | |
| var fields = {}; | |
| var index; | |
| var line; | |
| var field; | |
| var val; | |
| lines.pop(); // trailing CRLF | |
| for (var i = 0, len = lines.length; i < len; ++i) { | |
| line = lines[i]; | |
| index = line.indexOf(':'); | |
| field = line.slice(0, index).toLowerCase(); | |
| val = trim(line.slice(index + 1)); | |
| fields[field] = val; | |
| } | |
| return fields; | |
| } | |
| /** | |
| * Check if `mime` is json or has +json structured syntax suffix. | |
| * | |
| * @param {String} mime | |
| * @return {Boolean} | |
| * @api private | |
| */ | |
| function isJSON(mime) { | |
| return /[\/+]json\b/.test(mime); | |
| } | |
| /** | |
| * Initialize a new `Response` with the given `xhr`. | |
| * | |
| * - set flags (.ok, .error, etc) | |
| * - parse header | |
| * | |
| * Examples: | |
| * | |
| * Aliasing `superagent` as `request` is nice: | |
| * | |
| * request = superagent; | |
| * | |
| * We can use the promise-like API, or pass callbacks: | |
| * | |
| * request.get('/').end(function(res){}); | |
| * request.get('/', function(res){}); | |
| * | |
| * Sending data can be chained: | |
| * | |
| * request | |
| * .post('/user') | |
| * .send({ name: 'tj' }) | |
| * .end(function(res){}); | |
| * | |
| * Or passed to `.send()`: | |
| * | |
| * request | |
| * .post('/user') | |
| * .send({ name: 'tj' }, function(res){}); | |
| * | |
| * Or passed to `.post()`: | |
| * | |
| * request | |
| * .post('/user', { name: 'tj' }) | |
| * .end(function(res){}); | |
| * | |
| * Or further reduced to a single call for simple cases: | |
| * | |
| * request | |
| * .post('/user', { name: 'tj' }, function(res){}); | |
| * | |
| * @param {XMLHTTPRequest} xhr | |
| * @param {Object} options | |
| * @api private | |
| */ | |
| function Response(req) { | |
| this.req = req; | |
| this.xhr = this.req.xhr; | |
| // responseText is accessible only if responseType is '' or 'text' and on older browsers | |
| this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined') | |
| ? this.xhr.responseText | |
| : null; | |
| this.statusText = this.req.xhr.statusText; | |
| var status = this.xhr.status; | |
| // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request | |
| if (status === 1223) { | |
| status = 204; | |
| } | |
| this._setStatusProperties(status); | |
| this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders()); | |
| // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but | |
| // getResponseHeader still works. so we get content-type even if getting | |
| // other headers fails. | |
| this.header['content-type'] = this.xhr.getResponseHeader('content-type'); | |
| this._setHeaderProperties(this.header); | |
| if (null === this.text && req._responseType) { | |
| this.body = this.xhr.response; | |
| } else { | |
| this.body = this.req.method != 'HEAD' | |
| ? this._parseBody(this.text ? this.text : this.xhr.response) | |
| : null; | |
| } | |
| } | |
| ResponseBase(Response.prototype); | |
| /** | |
| * Parse the given body `str`. | |
| * | |
| * Used for auto-parsing of bodies. Parsers | |
| * are defined on the `superagent.parse` object. | |
| * | |
| * @param {String} str | |
| * @return {Mixed} | |
| * @api private | |
| */ | |
| Response.prototype._parseBody = function(str){ | |
| var parse = request.parse[this.type]; | |
| if(this.req._parser) { | |
| return this.req._parser(this, str); | |
| } | |
| if (!parse && isJSON(this.type)) { | |
| parse = request.parse['application/json']; | |
| } | |
| return parse && str && (str.length || str instanceof Object) | |
| ? parse(str) | |
| : null; | |
| }; | |
| /** | |
| * Return an `Error` representative of this response. | |
| * | |
| * @return {Error} | |
| * @api public | |
| */ | |
| Response.prototype.toError = function(){ | |
| var req = this.req; | |
| var method = req.method; | |
| var url = req.url; | |
| var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')'; | |
| var err = new Error(msg); | |
| err.status = this.status; | |
| err.method = method; | |
| err.url = url; | |
| return err; | |
| }; | |
| /** | |
| * Expose `Response`. | |
| */ | |
| request.Response = Response; | |
| /** | |
| * Initialize a new `Request` with the given `method` and `url`. | |
| * | |
| * @param {String} method | |
| * @param {String} url | |
| * @api public | |
| */ | |
| function Request(method, url) { | |
| var self = this; | |
| this._query = this._query || []; | |
| this.method = method; | |
| this.url = url; | |
| this.header = {}; // preserves header name case | |
| this._header = {}; // coerces header names to lowercase | |
| this.on('end', function(){ | |
| var err = null; | |
| var res = null; | |
| try { | |
| res = new Response(self); | |
| } catch(e) { | |
| err = new Error('Parser is unable to parse the response'); | |
| err.parse = true; | |
| err.original = e; | |
| // issue #675: return the raw response if the response parsing fails | |
| if (self.xhr) { | |
| // ie9 doesn't have 'response' property | |
| err.rawResponse = typeof self.xhr.responseType == 'undefined' ? self.xhr.responseText : self.xhr.response; | |
| // issue #876: return the http status code if the response parsing fails | |
| err.status = self.xhr.status ? self.xhr.status : null; | |
| err.statusCode = err.status; // backwards-compat only | |
| } else { | |
| err.rawResponse = null; | |
| err.status = null; | |
| } | |
| return self.callback(err); | |
| } | |
| self.emit('response', res); | |
| var new_err; | |
| try { | |
| if (!self._isResponseOK(res)) { | |
| new_err = new Error(res.statusText || 'Unsuccessful HTTP response'); | |
| new_err.original = err; | |
| new_err.response = res; | |
| new_err.status = res.status; | |
| } | |
| } catch(e) { | |
| new_err = e; // #985 touching res may cause INVALID_STATE_ERR on old Android | |
| } | |
| // #1000 don't catch errors from the callback to avoid double calling it | |
| if (new_err) { | |
| self.callback(new_err, res); | |
| } else { | |
| self.callback(null, res); | |
| } | |
| }); | |
| } | |
| /** | |
| * Mixin `Emitter` and `RequestBase`. | |
| */ | |
| Emitter(Request.prototype); | |
| RequestBase(Request.prototype); | |
| /** | |
| * Set Content-Type to `type`, mapping values from `request.types`. | |
| * | |
| * Examples: | |
| * | |
| * superagent.types.xml = 'application/xml'; | |
| * | |
| * request.post('/') | |
| * .type('xml') | |
| * .send(xmlstring) | |
| * .end(callback); | |
| * | |
| * request.post('/') | |
| * .type('application/xml') | |
| * .send(xmlstring) | |
| * .end(callback); | |
| * | |
| * @param {String} type | |
| * @return {Request} for chaining | |
| * @api public | |
| */ | |
| Request.prototype.type = function(type){ | |
| this.set('Content-Type', request.types[type] || type); | |
| return this; | |
| }; | |
| /** | |
| * Set Accept to `type`, mapping values from `request.types`. | |
| * | |
| * 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){ | |
| this.set('Accept', request.types[type] || type); | |
| return this; | |
| }; | |
| /** | |
| * Set Authorization field value with `user` and `pass`. | |
| * | |
| * @param {String} user | |
| * @param {String} [pass] optional in case of using 'bearer' as type | |
| * @param {Object} options with 'type' property 'auto', 'basic' or 'bearer' (default 'basic') | |
| * @return {Request} for chaining | |
| * @api public | |
| */ | |
| Request.prototype.auth = function(user, pass, options){ | |
| if (typeof pass === 'object' && pass !== null) { // pass is optional and can substitute for options | |
| options = pass; | |
| } | |
| if (!options) { | |
| options = { | |
| type: 'function' === typeof btoa ? 'basic' : 'auto', | |
| } | |
| } | |
| switch (options.type) { | |
| case 'basic': | |
| this.set('Authorization', 'Basic ' + btoa(user + ':' + pass)); | |
| break; | |
| case 'auto': | |
| this.username = user; | |
| this.password = pass; | |
| break; | |
| case 'bearer': // usage would be .auth(accessToken, { type: 'bearer' }) | |
| this.set('Authorization', 'Bearer ' + user); | |
| break; | |
| } | |
| return this; | |
| }; | |
| /** | |
| * 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 ('string' != typeof val) val = serialize(val); | |
| if (val) this._query.push(val); | |
| return this; | |
| }; | |
| /** | |
| * Queue the given `file` as an attachment to the specified `field`, | |
| * with optional `options` (or filename). | |
| * | |
| * ``` js | |
| * request.post('/upload') | |
| * .attach('content', new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: "text/html"})) | |
| * .end(callback); | |
| * ``` | |
| * | |
| * @param {String} field | |
| * @param {Blob|File} file | |
| * @param {String|Object} options | |
| * @return {Request} for chaining | |
| * @api public | |
| */ | |
| Request.prototype.attach = function(field, file, options){ | |
| if (file) { | |
| if (this._data) { | |
| throw Error("superagent can't mix .send() and .attach()"); | |
| } | |
| this._getFormData().append(field, file, options || file.name); | |
| } | |
| return this; | |
| }; | |
| Request.prototype._getFormData = function(){ | |
| if (!this._formData) { | |
| this._formData = new root.FormData(); | |
| } | |
| return this._formData; | |
| }; | |
| /** | |
| * 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){ | |
| // console.log(this._retries, this._maxRetries) | |
| if (this._maxRetries && this._retries++ < this._maxRetries && shouldRetry(err, res)) { | |
| return this._retry(); | |
| } | |
| var fn = this._callback; | |
| this.clearTimeout(); | |
| if (err) { | |
| if (this._maxRetries) err.retries = this._retries - 1; | |
| this.emit('error', err); | |
| } | |
| fn(err, res); | |
| }; | |
| /** | |
| * Invoke callback with x-domain error. | |
| * | |
| * @api private | |
| */ | |
| Request.prototype.crossDomainError = function(){ | |
| var err = new Error('Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.'); | |
| err.crossDomain = true; | |
| err.status = this.status; | |
| err.method = this.method; | |
| err.url = this.url; | |
| this.callback(err); | |
| }; | |
| // This only warns, because the request is still likely to work | |
| Request.prototype.buffer = Request.prototype.ca = Request.prototype.agent = function(){ | |
| console.warn("This is not supported in browser version of superagent"); | |
| return this; | |
| }; | |
| // This throws, because it can't send/receive data as expected | |
| Request.prototype.pipe = Request.prototype.write = function(){ | |
| throw Error("Streaming is not supported in browser version of superagent"); | |
| }; | |
| /** | |
| * Compose querystring to append to req.url | |
| * | |
| * @api private | |
| */ | |
| Request.prototype._appendQueryString = function(){ | |
| var query = this._query.join('&'); | |
| if (query) { | |
| this.url += (this.url.indexOf('?') >= 0 ? '&' : '?') + query; | |
| } | |
| if (this._sort) { | |
| var index = this.url.indexOf('?'); | |
| if (index >= 0) { | |
| var queryArr = this.url.substring(index + 1).split('&'); | |
| if (isFunction(this._sort)) { | |
| queryArr.sort(this._sort); | |
| } else { | |
| queryArr.sort(); | |
| } | |
| this.url = this.url.substring(0, index) + '?' + queryArr.join('&'); | |
| } | |
| } | |
| }; | |
| /** | |
| * Check if `obj` is a host object, | |
| * we don't want to serialize these :) | |
| * | |
| * @param {Object} obj | |
| * @return {Boolean} | |
| * @api private | |
| */ | |
| Request.prototype._isHost = function _isHost(obj) { | |
| // Native objects stringify to [object File], [object Blob], [object FormData], etc. | |
| return obj && 'object' === typeof obj && !Array.isArray(obj) && Object.prototype.toString.call(obj) !== '[object Object]'; | |
| } | |
| /** | |
| * Initiate request, invoking callback `fn(res)` | |
| * with an instanceof `Response`. | |
| * | |
| * @param {Function} fn | |
| * @return {Request} for chaining | |
| * @api public | |
| */ | |
| Request.prototype.end = function(fn){ | |
| if (this._endCalled) { | |
| console.warn("Warning: .end() was called twice. This is not supported in superagent"); | |
| } | |
| this._endCalled = true; | |
| // store callback | |
| this._callback = fn || noop; | |
| // querystring | |
| this._appendQueryString(); | |
| return this._end(); | |
| }; | |
| Request.prototype._end = function() { | |
| var self = this; | |
| var xhr = this.xhr = request.getXHR(); | |
| var data = this._formData || this._data; | |
| this._setTimeouts(); | |
| // state change | |
| xhr.onreadystatechange = function(){ | |
| var readyState = xhr.readyState; | |
| if (readyState >= 2 && self._responseTimeoutTimer) { | |
| clearTimeout(self._responseTimeoutTimer); | |
| } | |
| if (4 != readyState) { | |
| return; | |
| } | |
| // In IE9, reads to any property (e.g. status) off of an aborted XHR will | |
| // result in the error "Could not complete the operation due to error c00c023f" | |
| var status; | |
| try { status = xhr.status } catch(e) { status = 0; } | |
| if (!status) { | |
| if (self.timedout || self._aborted) return; | |
| return self.crossDomainError(); | |
| } | |
| self.emit('end'); | |
| }; | |
| // progress | |
| var handleProgress = function(direction, e) { | |
| if (e.total > 0) { | |
| e.percent = e.loaded / e.total * 100; | |
| } | |
| e.direction = direction; | |
| self.emit('progress', e); | |
| } | |
| if (this.hasListeners('progress')) { | |
| try { | |
| xhr.onprogress = handleProgress.bind(null, 'download'); | |
| if (xhr.upload) { | |
| xhr.upload.onprogress = handleProgress.bind(null, 'upload'); | |
| } | |
| } catch(e) { | |
| // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. | |
| // Reported here: | |
| // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context | |
| } | |
| } | |
| // initiate request | |
| try { | |
| if (this.username && this.password) { | |
| xhr.open(this.method, this.url, true, this.username, this.password); | |
| } else { | |
| xhr.open(this.method, this.url, true); | |
| } | |
| } catch (err) { | |
| // see #1149 | |
| return this.callback(err); | |
| } | |
| // CORS | |
| if (this._withCredentials) xhr.withCredentials = true; | |
| // body | |
| if (!this._formData && 'GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !this._isHost(data)) { | |
| // serialize stuff | |
| var contentType = this._header['content-type']; | |
| var serialize = this._serializer || request.serialize[contentType ? contentType.split(';')[0] : '']; | |
| if (!serialize && isJSON(contentType)) { | |
| serialize = request.serialize['application/json']; | |
| } | |
| if (serialize) data = serialize(data); | |
| } | |
| // set header fields | |
| for (var field in this.header) { | |
| if (null == this.header[field]) continue; | |
| if (this.header.hasOwnProperty(field)) | |
| xhr.setRequestHeader(field, this.header[field]); | |
| } | |
| if (this._responseType) { | |
| xhr.responseType = this._responseType; | |
| } | |
| // send stuff | |
| this.emit('request', this); | |
| // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing) | |
| // We need null here if data is undefined | |
| xhr.send(typeof data !== 'undefined' ? data : null); | |
| return this; | |
| }; | |
| /** | |
| * GET `url` with optional callback `fn(res)`. | |
| * | |
| * @param {String} url | |
| * @param {Mixed|Function} [data] or fn | |
| * @param {Function} [fn] | |
| * @return {Request} | |
| * @api public | |
| */ | |
| request.get = function(url, data, fn){ | |
| var req = request('GET', url); | |
| if ('function' == typeof data) fn = data, data = null; | |
| if (data) req.query(data); | |
| if (fn) req.end(fn); | |
| return req; | |
| }; | |
| /** | |
| * HEAD `url` with optional callback `fn(res)`. | |
| * | |
| * @param {String} url | |
| * @param {Mixed|Function} [data] or fn | |
| * @param {Function} [fn] | |
| * @return {Request} | |
| * @api public | |
| */ | |
| request.head = function(url, data, fn){ | |
| var req = request('HEAD', url); | |
| if ('function' == typeof data) fn = data, data = null; | |
| if (data) req.send(data); | |
| if (fn) req.end(fn); | |
| return req; | |
| }; | |
| /** | |
| * OPTIONS query to `url` with optional callback `fn(res)`. | |
| * | |
| * @param {String} url | |
| * @param {Mixed|Function} [data] or fn | |
| * @param {Function} [fn] | |
| * @return {Request} | |
| * @api public | |
| */ | |
| request.options = function(url, data, fn){ | |
| var req = request('OPTIONS', url); | |
| if ('function' == typeof data) fn = data, data = null; | |
| if (data) req.send(data); | |
| if (fn) req.end(fn); | |
| return req; | |
| }; | |
| /** | |
| * DELETE `url` with optional `data` and callback `fn(res)`. | |
| * | |
| * @param {String} url | |
| * @param {Mixed} [data] | |
| * @param {Function} [fn] | |
| * @return {Request} | |
| * @api public | |
| */ | |
| function del(url, data, fn){ | |
| var req = request('DELETE', url); | |
| if ('function' == typeof data) fn = data, data = null; | |
| if (data) req.send(data); | |
| if (fn) req.end(fn); | |
| return req; | |
| }; | |
| request['del'] = del; | |
| request['delete'] = del; | |
| /** | |
| * PATCH `url` with optional `data` and callback `fn(res)`. | |
| * | |
| * @param {String} url | |
| * @param {Mixed} [data] | |
| * @param {Function} [fn] | |
| * @return {Request} | |
| * @api public | |
| */ | |
| request.patch = function(url, data, fn){ | |
| var req = request('PATCH', url); | |
| if ('function' == typeof data) fn = data, data = null; | |
| if (data) req.send(data); | |
| if (fn) req.end(fn); | |
| return req; | |
| }; | |
| /** | |
| * POST `url` with optional `data` and callback `fn(res)`. | |
| * | |
| * @param {String} url | |
| * @param {Mixed} [data] | |
| * @param {Function} [fn] | |
| * @return {Request} | |
| * @api public | |
| */ | |
| request.post = function(url, data, fn){ | |
| var req = request('POST', url); | |
| if ('function' == typeof data) fn = data, data = null; | |
| if (data) req.send(data); | |
| if (fn) req.end(fn); | |
| return req; | |
| }; | |
| /** | |
| * PUT `url` with optional `data` and callback `fn(res)`. | |
| * | |
| * @param {String} url | |
| * @param {Mixed|Function} [data] or fn | |
| * @param {Function} [fn] | |
| * @return {Request} | |
| * @api public | |
| */ | |
| request.put = function(url, data, fn){ | |
| var req = request('PUT', url); | |
| if ('function' == typeof data) fn = data, data = null; | |
| if (data) req.send(data); | |
| if (fn) req.end(fn); | |
| return req; | |
| }; | |