discord-baymax-bot/node_modules/superagent/lib/node/response.js
2017-03-23 23:52:08 -05:00

211 lines
4.2 KiB
JavaScript

/**
* Module dependencies.
*/
var util = require('util');
var utils = require('./utils');
var Stream = require('stream');
/**
* Expose `Response`.
*/
module.exports = Response;
/**
* Initialize a new `Response` with the given `xhr`.
*
* - set flags (.ok, .error, etc)
* - parse header
*
* @param {Request} req
* @param {Object} options
* @constructor
* @extends {Stream}
* @implements {ReadableStream}
* @api private
*/
function Response(req, options) {
Stream.call(this);
options = options || {};
var res = this.res = req.res;
this.request = req;
this.req = req.req;
this.links = {};
this.text = res.text;
this.body = res.body !== undefined ? res.body : {};
this.files = res.files || {};
this.buffered = 'string' == typeof this.text;
this.header = this.headers = res.headers;
this.setStatusProperties(res.statusCode);
this.setHeaderProperties(this.header);
this.setEncoding = res.setEncoding.bind(res);
res.on('data', this.emit.bind(this, 'data'));
res.on('end', this.emit.bind(this, 'end'));
res.on('close', this.emit.bind(this, 'close'));
res.on('error', this.emit.bind(this, 'error'));
}
/**
* Inherit from `Stream`.
*/
util.inherits(Response, Stream);
/**
* Get case-insensitive `field` value.
*
* @param {String} field
* @return {String}
* @api public
*/
Response.prototype.get = function(field){
return this.header[field.toLowerCase()];
};
/**
* Implements methods of a `ReadableStream`
*/
Response.prototype.destroy = function(err){
this.res.destroy(err);
};
/**
* Pause.
*/
Response.prototype.pause = function(){
this.res.pause();
};
/**
* Resume.
*/
Response.prototype.resume = function(){
this.res.resume();
};
/**
* Return an `Error` representative of this response.
*
* @return {Error}
* @api public
*/
Response.prototype.toError = function(){
var req = this.req;
var method = req.method;
var path = req.path;
var msg = 'cannot ' + method + ' ' + path + ' (' + this.status + ')';
var err = new Error(msg);
err.status = this.status;
err.text = this.text;
err.method = method;
err.path = path;
return err;
};
/**
* Set header related properties:
*
* - `.type` the content type without params
*
* A response of "Content-Type: text/plain; charset=utf-8"
* will provide you with a `.type` of "text/plain".
*
* @param {Object} header
* @api private
*/
Response.prototype.setHeaderProperties = function(header){
// TODO: moar!
// TODO: make this a util
// content-type
var ct = this.header['content-type'] || '';
// params
var params = utils.params(ct);
for (var key in params) this[key] = params[key];
this.type = utils.type(ct);
// links
try {
if (header.link) this.links = utils.parseLinks(header.link);
} catch (err) {
// ignore
}
};
/**
* Set flags such as `.ok` based on `status`.
*
* For example a 2xx response will give you a `.ok` of __true__
* whereas 5xx will be __false__ and `.error` will be __true__. The
* `.clientError` and `.serverError` are also available to be more
* specific, and `.statusType` is the class of error ranging from 1..5
* sometimes useful for mapping respond colors etc.
*
* "sugar" properties are also defined for common cases. Currently providing:
*
* - .noContent
* - .badRequest
* - .unauthorized
* - .notAcceptable
* - .notFound
*
* @param {Number} status
* @api private
*/
Response.prototype.setStatusProperties = function(status){
var type = status / 100 | 0;
// status / class
this.status = this.statusCode = status;
this.statusType = type;
// basics
this.info = 1 == type;
this.ok = 2 == type;
this.redirect = 3 == type;
this.clientError = 4 == type;
this.serverError = 5 == type;
this.error = (4 == type || 5 == type)
? this.toError()
: false;
// sugar
this.accepted = 202 == status;
this.noContent = 204 == status;
this.badRequest = 400 == status;
this.unauthorized = 401 == status;
this.notAcceptable = 406 == status;
this.forbidden = 403 == status;
this.notFound = 404 == status;
};
/**
* To json.
*
* @return {Object}
* @api public
*/
Response.prototype.toJSON = function(){
return {
req: this.request.toJSON(),
header: this.header,
status: this.status,
text: this.text
};
};