From 02feadc4dbb4f048a3d8dc1e5bf9cfe02dfdd5cc Mon Sep 17 00:00:00 2001 From: initial-wu Date: Mon, 25 Jun 2018 16:13:20 +0800 Subject: [PATCH] Lazily initialize `request.accept` and delegate `context.accept` (#1209) --- lib/application.js | 2 -- lib/context.js | 1 + lib/request.js | 22 ++++++++++++++++++++++ test/request/accept.js | 27 +++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 test/request/accept.js diff --git a/lib/application.js b/lib/application.js index 18c2645..9aec792 100644 --- a/lib/application.js +++ b/lib/application.js @@ -15,7 +15,6 @@ const context = require('./context'); const request = require('./request'); const statuses = require('statuses'); const Cookies = require('cookies'); -const accepts = require('accepts'); const Emitter = require('events'); const util = require('util'); const Stream = require('stream'); @@ -175,7 +174,6 @@ module.exports = class Application extends Emitter { secure: request.secure }); request.ip = request.ips[0] || req.socket.remoteAddress || ''; - context.accept = request.accept = accepts(req); context.state = {}; return context; } diff --git a/lib/context.js b/lib/context.js index 80b8351..5bb5107 100644 --- a/lib/context.js +++ b/lib/context.js @@ -204,6 +204,7 @@ delegate(proto, 'request') .access('query') .access('path') .access('url') + .access('accept') .getter('origin') .getter('href') .getter('subdomains') diff --git a/lib/request.js b/lib/request.js index d1c3b44..fdf540e 100644 --- a/lib/request.js +++ b/lib/request.js @@ -7,6 +7,7 @@ const URL = require('url').URL; const net = require('net'); +const accepts = require('accepts'); const contentType = require('content-type'); const stringify = require('url').format; const parse = require('parseurl'); @@ -463,6 +464,27 @@ module.exports = { .slice(offset); }, + /** + * Get accept object. + * Lazily memoized. + * + * @return {Object} + * @api private + */ + get accept() { + return this._accept || (this._accept = accepts(this.req)); + }, + + /** + * Set accept object. + * + * @param {Object} + * @api private + */ + set accept(obj) { + return this._accept = obj; + }, + /** * Check if the given `type(s)` is acceptable, returning * the best match when true, otherwise `false`, in which diff --git a/test/request/accept.js b/test/request/accept.js new file mode 100644 index 0000000..9178180 --- /dev/null +++ b/test/request/accept.js @@ -0,0 +1,27 @@ + +'use strict'; + +const Accept = require('accepts'); +const assert = require('assert'); +const context = require('../helpers/context'); + +describe('ctx.accept', () => { + it('should return an Accept instance', () => { + const ctx = context(); + ctx.req.headers.accept = 'application/*;q=0.2, image/jpeg;q=0.8, text/html, text/plain'; + assert(ctx.accept instanceof Accept); + }); +}); + +describe('ctx.accept=', () => { + it('should replace the accept object', () => { + const ctx = context(); + ctx.req.headers.accept = 'text/plain'; + assert.deepEqual(ctx.accepts(), ['text/plain']); + + const request = context.request(); + request.req.headers.accept = 'application/*;q=0.2, image/jpeg;q=0.8, text/html, text/plain'; + ctx.accept = Accept(request.req); + assert.deepEqual(ctx.accepts(), ['text/html', 'text/plain', 'image/jpeg', 'application/*']); + }); +});