3 * Copyright(c) 2010 Sencha Inc.
4 * Copyright(c) 2011 TJ Holowaychuk
5 * Copyright(c) 2014 Jonathan Ong
6 * Copyright(c) 2014 Douglas Christopher Wilson
13 * Module dependencies.
16 var debug = require('debug')('method-override')
17 var methods = require('methods')
18 var parseurl = require('parseurl')
19 var querystring = require('querystring')
20 var vary = require('vary')
25 * Provides faux HTTP method support.
27 * Pass an optional `getter` to use when checking for
30 * A string is converted to a getter that will look for
31 * the method in `req.body[getter]` and a function will be
32 * called with `req` and expects the method to be returned.
33 * If the string starts with `X-` then it will look in
34 * `req.headers[getter]` instead.
36 * The original method is available via `req.originalMethod`.
38 * @param {string|function} [getter=X-HTTP-Method-Override]
39 * @param {object} [options]
44 module.exports = function methodOverride (getter, options) {
45 var opts = options || {}
48 var get = typeof getter === 'function'
50 : createGetter(getter || 'X-HTTP-Method-Override')
52 // get allowed request methods to examine
53 var methods = opts.methods === undefined
57 return function methodOverride (req, res, next) {
61 req.originalMethod = req.originalMethod || req.method
63 // validate request is an allowed method
64 if (methods && methods.indexOf(req.originalMethod) === -1) {
69 method = Array.isArray(val)
74 if (method !== undefined && supports(method)) {
75 req.method = method.toUpperCase()
76 debug('override %s as %s', req.originalMethod, req.method)
84 * Create a getter for the given string.
87 function createGetter (str) {
88 if (str.substr(0, 2).toUpperCase() === 'X-') {
90 return createHeaderGetter(str)
93 return createQueryGetter(str)
97 * Create a getter for the given query key name.
100 function createQueryGetter (key) {
101 return function (req, res) {
102 var url = parseurl(req)
103 var query = querystring.parse(url.query || '')
109 * Create a getter for the given header name.
112 function createHeaderGetter (str) {
113 var header = str.toLowerCase()
115 return function (req, res) {
116 // set appropriate Vary header
119 // multiple headers get joined with comma by node.js core
120 return (req.headers[header] || '').split(/ *, */)
125 * Check if node supports `method`.
128 function supports (method) {
130 typeof method === 'string' &&
131 methods.indexOf(method.toLowerCase()) !== -1