Remove accepts, cache-content-type and content-type.
Replace content-disposition with one that doesn’t use safe-buffer
This commit is contained in:
parent
a0d2816cba
commit
2ef7846b5f
13 changed files with 31 additions and 604 deletions
14
Readme.md
14
Readme.md
|
@ -103,17 +103,6 @@ Koa's `Request` object provides helpful methods for working with
|
||||||
http requests which delegate to an [IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage)
|
http requests which delegate to an [IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage)
|
||||||
from the node `http` module.
|
from the node `http` module.
|
||||||
|
|
||||||
Here is an example of checking that a requesting client supports xml.
|
|
||||||
|
|
||||||
```js
|
|
||||||
app.use(async (ctx, next) => {
|
|
||||||
ctx.assert(ctx.request.accepts('xml'), 406);
|
|
||||||
// equivalent to:
|
|
||||||
// if (!ctx.request.accepts('xml')) ctx.throw(406);
|
|
||||||
await next();
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
Koa provides a `Response` object as the `response` property of the `Context`.
|
Koa provides a `Response` object as the `response` property of the `Context`.
|
||||||
Koa's `Response` object provides helpful methods for working with
|
Koa's `Response` object provides helpful methods for working with
|
||||||
http responses which delegate to a [ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse)
|
http responses which delegate to a [ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse)
|
||||||
|
@ -136,8 +125,7 @@ app.use(async (ctx, next) => {
|
||||||
```
|
```
|
||||||
|
|
||||||
The `Context` object also provides shortcuts for methods on its `request` and `response`. In the prior
|
The `Context` object also provides shortcuts for methods on its `request` and `response`. In the prior
|
||||||
examples, `ctx.type` can be used instead of `ctx.response.type` and `ctx.accepts` can be used
|
examples, `ctx.type` can be used instead of `ctx.response.type`.
|
||||||
instead of `ctx.request.accepts`.
|
|
||||||
|
|
||||||
For more information on `Request`, `Response` and `Context`, see the [Request API Reference](docs/api/request.md),
|
For more information on `Request`, `Response` and `Context`, see the [Request API Reference](docs/api/request.md),
|
||||||
[Response API Reference](docs/api/response.md) and [Context API Reference](docs/api/context.md).
|
[Response API Reference](docs/api/response.md) and [Context API Reference](docs/api/context.md).
|
||||||
|
|
|
@ -172,10 +172,6 @@ Koa uses [http-assert](https://github.com/jshttp/http-assert) for assertions.
|
||||||
- `ctx.ips`
|
- `ctx.ips`
|
||||||
- `ctx.subdomains`
|
- `ctx.subdomains`
|
||||||
- `ctx.is()`
|
- `ctx.is()`
|
||||||
- `ctx.accepts()`
|
|
||||||
- `ctx.acceptsEncodings()`
|
|
||||||
- `ctx.acceptsCharsets()`
|
|
||||||
- `ctx.acceptsLanguages()`
|
|
||||||
- `ctx.get()`
|
- `ctx.get()`
|
||||||
|
|
||||||
## Response aliases
|
## Response aliases
|
||||||
|
|
|
@ -241,141 +241,6 @@ if (ctx.is('image/*')) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Content Negotiation
|
|
||||||
|
|
||||||
Koa's `request` object includes helpful content negotiation utilities powered by [accepts](http://github.com/expressjs/accepts) and [negotiator](https://github.com/federomero/negotiator). These utilities are:
|
|
||||||
|
|
||||||
- `request.accepts(types)`
|
|
||||||
- `request.acceptsEncodings(types)`
|
|
||||||
- `request.acceptsCharsets(charsets)`
|
|
||||||
- `request.acceptsLanguages(langs)`
|
|
||||||
|
|
||||||
If no types are supplied, __all__ acceptable types are returned.
|
|
||||||
|
|
||||||
If multiple types are supplied, the best match will be returned. If no matches are found, a `false` is returned, and you should send a `406 "Not Acceptable"` response to the client.
|
|
||||||
|
|
||||||
In the case of missing accept headers where any type is acceptable, the first type will be returned. Thus, the order of types you supply is important.
|
|
||||||
|
|
||||||
### request.accepts(types)
|
|
||||||
|
|
||||||
Check if the given `type(s)` is acceptable, returning the best match when true, otherwise `false`. 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"]`.
|
|
||||||
|
|
||||||
```js
|
|
||||||
// Accept: text/html
|
|
||||||
ctx.accepts('html');
|
|
||||||
// => "html"
|
|
||||||
|
|
||||||
// Accept: text/*, application/json
|
|
||||||
ctx.accepts('html');
|
|
||||||
// => "html"
|
|
||||||
ctx.accepts('text/html');
|
|
||||||
// => "text/html"
|
|
||||||
ctx.accepts('json', 'text');
|
|
||||||
// => "json"
|
|
||||||
ctx.accepts('application/json');
|
|
||||||
// => "application/json"
|
|
||||||
|
|
||||||
// Accept: text/*, application/json
|
|
||||||
ctx.accepts('image/png');
|
|
||||||
ctx.accepts('png');
|
|
||||||
// => false
|
|
||||||
|
|
||||||
// Accept: text/*;q=.5, application/json
|
|
||||||
ctx.accepts(['html', 'json']);
|
|
||||||
ctx.accepts('html', 'json');
|
|
||||||
// => "json"
|
|
||||||
|
|
||||||
// No Accept header
|
|
||||||
ctx.accepts('html', 'json');
|
|
||||||
// => "html"
|
|
||||||
ctx.accepts('json', 'html');
|
|
||||||
// => "json"
|
|
||||||
```
|
|
||||||
|
|
||||||
You may call `ctx.accepts()` as many times as you like,
|
|
||||||
or use a switch:
|
|
||||||
|
|
||||||
```js
|
|
||||||
switch (ctx.accepts('json', 'html', 'text')) {
|
|
||||||
case 'json': break;
|
|
||||||
case 'html': break;
|
|
||||||
case 'text': break;
|
|
||||||
default: ctx.throw(406, 'json, html, or text only');
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### request.acceptsEncodings(encodings)
|
|
||||||
|
|
||||||
Check if `encodings` are acceptable, returning the best match when true, otherwise `false`. Note that you should include `identity` as one of the encodings!
|
|
||||||
|
|
||||||
```js
|
|
||||||
// Accept-Encoding: gzip
|
|
||||||
ctx.acceptsEncodings('gzip', 'deflate', 'identity');
|
|
||||||
// => "gzip"
|
|
||||||
|
|
||||||
ctx.acceptsEncodings(['gzip', 'deflate', 'identity']);
|
|
||||||
// => "gzip"
|
|
||||||
```
|
|
||||||
|
|
||||||
When no arguments are given all accepted encodings
|
|
||||||
are returned as an array:
|
|
||||||
|
|
||||||
```js
|
|
||||||
// Accept-Encoding: gzip, deflate
|
|
||||||
ctx.acceptsEncodings();
|
|
||||||
// => ["gzip", "deflate", "identity"]
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that the `identity` encoding (which means no encoding) could be unacceptable if the client explicitly sends `identity;q=0`. Although this is an edge case, you should still handle the case where this method returns `false`.
|
|
||||||
|
|
||||||
### request.acceptsCharsets(charsets)
|
|
||||||
|
|
||||||
Check if `charsets` are acceptable, returning
|
|
||||||
the best match when true, otherwise `false`.
|
|
||||||
|
|
||||||
```js
|
|
||||||
// Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5
|
|
||||||
ctx.acceptsCharsets('utf-8', 'utf-7');
|
|
||||||
// => "utf-8"
|
|
||||||
|
|
||||||
ctx.acceptsCharsets(['utf-7', 'utf-8']);
|
|
||||||
// => "utf-8"
|
|
||||||
```
|
|
||||||
|
|
||||||
When no arguments are given all accepted charsets
|
|
||||||
are returned as an array:
|
|
||||||
|
|
||||||
```js
|
|
||||||
// Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5
|
|
||||||
ctx.acceptsCharsets();
|
|
||||||
// => ["utf-8", "utf-7", "iso-8859-1"]
|
|
||||||
```
|
|
||||||
|
|
||||||
### request.acceptsLanguages(langs)
|
|
||||||
|
|
||||||
Check if `langs` are acceptable, returning
|
|
||||||
the best match when true, otherwise `false`.
|
|
||||||
|
|
||||||
```js
|
|
||||||
// Accept-Language: en;q=0.8, es, pt
|
|
||||||
ctx.acceptsLanguages('es', 'en');
|
|
||||||
// => "es"
|
|
||||||
|
|
||||||
ctx.acceptsLanguages(['en', 'es']);
|
|
||||||
// => "es"
|
|
||||||
```
|
|
||||||
|
|
||||||
When no arguments are given all accepted languages
|
|
||||||
are returned as an array:
|
|
||||||
|
|
||||||
```js
|
|
||||||
// Accept-Language: en;q=0.8, es, pt
|
|
||||||
ctx.acceptsLanguages();
|
|
||||||
// => ["es", "pt", "en"]
|
|
||||||
```
|
|
||||||
|
|
||||||
### request.idempotent
|
### request.idempotent
|
||||||
|
|
||||||
Check if the request is idempotent.
|
Check if the request is idempotent.
|
||||||
|
|
|
@ -211,10 +211,6 @@ delegate(proto, 'response')
|
||||||
*/
|
*/
|
||||||
|
|
||||||
delegate(proto, 'request')
|
delegate(proto, 'request')
|
||||||
.method('acceptsLanguages')
|
|
||||||
.method('acceptsEncodings')
|
|
||||||
.method('acceptsCharsets')
|
|
||||||
.method('accepts')
|
|
||||||
.method('get')
|
.method('get')
|
||||||
.method('is')
|
.method('is')
|
||||||
.access('querystring')
|
.access('querystring')
|
||||||
|
|
135
lib/request.js
135
lib/request.js
|
@ -7,8 +7,6 @@
|
||||||
|
|
||||||
const URL = require('url').URL;
|
const URL = require('url').URL;
|
||||||
const net = require('net');
|
const net = require('net');
|
||||||
const accepts = require('accepts');
|
|
||||||
const contentType = require('content-type');
|
|
||||||
const stringify = require('url').format;
|
const stringify = require('url').format;
|
||||||
const parse = require('parseurl');
|
const parse = require('parseurl');
|
||||||
const qs = require('querystring');
|
const qs = require('querystring');
|
||||||
|
@ -357,22 +355,6 @@ module.exports = {
|
||||||
return this.req.socket;
|
return this.req.socket;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the charset when present or undefined.
|
|
||||||
*
|
|
||||||
* @return {String}
|
|
||||||
* @api public
|
|
||||||
*/
|
|
||||||
|
|
||||||
get charset() {
|
|
||||||
try {
|
|
||||||
const { parameters } = contentType.parse(this.req);
|
|
||||||
return parameters.charset || '';
|
|
||||||
} catch (e) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return parsed Content-Length when present.
|
* Return parsed Content-Length when present.
|
||||||
*
|
*
|
||||||
|
@ -484,123 +466,6 @@ module.exports = {
|
||||||
.slice(offset);
|
.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) {
|
|
||||||
this._accept = obj;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the given `type(s)` is acceptable, returning
|
|
||||||
* the best match when true, otherwise `false`, in which
|
|
||||||
* case you should respond with 406 "Not Acceptable".
|
|
||||||
*
|
|
||||||
* The `type` value may be a single 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.
|
|
||||||
*
|
|
||||||
* Examples:
|
|
||||||
*
|
|
||||||
* // Accept: text/html
|
|
||||||
* this.accepts('html');
|
|
||||||
* // => "html"
|
|
||||||
*
|
|
||||||
* // Accept: text/*, application/json
|
|
||||||
* this.accepts('html');
|
|
||||||
* // => "html"
|
|
||||||
* this.accepts('text/html');
|
|
||||||
* // => "text/html"
|
|
||||||
* this.accepts('json', 'text');
|
|
||||||
* // => "json"
|
|
||||||
* this.accepts('application/json');
|
|
||||||
* // => "application/json"
|
|
||||||
*
|
|
||||||
* // Accept: text/*, application/json
|
|
||||||
* this.accepts('image/png');
|
|
||||||
* this.accepts('png');
|
|
||||||
* // => false
|
|
||||||
*
|
|
||||||
* // Accept: text/*;q=.5, application/json
|
|
||||||
* this.accepts(['html', 'json']);
|
|
||||||
* this.accepts('html', 'json');
|
|
||||||
* // => "json"
|
|
||||||
*
|
|
||||||
* @param {String|Array} type(s)...
|
|
||||||
* @return {String|Array|false}
|
|
||||||
* @api public
|
|
||||||
*/
|
|
||||||
|
|
||||||
accepts(...args) {
|
|
||||||
return this.accept.types(...args);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return accepted encodings or best fit based on `encodings`.
|
|
||||||
*
|
|
||||||
* Given `Accept-Encoding: gzip, deflate`
|
|
||||||
* an array sorted by quality is returned:
|
|
||||||
*
|
|
||||||
* ['gzip', 'deflate']
|
|
||||||
*
|
|
||||||
* @param {String|Array} encoding(s)...
|
|
||||||
* @return {String|Array}
|
|
||||||
* @api public
|
|
||||||
*/
|
|
||||||
|
|
||||||
acceptsEncodings(...args) {
|
|
||||||
return this.accept.encodings(...args);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return accepted charsets or best fit based on `charsets`.
|
|
||||||
*
|
|
||||||
* Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
|
|
||||||
* an array sorted by quality is returned:
|
|
||||||
*
|
|
||||||
* ['utf-8', 'utf-7', 'iso-8859-1']
|
|
||||||
*
|
|
||||||
* @param {String|Array} charset(s)...
|
|
||||||
* @return {String|Array}
|
|
||||||
* @api public
|
|
||||||
*/
|
|
||||||
|
|
||||||
acceptsCharsets(...args) {
|
|
||||||
return this.accept.charsets(...args);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return accepted languages or best fit based on `langs`.
|
|
||||||
*
|
|
||||||
* Given `Accept-Language: en;q=0.8, es, pt`
|
|
||||||
* an array sorted by quality is returned:
|
|
||||||
*
|
|
||||||
* ['es', 'pt', 'en']
|
|
||||||
*
|
|
||||||
* @param {String|Array} lang(s)...
|
|
||||||
* @return {Array|String}
|
|
||||||
* @api public
|
|
||||||
*/
|
|
||||||
|
|
||||||
acceptsLanguages(...args) {
|
|
||||||
return this.accept.languages(...args);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the incoming request contains the "Content-Type"
|
* Check if the incoming request contains the "Content-Type"
|
||||||
* header field, and it contains any of the give mime `type`s.
|
* header field, and it contains any of the give mime `type`s.
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
const contentDisposition = require('content-disposition');
|
const contentDisposition = require('content-disposition');
|
||||||
const ensureErrorHandler = require('error-inject');
|
const ensureErrorHandler = require('error-inject');
|
||||||
const getType = require('cache-content-type');
|
|
||||||
const onFinish = require('on-finished');
|
const onFinish = require('on-finished');
|
||||||
const isJSON = require('koa-is-json');
|
const isJSON = require('koa-is-json');
|
||||||
const escape = require('escape-html');
|
const escape = require('escape-html');
|
||||||
|
@ -267,7 +266,7 @@ module.exports = {
|
||||||
if (!statuses.redirect[this.status]) this.status = 302;
|
if (!statuses.redirect[this.status]) this.status = 302;
|
||||||
|
|
||||||
// html
|
// html
|
||||||
if (this.ctx.accepts('html')) {
|
if (this.ctx.headers.accept && this.ctx.headers.accept.indexOf('html') >= 0) {
|
||||||
url = escape(url);
|
url = escape(url);
|
||||||
this.type = 'text/html; charset=utf-8';
|
this.type = 'text/html; charset=utf-8';
|
||||||
this.body = `Redirecting to <a href="${url}">${url}</a>.`;
|
this.body = `Redirecting to <a href="${url}">${url}</a>.`;
|
||||||
|
@ -307,10 +306,34 @@ module.exports = {
|
||||||
* @api public
|
* @api public
|
||||||
*/
|
*/
|
||||||
|
|
||||||
set type(type) {
|
set type(orgType) {
|
||||||
type = getType(type);
|
let type = orgType
|
||||||
if (type) {
|
// If full type is specified, pass it straight on.
|
||||||
|
// Otherwise we do some basic checking for most common
|
||||||
|
// supported mime types.
|
||||||
|
if (type.indexOf('/') > 0 || type.indexOf(';') > 0) {
|
||||||
|
if (type.indexOf(';') === -1 && type.indexOf('text') >= 0) {
|
||||||
|
type += '; charset=utf-8'
|
||||||
|
}
|
||||||
this.set('Content-Type', type);
|
this.set('Content-Type', type);
|
||||||
|
} else if (type.indexOf('json')) {
|
||||||
|
this.set('Content-Type', 'application/json; charset=utf-8');
|
||||||
|
} else if (type.indexOf('html') => 0) {
|
||||||
|
this.set('Content-Type', 'text/html; charset=utf-8');
|
||||||
|
} else if (type.indexOf('css') => 0) {
|
||||||
|
this.set('Content-Type', 'text/css; charset=utf-8');
|
||||||
|
} else if (type.indexOf('js') => 0 || type.indexOf('javascript') => 0) {
|
||||||
|
this.set('Content-Type', 'application/javascript; charset=utf-8');
|
||||||
|
} else if (type.indexOf('png') => 0) {
|
||||||
|
this.set('Content-Type', 'image/png');
|
||||||
|
} else if (type.indexOf('jpg') => 0) {
|
||||||
|
this.set('Content-Type', 'image/jpeg');
|
||||||
|
} else if (type.indexOf('jpeg') => 0) {
|
||||||
|
this.set('Content-Type', 'image/jpeg');
|
||||||
|
} else if (type.indexOf('gif') => 0) {
|
||||||
|
this.set('Content-Type', 'image/gif');
|
||||||
|
} else if (type.indexOf('text')) {
|
||||||
|
this.set('Content-Type', 'text/plain; charset=utf-8');
|
||||||
} else {
|
} else {
|
||||||
this.remove('Content-Type');
|
this.remove('Content-Type');
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,10 +22,8 @@
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"accepts": "^1.3.5",
|
"content-disposition": "jharrilim/content-disposition#572383f
|
||||||
"cache-content-type": "^1.0.0",
|
",
|
||||||
"content-disposition": "~0.5.2",
|
|
||||||
"content-type": "^1.0.4",
|
|
||||||
"cookies": "~0.7.1",
|
"cookies": "~0.7.1",
|
||||||
"debug": "~3.1.0",
|
"debug": "~3.1.0",
|
||||||
"delegates": "^1.0.0",
|
"delegates": "^1.0.0",
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
|
|
||||||
'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/*']);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,94 +0,0 @@
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const assert = require('assert');
|
|
||||||
const context = require('../helpers/context');
|
|
||||||
|
|
||||||
describe('ctx.accepts(types)', () => {
|
|
||||||
describe('with no arguments', () => {
|
|
||||||
describe('when Accept is populated', () => {
|
|
||||||
it('should return all accepted types', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers.accept = 'application/*;q=0.2, image/jpeg;q=0.8, text/html, text/plain';
|
|
||||||
assert.deepEqual(ctx.accepts(), ['text/html', 'text/plain', 'image/jpeg', 'application/*']);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with no valid types', () => {
|
|
||||||
describe('when Accept is populated', () => {
|
|
||||||
it('should return false', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers.accept = 'application/*;q=0.2, image/jpeg;q=0.8, text/html, text/plain';
|
|
||||||
assert.equal(ctx.accepts('image/png', 'image/tiff'), false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when Accept is not populated', () => {
|
|
||||||
it('should return the first type', () => {
|
|
||||||
const ctx = context();
|
|
||||||
assert.equal(ctx.accepts('text/html', 'text/plain', 'image/jpeg', 'application/*'), 'text/html');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when extensions are given', () => {
|
|
||||||
it('should convert to mime types', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers.accept = 'text/plain, text/html';
|
|
||||||
assert.equal(ctx.accepts('html'), 'html');
|
|
||||||
assert.equal(ctx.accepts('.html'), '.html');
|
|
||||||
assert.equal(ctx.accepts('txt'), 'txt');
|
|
||||||
assert.equal(ctx.accepts('.txt'), '.txt');
|
|
||||||
assert.equal(ctx.accepts('png'), false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when an array is given', () => {
|
|
||||||
it('should return the first match', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers.accept = 'text/plain, text/html';
|
|
||||||
assert.equal(ctx.accepts(['png', 'text', 'html']), 'text');
|
|
||||||
assert.equal(ctx.accepts(['png', 'html']), 'html');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when multiple arguments are given', () => {
|
|
||||||
it('should return the first match', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers.accept = 'text/plain, text/html';
|
|
||||||
assert.equal(ctx.accepts('png', 'text', 'html'), 'text');
|
|
||||||
assert.equal(ctx.accepts('png', 'html'), 'html');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when present in Accept as an exact match', () => {
|
|
||||||
it('should return the type', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers.accept = 'text/plain, text/html';
|
|
||||||
assert.equal(ctx.accepts('text/html'), 'text/html');
|
|
||||||
assert.equal(ctx.accepts('text/plain'), 'text/plain');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when present in Accept as a type match', () => {
|
|
||||||
it('should return the type', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers.accept = 'application/json, */*';
|
|
||||||
assert.equal(ctx.accepts('text/html'), 'text/html');
|
|
||||||
assert.equal(ctx.accepts('text/plain'), 'text/plain');
|
|
||||||
assert.equal(ctx.accepts('image/png'), 'image/png');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when present in Accept as a subtype match', () => {
|
|
||||||
it('should return the type', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers.accept = 'application/json, text/*';
|
|
||||||
assert.equal(ctx.accepts('text/html'), 'text/html');
|
|
||||||
assert.equal(ctx.accepts('text/plain'), 'text/plain');
|
|
||||||
assert.equal(ctx.accepts('image/png'), false);
|
|
||||||
assert.equal(ctx.accepts('png'), false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,52 +0,0 @@
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const assert = require('assert');
|
|
||||||
const context = require('../helpers/context');
|
|
||||||
|
|
||||||
describe('ctx.acceptsCharsets()', () => {
|
|
||||||
describe('with no arguments', () => {
|
|
||||||
describe('when Accept-Charset is populated', () => {
|
|
||||||
it('should return accepted types', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers['accept-charset'] = 'utf-8, iso-8859-1;q=0.2, utf-7;q=0.5';
|
|
||||||
assert.deepEqual(ctx.acceptsCharsets(), ['utf-8', 'utf-7', 'iso-8859-1']);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with multiple arguments', () => {
|
|
||||||
describe('when Accept-Charset is populated', () => {
|
|
||||||
describe('if any types match', () => {
|
|
||||||
it('should return the best fit', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers['accept-charset'] = 'utf-8, iso-8859-1;q=0.2, utf-7;q=0.5';
|
|
||||||
assert.equal(ctx.acceptsCharsets('utf-7', 'utf-8'), 'utf-8');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if no types match', () => {
|
|
||||||
it('should return false', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers['accept-charset'] = 'utf-8, iso-8859-1;q=0.2, utf-7;q=0.5';
|
|
||||||
assert.equal(ctx.acceptsCharsets('utf-16'), false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when Accept-Charset is not populated', () => {
|
|
||||||
it('should return the first type', () => {
|
|
||||||
const ctx = context();
|
|
||||||
assert.equal(ctx.acceptsCharsets('utf-7', 'utf-8'), 'utf-7');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with an array', () => {
|
|
||||||
it('should return the best fit', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers['accept-charset'] = 'utf-8, iso-8859-1;q=0.2, utf-7;q=0.5';
|
|
||||||
assert.equal(ctx.acceptsCharsets(['utf-7', 'utf-8']), 'utf-8');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,43 +0,0 @@
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const assert = require('assert');
|
|
||||||
const context = require('../helpers/context');
|
|
||||||
|
|
||||||
describe('ctx.acceptsEncodings()', () => {
|
|
||||||
describe('with no arguments', () => {
|
|
||||||
describe('when Accept-Encoding is populated', () => {
|
|
||||||
it('should return accepted types', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers['accept-encoding'] = 'gzip, compress;q=0.2';
|
|
||||||
assert.deepEqual(ctx.acceptsEncodings(), ['gzip', 'compress', 'identity']);
|
|
||||||
assert.equal(ctx.acceptsEncodings('gzip', 'compress'), 'gzip');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when Accept-Encoding is not populated', () => {
|
|
||||||
it('should return identity', () => {
|
|
||||||
const ctx = context();
|
|
||||||
assert.deepEqual(ctx.acceptsEncodings(), ['identity']);
|
|
||||||
assert.equal(ctx.acceptsEncodings('gzip', 'deflate', 'identity'), 'identity');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with multiple arguments', () => {
|
|
||||||
it('should return the best fit', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers['accept-encoding'] = 'gzip, compress;q=0.2';
|
|
||||||
assert.equal(ctx.acceptsEncodings('compress', 'gzip'), 'gzip');
|
|
||||||
assert.equal(ctx.acceptsEncodings('gzip', 'compress'), 'gzip');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with an array', () => {
|
|
||||||
it('should return the best fit', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers['accept-encoding'] = 'gzip, compress;q=0.2';
|
|
||||||
assert.equal(ctx.acceptsEncodings(['compress', 'gzip']), 'gzip');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,52 +0,0 @@
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const assert = require('assert');
|
|
||||||
const context = require('../helpers/context');
|
|
||||||
|
|
||||||
describe('ctx.acceptsLanguages(langs)', () => {
|
|
||||||
describe('with no arguments', () => {
|
|
||||||
describe('when Accept-Language is populated', () => {
|
|
||||||
it('should return accepted types', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers['accept-language'] = 'en;q=0.8, es, pt';
|
|
||||||
assert.deepEqual(ctx.acceptsLanguages(), ['es', 'pt', 'en']);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with multiple arguments', () => {
|
|
||||||
describe('when Accept-Language is populated', () => {
|
|
||||||
describe('if any types types match', () => {
|
|
||||||
it('should return the best fit', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers['accept-language'] = 'en;q=0.8, es, pt';
|
|
||||||
assert.equal(ctx.acceptsLanguages('es', 'en'), 'es');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('if no types match', () => {
|
|
||||||
it('should return false', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers['accept-language'] = 'en;q=0.8, es, pt';
|
|
||||||
assert.equal(ctx.acceptsLanguages('fr', 'au'), false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when Accept-Language is not populated', () => {
|
|
||||||
it('should return the first type', () => {
|
|
||||||
const ctx = context();
|
|
||||||
assert.equal(ctx.acceptsLanguages('es', 'en'), 'es');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with an array', () => {
|
|
||||||
it('should return the best fit', () => {
|
|
||||||
const ctx = context();
|
|
||||||
ctx.req.headers['accept-language'] = 'en;q=0.8, es, pt';
|
|
||||||
assert.equal(ctx.acceptsLanguages(['es', 'en']), 'es');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,36 +0,0 @@
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const request = require('../helpers/context').request;
|
|
||||||
const assert = require('assert');
|
|
||||||
|
|
||||||
describe('req.charset', () => {
|
|
||||||
describe('with no content-type present', () => {
|
|
||||||
it('should return ""', () => {
|
|
||||||
const req = request();
|
|
||||||
assert('' === req.charset);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with charset present', () => {
|
|
||||||
it('should return ""', () => {
|
|
||||||
const req = request();
|
|
||||||
req.header['content-type'] = 'text/plain';
|
|
||||||
assert('' === req.charset);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with a charset', () => {
|
|
||||||
it('should return the charset', () => {
|
|
||||||
const req = request();
|
|
||||||
req.header['content-type'] = 'text/plain; charset=utf-8';
|
|
||||||
assert.equal(req.charset, 'utf-8');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return "" if content-type is invalid', () => {
|
|
||||||
const req = request();
|
|
||||||
req.header['content-type'] = 'application/json; application/text; charset=utf-8';
|
|
||||||
assert.equal(req.charset, '');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
Loading…
Reference in a new issue