Remove is-type and replace with a helper function :)
This commit is contained in:
parent
54aa155328
commit
5a9a3f0dc2
6 changed files with 67 additions and 65 deletions
|
@ -1,10 +1,12 @@
|
|||
const getMimetype = require('./getmimetype');
|
||||
|
||||
module.exports = function accepts(ctx, type, ask) {
|
||||
module.exports = function accepts(ctx, type, ask, isReq = true) {
|
||||
if (!ctx._accept) {
|
||||
ctx._accept = {};
|
||||
}
|
||||
if (!ctx._accept[type]) {
|
||||
|
||||
// We don't need to parse content-type
|
||||
if (!ctx._accept[type] && type !== 'content-type') {
|
||||
let types = ctx.req.headers[type];
|
||||
let quality = 9999; // Little bit of a hack :)
|
||||
if (types) {
|
||||
|
@ -27,37 +29,67 @@ module.exports = function accepts(ctx, type, ask) {
|
|||
if (type === 'accept-encoding') {
|
||||
types.push('identity');
|
||||
}
|
||||
|
||||
ctx._accept[type] = types;
|
||||
}
|
||||
|
||||
let can = ctx._accept[type];
|
||||
let can;
|
||||
|
||||
if (type === 'content-type') {
|
||||
if (isReq) {
|
||||
// Check if a request has a request body.
|
||||
// A request with a body __must__ either have `transfer-encoding`
|
||||
// or `content-length` headers set.
|
||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3
|
||||
if (ctx.req.headers['transfer-encoding'] === undefined
|
||||
&& isNaN(ctx.req.headers['content-length'])) {
|
||||
return null;
|
||||
}
|
||||
can = ctx.req.headers[type];
|
||||
} else {
|
||||
can = ctx.type;
|
||||
}
|
||||
} else {
|
||||
can = ctx._accept[type];
|
||||
if (!can.length) can = null;
|
||||
}
|
||||
|
||||
// If empty argument, return all supported can
|
||||
if (ask.length === 0) {
|
||||
return can;
|
||||
if (ask.length === 0 && can) {
|
||||
return can || false;
|
||||
}
|
||||
|
||||
// If no supported was sent, return the first ask item
|
||||
if (!can.length) {
|
||||
// unless we're dealing with content-type we need to be smarter.
|
||||
if (!can) {
|
||||
if (type === 'content-type') {
|
||||
return false;
|
||||
}
|
||||
return ask[0];
|
||||
}
|
||||
|
||||
let parsed = ask.slice();
|
||||
|
||||
if (type === 'accept') {
|
||||
if (type === 'accept' || type === 'content-type') {
|
||||
for (let t = 0; t < parsed.length; t++) {
|
||||
if (parsed[t].startsWith('*/')) {
|
||||
parsed[t] = parsed[t].substr(2);
|
||||
} else if (parsed[t].indexOf('/*') < 0) {
|
||||
parsed[t] = getMimetype(parsed[t]) || parsed[t];
|
||||
}
|
||||
}
|
||||
if (type === 'content-type') {
|
||||
can = [can.split(';')[0]];
|
||||
}
|
||||
}
|
||||
|
||||
// Loop over the supported can, returning the first
|
||||
// matching ask type.
|
||||
for (let i = 0; i < can.length; i++) {
|
||||
for (let t = 0; t < parsed.length; t++) {
|
||||
// Check if we allow root checking (application/*)
|
||||
if (type === 'accept') {
|
||||
let allowRoot = can[i].indexOf('/*') >= 0;
|
||||
if (type === 'accept' || type === 'content-type') {
|
||||
let allowRoot = can[i].indexOf('/*') >= 0
|
||||
|| parsed[t].indexOf('/*') >= 0;
|
||||
|
||||
// Big if :)
|
||||
if (can[i] === '*/*'
|
||||
|
@ -66,6 +98,12 @@ module.exports = function accepts(ctx, type, ask) {
|
|||
&& parsed[t].indexOf('/') >= 0
|
||||
&& can[i].split('/')[0] === parsed[t].split('/')[0]
|
||||
)) {
|
||||
if (type === 'content-type') {
|
||||
if (ask[t].indexOf('/') === -1) {
|
||||
return ask[t];
|
||||
}
|
||||
return can[i];
|
||||
}
|
||||
return ask[t];
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
*/
|
||||
|
||||
const debug = require('debug-ms')('koa:application');
|
||||
const Emitter = require('events');
|
||||
const util = require('util');
|
||||
const Stream = require('stream');
|
||||
const http = require('http');
|
||||
const onFinished = require('./onfinish');
|
||||
const response = require('./response');
|
||||
const compose = require('./compose');
|
||||
|
@ -13,10 +17,6 @@ const isJSON = require('./isjson');
|
|||
const context = require('./context');
|
||||
const request = require('./request');
|
||||
const statuses = require('./statuses');
|
||||
const Emitter = require('events');
|
||||
const util = require('util');
|
||||
const Stream = require('stream');
|
||||
const http = require('http');
|
||||
|
||||
/**
|
||||
* Expose `Application` class.
|
||||
|
|
|
@ -8,11 +8,10 @@
|
|||
const URL = require('url').URL;
|
||||
const net = require('net');
|
||||
const stringify = require('url').format;
|
||||
const fastparse = require('./fastparse');
|
||||
const qs = require('querystring');
|
||||
const typeis = require('type-is');
|
||||
const fresh = require('fresh');
|
||||
const util = require('util');
|
||||
const fastparse = require('./fastparse');
|
||||
const accepts = require('./accepts');
|
||||
|
||||
const IP = Symbol('context#ip');
|
||||
|
@ -473,40 +472,6 @@ module.exports = {
|
|||
.slice(offset);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get accept object.
|
||||
* Lazily memoized.
|
||||
*
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
accept(type, ) {
|
||||
if (!this._accept) {
|
||||
let types = this.req.headers.accept;
|
||||
if (types) {
|
||||
types = types.split(',')
|
||||
.map(x => {
|
||||
x = x.trim();
|
||||
let q = 1;
|
||||
if (x.indexOf('q=') >= 0) {
|
||||
q = parseFloat(x.substr(x.indexOf('q=') + 2)) || 1;
|
||||
x = x.substr(0, x.indexOf(';'));
|
||||
}
|
||||
return [x, q];
|
||||
})
|
||||
.sort((a, b) => b[1] - a[1])
|
||||
.map(x => x[0]);
|
||||
} else {
|
||||
types = [];
|
||||
}
|
||||
|
||||
this._accept = {
|
||||
types: types
|
||||
};
|
||||
}
|
||||
return this._accept;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the given `type(s)` is acceptable, returning
|
||||
* the best match when true, otherwise `false`, in which
|
||||
|
@ -658,9 +623,9 @@ module.exports = {
|
|||
*/
|
||||
|
||||
is(types) {
|
||||
if (!types) return typeis(this.req);
|
||||
if (!types) return accepts(this, 'content-type', []);
|
||||
if (!Array.isArray(types)) types = [].slice.call(arguments);
|
||||
return typeis(this.req, types);
|
||||
return accepts(this, 'content-type', types);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
|
||||
const ReadStream = require('fs').ReadStream;
|
||||
const contentDisposition = require('content-disposition');
|
||||
const onFinish = require('./onfinish');
|
||||
const isJSON = require('./isjson');
|
||||
const typeis = require('type-is').is;
|
||||
const statuses = require('./statuses');
|
||||
const assert = require('assert');
|
||||
const extname = require('path').extname;
|
||||
const getMimetype = require('./getmimetype');
|
||||
const util = require('util');
|
||||
const onFinish = require('./onfinish');
|
||||
const isJSON = require('./isjson');
|
||||
const statuses = require('./statuses');
|
||||
const getMimetype = require('./getmimetype');
|
||||
const accepts = require('./accepts');
|
||||
|
||||
/**
|
||||
* Prototype.
|
||||
|
@ -287,6 +287,8 @@ module.exports = {
|
|||
|
||||
// html
|
||||
if (this.ctx.headers.accept && this.ctx.headers.accept.indexOf('html') >= 0) {
|
||||
// Sanitize the url in case developer does something silly like:
|
||||
// ctx.redirect(ctx.query.goto) or something without sanitizing himself.
|
||||
url = url.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
|
@ -434,10 +436,9 @@ module.exports = {
|
|||
*/
|
||||
|
||||
is(types) {
|
||||
const type = this.type;
|
||||
if (!types) return type || false;
|
||||
if (!types) return this.type || false;
|
||||
if (!Array.isArray(types)) types = [].slice.call(arguments);
|
||||
return typeis(type, types);
|
||||
return accepts(this, 'content-type', types, false);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,8 +25,7 @@
|
|||
"content-disposition": "jharrilim/content-disposition#572383f",
|
||||
"debug-ms": "~4.1.2",
|
||||
"fresh": "~0.5.2",
|
||||
"http-errors-lite": "^2.0.2",
|
||||
"type-is": "^1.6.16"
|
||||
"http-errors-lite": "^2.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"egg-bin": "^4.13.0",
|
||||
|
|
|
@ -32,8 +32,7 @@ describe('app', () => {
|
|||
ctx.socket.writable = false;
|
||||
ctx.status = 204;
|
||||
// throw if .writeHead or .end is called
|
||||
ctx.res.writeHead =
|
||||
ctx.res.end = () => {
|
||||
ctx.res.writeHead = ctx.res.end = () => {
|
||||
throw new Error('response sent');
|
||||
};
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue