mirror of
https://github.com/zebrajr/express.git
synced 2025-12-06 00:19:48 +01:00
parent
b43205ca98
commit
e29fa25bb4
|
|
@ -1,6 +1,11 @@
|
|||
unreleased
|
||||
==========
|
||||
|
||||
* configurable query parser with `app.set('query parser', parser)`
|
||||
- `app.set('query parser', 'extended')` parse with "qs" module
|
||||
- `app.set('query parser', 'simple')` parse with "querystring" core module
|
||||
- `app.set('query parser', false)` disable query string parsing
|
||||
- `app.set('query parser', true)` enable simple parsing
|
||||
* perf: prevent multiple `Buffer` creation in `res.send`
|
||||
|
||||
4.6.1 / 2014-07-12
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ var debug = require('debug')('express:application');
|
|||
var View = require('./view');
|
||||
var http = require('http');
|
||||
var compileETag = require('./utils').compileETag;
|
||||
var compileQueryParser = require('./utils').compileQueryParser;
|
||||
var compileTrust = require('./utils').compileTrust;
|
||||
var deprecate = require('depd')('express');
|
||||
var resolve = require('path').resolve;
|
||||
|
|
@ -51,6 +52,7 @@ app.defaultConfiguration = function(){
|
|||
this.set('etag', 'weak');
|
||||
var env = process.env.NODE_ENV || 'development';
|
||||
this.set('env', env);
|
||||
this.set('query parser', 'extended');
|
||||
this.set('subdomain offset', 2);
|
||||
this.set('trust proxy', false);
|
||||
|
||||
|
|
@ -104,7 +106,7 @@ app.lazyrouter = function() {
|
|||
strict: this.enabled('strict routing')
|
||||
});
|
||||
|
||||
this._router.use(query());
|
||||
this._router.use(query(this.get('query parser fn')));
|
||||
this._router.use(middleware.init(this));
|
||||
}
|
||||
};
|
||||
|
|
@ -306,6 +308,10 @@ app.set = function(setting, val){
|
|||
debug('compile etag %s', val);
|
||||
this.set('etag fn', compileETag(val));
|
||||
break;
|
||||
case 'query parser':
|
||||
debug('compile query parser %s', val);
|
||||
this.set('query parser fn', compileQueryParser(val));
|
||||
break;
|
||||
case 'trust proxy':
|
||||
debug('compile trust proxy %s', val);
|
||||
this.set('trust proxy fn', compileTrust(val));
|
||||
|
|
|
|||
|
|
@ -2,36 +2,27 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var qs = require('qs');
|
||||
var parseUrl = require('parseurl');
|
||||
var qs = require('qs');
|
||||
|
||||
/**
|
||||
* Query:
|
||||
*
|
||||
* Automatically parse the query-string when available,
|
||||
* populating the `req.query` object using
|
||||
* [qs](https://github.com/visionmedia/node-querystring).
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* .use(connect.query())
|
||||
* .use(function(req, res){
|
||||
* res.end(JSON.stringify(req.query));
|
||||
* });
|
||||
*
|
||||
* The `options` passed are provided to qs.parse function.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function query(options){
|
||||
module.exports = function query(options) {
|
||||
var queryparse = qs.parse;
|
||||
|
||||
if (typeof options === 'function') {
|
||||
queryparse = options;
|
||||
options = undefined;
|
||||
}
|
||||
|
||||
return function query(req, res, next){
|
||||
if (!req.query) {
|
||||
req.query = ~req.url.indexOf('?')
|
||||
? qs.parse(parseUrl(req).query, options)
|
||||
: {};
|
||||
var val = parseUrl(req).query;
|
||||
req.query = queryparse(val, options);
|
||||
}
|
||||
|
||||
next();
|
||||
|
|
|
|||
48
lib/utils.js
48
lib/utils.js
|
|
@ -7,6 +7,8 @@ var crc32 = require('buffer-crc32');
|
|||
var crypto = require('crypto');
|
||||
var basename = require('path').basename;
|
||||
var proxyaddr = require('proxy-addr');
|
||||
var qs = require('qs');
|
||||
var querystring = require('querystring');
|
||||
var typer = require('media-typer');
|
||||
|
||||
/**
|
||||
|
|
@ -202,6 +204,41 @@ exports.compileETag = function(val) {
|
|||
return fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile "query parser" value to function.
|
||||
*
|
||||
* @param {String|Function} val
|
||||
* @return {Function}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.compileQueryParser = function compileQueryParser(val) {
|
||||
var fn;
|
||||
|
||||
if (typeof val === 'function') {
|
||||
return val;
|
||||
}
|
||||
|
||||
switch (val) {
|
||||
case true:
|
||||
fn = querystring.parse;
|
||||
break;
|
||||
case false:
|
||||
fn = newObject;
|
||||
break;
|
||||
case 'extended':
|
||||
fn = qs.parse;
|
||||
break;
|
||||
case 'simple':
|
||||
fn = querystring.parse;
|
||||
break;
|
||||
default:
|
||||
throw new TypeError('unknown value for query parser function: ' + val);
|
||||
}
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile "proxy trust" value to function.
|
||||
*
|
||||
|
|
@ -252,3 +289,14 @@ exports.setCharset = function(type, charset){
|
|||
// format type
|
||||
return typer.format(parsed);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return new empty objet.
|
||||
*
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function newObject() {
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,33 +5,91 @@ var express = require('../')
|
|||
describe('req', function(){
|
||||
describe('.query', function(){
|
||||
it('should default to {}', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
req.query.should.eql({});
|
||||
res.end();
|
||||
});
|
||||
var app = createApp();
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(res){
|
||||
done();
|
||||
});
|
||||
})
|
||||
.expect(200, '{}', done);
|
||||
});
|
||||
|
||||
it('should contain the parsed query-string', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
req.query.should.eql({ user: { name: 'tj' }});
|
||||
res.end();
|
||||
});
|
||||
it('should default to parse complex keys', function (done) {
|
||||
var app = createApp();
|
||||
|
||||
request(app)
|
||||
.get('/?user[name]=tj')
|
||||
.end(function(res){
|
||||
done();
|
||||
.expect(200, '{"user":{"name":"tj"}}', done);
|
||||
});
|
||||
|
||||
describe('when "query parser" is extended', function () {
|
||||
it('should parse complex keys', function (done) {
|
||||
var app = createApp('extended');
|
||||
|
||||
request(app)
|
||||
.get('/?user[name]=tj')
|
||||
.expect(200, '{"user":{"name":"tj"}}', done);
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
describe('when "query parser" is simple', function () {
|
||||
it('should not parse complex keys', function (done) {
|
||||
var app = createApp('simple');
|
||||
|
||||
request(app)
|
||||
.get('/?user[name]=tj')
|
||||
.expect(200, '{"user[name]":"tj"}', done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "query parser" is a function', function () {
|
||||
it('should parse using function', function (done) {
|
||||
var app = createApp(function (str) {
|
||||
return {'length': (str || '').length};
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/?user[name]=tj')
|
||||
.expect(200, '{"length":17}', done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "query parser" disabled', function () {
|
||||
it('should not parse query', function (done) {
|
||||
var app = createApp(false);
|
||||
|
||||
request(app)
|
||||
.get('/?user[name]=tj')
|
||||
.expect(200, '{}', done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "query parser" disabled', function () {
|
||||
it('should not parse complex keys', function (done) {
|
||||
var app = createApp(true);
|
||||
|
||||
request(app)
|
||||
.get('/?user[name]=tj')
|
||||
.expect(200, '{"user[name]":"tj"}', done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "query parser" an unknown value', function () {
|
||||
it('should throw', function () {
|
||||
createApp.bind(null, 'bogus').should.throw(/unknown value.*query parser/);
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
function createApp(setting) {
|
||||
var app = express();
|
||||
|
||||
if (setting !== undefined) {
|
||||
app.set('query parser', setting);
|
||||
}
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.send(req.query);
|
||||
});
|
||||
|
||||
return app;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user