Skip to content

Commit 126187c

Browse files
committed
add whitelisting of supported methods to methodOverride()
1 parent b0df35b commit 126187c

File tree

3 files changed

+77
-8
lines changed

3 files changed

+77
-8
lines changed

lib/middleware/methodOverride.js

+25-6
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,17 @@
66
* MIT Licensed
77
*/
88

9+
/**
10+
* Module dependencies.
11+
*/
12+
13+
var methods = require('methods');
14+
915
/**
1016
* Method Override:
11-
*
17+
*
1218
* Provides faux HTTP method support.
13-
*
19+
*
1420
* Pass an optional `key` to use when checking for
1521
* a method override, othewise defaults to _\_method_.
1622
* The original method is available via `req.originalMethod`.
@@ -23,18 +29,31 @@
2329
module.exports = function methodOverride(key){
2430
key = key || "_method";
2531
return function methodOverride(req, res, next) {
32+
var method;
2633
req.originalMethod = req.originalMethod || req.method;
2734

2835
// req.body
2936
if (req.body && key in req.body) {
30-
req.method = req.body[key].toUpperCase();
37+
method = req.body[key].toLowerCase();
3138
delete req.body[key];
39+
}
40+
3241
// check X-HTTP-Method-Override
33-
} else if (req.headers['x-http-method-override']) {
34-
req.method = req.headers['x-http-method-override'].toUpperCase();
42+
if (req.headers['x-http-method-override']) {
43+
method = req.headers['x-http-method-override'].toLowerCase();
3544
}
36-
45+
46+
// replace
47+
if (supports(method)) req.method = method.toUpperCase();
48+
3749
next();
3850
};
3951
};
4052

53+
/**
54+
* Check if node supports `method`.
55+
*/
56+
57+
function supports(method) {
58+
return ~methods.indexOf(method);
59+
}

package.json

+9-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22
"name": "connect",
33
"version": "2.8.1",
44
"description": "High performance middleware framework",
5-
"keywords": ["framework", "web", "middleware", "connect", "rack"],
5+
"keywords": [
6+
"framework",
7+
"web",
8+
"middleware",
9+
"connect",
10+
"rack"
11+
],
612
"repository": "git://github.com/senchalabs/connect.git",
713
"author": "TJ Holowaychuk <[email protected]> (http://tjholowaychuk.com)",
814
"dependencies": {
@@ -16,7 +22,8 @@
1622
"fresh": "0.1.0",
1723
"pause": "0.0.1",
1824
"uid2": "0.0.2",
19-
"debug": "*"
25+
"debug": "*",
26+
"methods": "0.0.1"
2027
},
2128
"devDependencies": {
2229
"should": "*",

test/methodOverride.js

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
2+
var connect = require('../');
3+
4+
var app = connect();
5+
6+
app.use(connect.bodyParser());
7+
app.use(connect.methodOverride());
8+
9+
app.use(function(req, res){
10+
res.end(req.method);
11+
});
12+
13+
describe('connect.methodOverride()', function(){
14+
it('should not touch the method by default', function(done){
15+
app.request()
16+
.get('/')
17+
.expect('GET', done);
18+
})
19+
20+
it('should support req.body._method', function(done){
21+
app.request()
22+
.post('/')
23+
.set('Content-Type', 'application/x-www-form-urlencoded')
24+
.write('_method=DELETE')
25+
.expect('DELETE', done);
26+
})
27+
28+
it('should be case in-sensitive', function(done){
29+
app.request()
30+
.post('/')
31+
.set('Content-Type', 'application/x-www-form-urlencoded')
32+
.write('_method=delete')
33+
.expect('DELETE', done);
34+
})
35+
36+
it('should ignore invalid methods', function(done){
37+
app.request()
38+
.post('/')
39+
.set('Content-Type', 'application/x-www-form-urlencoded')
40+
.write('_method=<whatever>')
41+
.expect('POST', done);
42+
})
43+
})

0 commit comments

Comments
 (0)