diff --git a/docs/api/request.md b/docs/api/request.md index aca01c7..0d0474c 100644 --- a/docs/api/request.md +++ b/docs/api/request.md @@ -177,12 +177,16 @@ this.is('html'); ### req.accepts(types) Check if the given `type(s)` is acceptable, returning - the best match when true, otherwise `undefined`, in which + the best match when true, otherwise `false`, in which case you should respond with 406 "Not Acceptable". The `type` value may be one or more mime type string such as "application/json", the extension name - such as "json", or an array `["json", "html", "text/plain"]`. When a list or array is given the _best_ match, if any is returned. + such as "json", or an array `["json", "html", "text/plain"]`. + When a list or array is given the _best_ match, if any is returned. + + Note that if the client did not send an `Accept` header, + the first `type` will be returned. ```js // Accept: text/html @@ -218,6 +222,7 @@ switch (this.accepts('json', 'html', 'text')) { case 'json': break; case 'html': break; case 'text': break; + case false: break; } ``` diff --git a/lib/request.js b/lib/request.js index afb7672..7e87603 100644 --- a/lib/request.js +++ b/lib/request.js @@ -404,6 +404,7 @@ module.exports = { if (!Array.isArray(types)) types = [].slice.call(arguments); var n = new Negotiator(this.req); if (!types.length) return n.preferredMediaTypes(); + if (!this.header.accept) return types[0]; var mimes = types.map(extToMime); var accepts = n.preferredMediaTypes(mimes); var first = accepts[0]; diff --git a/test/request/accepts.js b/test/request/accepts.js index b5bde9f..b72b0f2 100644 --- a/test/request/accepts.js +++ b/test/request/accepts.js @@ -3,17 +3,36 @@ var context = require('../context'); describe('ctx.accepts(types)', function(){ describe('with no arguments', function(){ - it('should return all accepted types', function(){ - var ctx = context(); - ctx.req.headers.accept = 'application/*;q=0.2, image/jpeg;q=0.8, text/html, text/plain'; - ctx.accepts().should.eql(['text/html', 'text/plain', 'image/jpeg', 'application/*']); + describe('when Accept is populated', function(){ + it('should return all accepted types', function(){ + var ctx = context(); + ctx.req.headers.accept = 'application/*;q=0.2, image/jpeg;q=0.8, text/html, text/plain'; + ctx.accepts().should.eql(['text/html', 'text/plain', 'image/jpeg', 'application/*']); + }) + }) + + describe('when Accept is not populated', function(){ + it('should return []', function(){ + var ctx = context(); + ctx.accepts().should.eql([]); + }) }) }) describe('with no valid types', function(){ - it('should return false', function(){ - var ctx = context(); - ctx.accepts('', 'hey').should.be.false; + describe('when Accept is populated', function(){ + it('should return false', function(){ + var ctx = context(); + ctx.req.headers.accept = 'application/*;q=0.2, image/jpeg;q=0.8, text/html, text/plain'; + ctx.accepts('image/png', 'image/tiff').should.be.false; + }) + }) + + describe('when Accept is not populated', function(){ + it('should return the first type', function(){ + var ctx = context(); + ctx.accepts('text/html', 'text/plain', 'image/jpeg', 'application/*').should.equal('text/html'); + }) }) })