Fix routing regression when altering req.method

This commit is contained in:
Douglas Christopher Wilson 2014-07-06 19:42:08 -04:00
parent b4b2efee0f
commit 23a49ff61e
3 changed files with 40 additions and 6 deletions

View File

@ -1,3 +1,8 @@
unreleased
==========
* fix routing regression when altering `req.method`
4.5.0 / 2014-07-04
==================

View File

@ -115,8 +115,6 @@ proto.handle = function(req, res, done) {
debug('dispatching %s %s', req.method, req.url);
var method = req.method.toLowerCase();
var search = 1 + req.url.indexOf('?');
var pathlength = search ? search - 1 : req.url.length;
var fqdn = 1 + req.url.substr(0, pathlength).indexOf('://');
@ -142,7 +140,7 @@ proto.handle = function(req, res, done) {
req.next = next;
// for options requests, respond with a default if nothing else responds
if (method === 'options') {
if (req.method === 'OPTIONS') {
done = wrap(done, function(old, err) {
if (err || options.length === 0) return old(err);
@ -191,15 +189,16 @@ proto.handle = function(req, res, done) {
return next(err);
}
var method = req.method;
var has_method = route._handles_method(method);
// build up automatic options response
if (!has_method && method === 'options') {
if (!has_method && method === 'OPTIONS') {
options.push.apply(options, route._options());
}
// don't even bother
if (!has_method && method !== 'head') {
if (!has_method && method !== 'HEAD') {
return next();
}

View File

@ -1,4 +1,5 @@
var after = require('after');
var express = require('../')
, request = require('supertest')
, assert = require('assert')
@ -32,7 +33,7 @@ describe('app.router', function(){
.expect(200, '1', done);
})
describe('methods supported', function(){
describe('methods', function(){
methods.concat('del').forEach(function(method){
if (method === 'connect') return;
@ -58,6 +59,35 @@ describe('app.router', function(){
app[method].bind(app, '/', 3).should.throw(/Number/);
})
});
it('should re-route when method is altered', function (done) {
var app = express();
var cb = after(3, done);
app.use(function (req, res, next) {
if (req.method !== 'POST') return next();
req.method = 'DELETE';
res.setHeader('X-Method-Altered', '1');
next();
});
app.delete('/', function (req, res) {
res.end('deleted everything');
});
request(app)
.get('/')
.expect(404, 'Cannot GET /\n', cb);
request(app)
.delete('/')
.expect(200, 'deleted everything', cb);
request(app)
.post('/')
.expect('X-Method-Altered', '1')
.expect(200, 'deleted everything', cb);
});
})
describe('decode querystring', function(){