-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathindex.js
136 lines (108 loc) · 2.88 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
'use strict'
/*!
* method-override
* Copyright(c) 2010 Sencha Inc.
* Copyright(c) 2011 TJ Holowaychuk
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2014 Douglas Christopher Wilson
* Copyright(c) 2015 Fangdun Cai
* MIT Licensed
*/
/**
* Module dependences.
*/
const debug = require('debug')('method-override')
const methods = require('methods')
const ALLOWED_METHODS = 'POST'
const HTTP_METHOD_OVERRIDE_HEADER = "X-HTTP-Method-Override"
/**
* Method Override:
*
* Provides faux HTTP method support.
*
* Pass an optional `getter` to use when checking for
* a method override.
*
* A string is converted to a getter that will look for
* the method in `req.body[getter]` and a function will be
* called with `req` and expects the method to be returned.
* If the string starts with `X-` then it will look in
* `req.headers[getter]` instead.
*
* The original method is available via `req.originalMethod`.
*
* @param {string|function} [getter=X-HTTP-Method-Override]
* @param {object} [options]
* @return {function}
* @api public
*/
module.exports = methodOverride
function methodOverride(getter, options) {
options = options || {}
// get the getter fn
const get = typeof getter === 'function'
? getter
: createGetter(getter || HTTP_METHOD_OVERRIDE_HEADER)
// get allowed request methods to examine
const methods = options.methods === undefined
? ALLOWED_METHODS.split(' ')
: options.methods
return (ctx, next) => {
const req = ctx.request
let method
let val
req.originalMethod = req.originalMethod || req.method
// validate request is an allowed method
if (methods && methods.indexOf(req.originalMethod) === -1) {
return next()
}
val = get(req, ctx.response)
method = Array.isArray(val) ? val[0] : val
// replace
if (method !== undefined && supports(method)) {
req.method = method.toUpperCase()
debug(`override ${req.originalMethod} as ${req.method}`)
}
return next()
}
}
/**
* Create a getter for the given string.
*/
function createGetter(str) {
if (str.substring(0, 2).toUpperCase() === 'X-') {
// header getter
return createHeaderGetter(str)
}
return createQueryGetter(str)
}
/**
* Create a getter for the given query key name.
*/
function createQueryGetter(key) {
return queryGetter
function queryGetter(req) {
return req.query[key]
}
}
/**
* Create a getter for the given header name.
*/
function createHeaderGetter(str) {
var header = str.toLowerCase()
return headerGetter
function headerGetter(req, res) {
// set appropriate Vary header
res.vary(str)
// multiple headers get joined with comma by node.js core
return (req.headers[header] || '').split(/ *, */)
}
}
/**
* Check if node supports `method`.
*/
function supports(method) {
return method
&& typeof method === 'string'
&& methods.indexOf(method.toLowerCase()) !== -1
}