koa-lite/lib/context.js

187 lines
3.8 KiB
JavaScript
Raw Normal View History

2013-08-17 07:15:57 +00:00
/**
* Module dependencies.
*/
var debug = require('debug')('koa:context');
2014-01-13 14:36:10 +00:00
var delegate = require('delegates');
2013-08-17 07:15:57 +00:00
var http = require('http');
/**
2014-01-13 14:36:10 +00:00
* Context prototype.
2013-08-17 07:15:57 +00:00
*/
2014-01-13 14:36:10 +00:00
var proto = module.exports = {
2013-08-17 07:15:57 +00:00
/**
* Inspect implementation.
*
* @return {Object}
* @api public
*/
inspect: function(){
return {
request: this.request,
response: this.response
}
},
/**
* Return JSON representation.
*
* Here we explicitly invoke .toJSON() on each
* object, as iteration will otherwise fail due
* to the getters and cause utilities such as
* clone() to fail.
*
* @return {Object}
* @api public
*/
toJSON: function(){
return {
request: this.request.toJSON(),
response: this.response.toJSON()
}
},
/**
* Throw an error with `msg` and optional `status`
* defaulting to 500. Note that these are user-level
* errors, and the message may be exposed to the client.
*
* this.throw(403)
* this.throw('name required', 400)
* this.throw(400, 'name required')
* this.throw('something exploded')
2014-01-04 08:23:39 +00:00
* this.throw(new Error('invalid'), 400);
* this.throw(400, new Error('invalid'));
*
2014-01-04 08:23:39 +00:00
* @param {String|Number|Error} err, msg or status
* @param {String|Number|Error} err, msg or status
* @api public
*/
throw: function(msg, status){
if ('number' == typeof msg) {
var tmp = msg;
msg = status || http.STATUS_CODES[tmp];
status = tmp;
}
2014-01-04 08:23:39 +00:00
var err = msg instanceof Error ? msg : new Error(msg);
err.status = status || 500;
err.expose = err.status < 500;
throw err;
},
/**
* Alias for .throw() for backwards compatibility.
* Do not use - will be removed in the future.
*
* @param {String|Number} msg
* @param {Number} status
* @api private
*/
error: function(msg, status){
console.warn('ctx.error is deprecated, use ctx.throw');
this.throw(msg, status);
},
/**
* Default error handling.
*
* @param {Error} err
* @api private
*/
onerror: function(err){
// don't do anything if there is no error.
// this allows you to pass `this.onerror`
// to node-style callbacks.
if (!err) return;
// nothing we can do here other
// than delegate to the app-level
// handler and log.
2013-12-18 01:37:35 +00:00
if (this.headerSent || !this.socket.writable) {
err.headerSent = true;
this.app.emit('error', err, this);
return;
}
// delegate
this.app.emit('error', err, this);
// unset all headers
this.res._headers = {};
// force text/plain
this.type = 'text';
// ENOENT support
if ('ENOENT' == err.code) err.status = 404;
// default to 500
err.status = err.status || 500;
// respond
var code = http.STATUS_CODES[err.status];
var msg = err.expose ? err.message : code;
this.status = err.status;
this.length = Buffer.byteLength(msg);
this.res.end(msg);
2014-01-13 14:36:10 +00:00
}
};
2014-01-13 14:36:10 +00:00
/**
* Response delegation.
*/
2014-01-13 14:36:10 +00:00
delegate(proto, 'response')
.method('attachment')
.method('redirect')
.method('append')
.method('remove')
.method('vary')
2014-01-13 14:36:49 +00:00
.method('set')
2014-01-13 14:36:10 +00:00
.access('status')
.access('body')
.access('length')
.access('type')
.access('charset')
2014-01-13 14:36:10 +00:00
.getter('headerSent')
.setter('lastModified')
.setter('etag');
2014-01-13 14:36:10 +00:00
/**
* Request delegation.
*/
2014-01-13 14:36:10 +00:00
delegate(proto, 'request')
.method('acceptsLanguages')
.method('acceptsEncodings')
.method('acceptsCharsets')
.method('accepts')
.method('get')
.method('is')
.access('querystring')
.access('idempotent')
.access('socket')
.access('search')
.access('method')
2014-01-13 14:36:49 +00:00
.access('query')
2014-01-13 14:36:10 +00:00
.access('path')
.access('host')
.access('url')
.getter('subdomains')
.getter('protocol')
.getter('header')
2014-01-13 14:36:49 +00:00
.getter('secure')
2014-01-13 14:36:10 +00:00
.getter('stale')
.getter('fresh')
.getter('ips')
2014-01-13 14:36:49 +00:00
.getter('ip');