diff options
| author | ruki <waruqi@gmail.com> | 2018-11-08 00:38:48 +0800 |
|---|---|---|
| committer | ruki <waruqi@gmail.com> | 2018-11-07 21:53:09 +0800 |
| commit | 26105034da4fcce7ac883c899d781f016559310d (patch) | |
| tree | c459a5dc4e3aa0972d9919033ece511ce76dd129 /node_modules/koa/lib/context.js | |
| parent | 2c77f00f1a7ecb6c8192f9c16d3b2001b254a107 (diff) | |
| download | xmake-docs-26105034da4fcce7ac883c899d781f016559310d.tar.gz xmake-docs-26105034da4fcce7ac883c899d781f016559310d.zip | |
switch to vuepress
Diffstat (limited to 'node_modules/koa/lib/context.js')
| -rw-r--r-- | node_modules/koa/lib/context.js | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/node_modules/koa/lib/context.js b/node_modules/koa/lib/context.js new file mode 100644 index 00000000..1b92f018 --- /dev/null +++ b/node_modules/koa/lib/context.js @@ -0,0 +1,241 @@ + +'use strict'; + +/** + * Module dependencies. + */ + +const util = require('util'); +const createError = require('http-errors'); +const httpAssert = require('http-assert'); +const delegate = require('delegates'); +const statuses = require('statuses'); +const Cookies = require('cookies'); + +const COOKIES = Symbol('context#cookies'); + +/** + * Context prototype. + */ + +const proto = module.exports = { + + /** + * util.inspect() implementation, which + * just returns the JSON output. + * + * @return {Object} + * @api public + */ + + inspect() { + if (this === proto) return this; + return this.toJSON(); + }, + + /** + * 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() { + return { + request: this.request.toJSON(), + response: this.response.toJSON(), + app: this.app.toJSON(), + originalUrl: this.originalUrl, + req: '<original node req>', + res: '<original node res>', + socket: '<original node socket>' + }; + }, + + /** + * Similar to .throw(), adds assertion. + * + * this.assert(this.user, 401, 'Please login!'); + * + * See: https://github.com/jshttp/http-assert + * + * @param {Mixed} test + * @param {Number} status + * @param {String} message + * @api public + */ + + assert: httpAssert, + + /** + * 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') + * this.throw(new Error('invalid'), 400); + * this.throw(400, new Error('invalid')); + * + * See: https://github.com/jshttp/http-errors + * + * @param {String|Number|Error} err, msg or status + * @param {String|Number|Error} [err, msg or status] + * @param {Object} [props] + * @api public + */ + + throw(...args) { + throw createError(...args); + }, + + /** + * Default error handling. + * + * @param {Error} err + * @api private + */ + + onerror(err) { + // don't do anything if there is no error. + // this allows you to pass `this.onerror` + // to node-style callbacks. + if (null == err) return; + + if (!(err instanceof Error)) err = new Error(util.format('non-error thrown: %j', err)); + + let headerSent = false; + if (this.headerSent || !this.writable) { + headerSent = err.headerSent = true; + } + + // delegate + this.app.emit('error', err, this); + + // nothing we can do here other + // than delegate to the app-level + // handler and log. + if (headerSent) { + return; + } + + const { res } = this; + + // first unset all headers + /* istanbul ignore else */ + if (typeof res.getHeaderNames === 'function') { + res.getHeaderNames().forEach(name => res.removeHeader(name)); + } else { + res._headers = {}; // Node < 7.7 + } + + // then set those specified + this.set(err.headers); + + // force text/plain + this.type = 'text'; + + // ENOENT support + if ('ENOENT' == err.code) err.status = 404; + + // default to 500 + if ('number' != typeof err.status || !statuses[err.status]) err.status = 500; + + // respond + const code = statuses[err.status]; + const msg = err.expose ? err.message : code; + this.status = err.status; + this.length = Buffer.byteLength(msg); + this.res.end(msg); + }, + + get cookies() { + if (!this[COOKIES]) { + this[COOKIES] = new Cookies(this.req, this.res, { + keys: this.app.keys, + secure: this.request.secure + }); + } + return this[COOKIES]; + }, + + set cookies(_cookies) { + this[COOKIES] = _cookies; + } +}; + +/** + * Custom inspection implementation for newer Node.js versions. + * + * @return {Object} + * @api public + */ + +/* istanbul ignore else */ +if (util.inspect.custom) { + module.exports[util.inspect.custom] = module.exports.inspect; +} + +/** + * Response delegation. + */ + +delegate(proto, 'response') + .method('attachment') + .method('redirect') + .method('remove') + .method('vary') + .method('set') + .method('append') + .method('flushHeaders') + .access('status') + .access('message') + .access('body') + .access('length') + .access('type') + .access('lastModified') + .access('etag') + .getter('headerSent') + .getter('writable'); + +/** + * Request delegation. + */ + +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') + .access('query') + .access('path') + .access('url') + .access('accept') + .getter('origin') + .getter('href') + .getter('subdomains') + .getter('protocol') + .getter('host') + .getter('hostname') + .getter('URL') + .getter('header') + .getter('headers') + .getter('secure') + .getter('stale') + .getter('fresh') + .getter('ips') + .getter('ip'); |
