arnaucube
arnaucube/thoughtsPublic Self-hosted repository
thoughts/node_modules/method-override/index.js
node_modules/method-override/index.jsRaw
  1/*!
  2 * method-override
  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
  7 * MIT Licensed
  8 */
  9
 10'use strict'
 11
 12/**
 13 * Module dependencies.
 14 */
 15
 16var debug = require('debug')('method-override')
 17var methods = require('methods')
 18var parseurl = require('parseurl')
 19var querystring = require('querystring')
 20var vary = require('vary')
 21
 22/**
 23 * Method Override:
 24 *
 25 * Provides faux HTTP method support.
 26 *
 27 * Pass an optional `getter` to use when checking for
 28 * a method override.
 29 *
 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.
 35 *
 36 * The original method is available via `req.originalMethod`.
 37 *
 38 * @param {string|function} [getter=X-HTTP-Method-Override]
 39 * @param {object} [options]
 40 * @return {function}
 41 * @api public
 42 */
 43
 44module.exports = function methodOverride (getter, options) {
 45  options = options || {}
 46
 47  // get the getter fn
 48  var get = typeof getter === 'function'
 49    ? getter
 50    : createGetter(getter || 'X-HTTP-Method-Override')
 51
 52  // get allowed request methods to examine
 53  var methods = options.methods === undefined
 54    ? ['POST']
 55    : options.methods
 56
 57  return function methodOverride (req, res, next) {
 58    var method
 59    var val
 60
 61    req.originalMethod = req.originalMethod || req.method
 62
 63    // validate request is an allowed method
 64    if (methods && methods.indexOf(req.originalMethod) === -1) {
 65      return next()
 66    }
 67
 68    val = get(req, res)
 69    method = Array.isArray(val)
 70      ? val[0]
 71      : val
 72
 73    // replace
 74    if (method !== undefined && supports(method)) {
 75      req.method = method.toUpperCase()
 76      debug('override %s as %s', req.originalMethod, req.method)
 77    }
 78
 79    next()
 80  }
 81}
 82
 83/**
 84 * Create a getter for the given string.
 85 */
 86
 87function createGetter (str) {
 88  if (str.substr(0, 2).toUpperCase() === 'X-') {
 89    // header getter
 90    return createHeaderGetter(str)
 91  }
 92
 93  return createQueryGetter(str)
 94}
 95
 96/**
 97 * Create a getter for the given query key name.
 98 */
 99
100function createQueryGetter (key) {
101  return function (req, res) {
102    var url = parseurl(req)
103    var query = querystring.parse(url.query || '')
104    return query[key]
105  }
106}
107
108/**
109 * Create a getter for the given header name.
110 */
111
112function createHeaderGetter (str) {
113  var header = str.toLowerCase()
114
115  return function (req, res) {
116    // set appropriate Vary header
117    vary(res, str)
118
119    // multiple headers get joined with comma by node.js core
120    return (req.headers[header] || '').split(/ *, */)
121  }
122}
123
124/**
125 * Check if node supports `method`.
126 */
127
128function supports (method) {
129  return method &&
130    typeof method === 'string' &&
131    methods.indexOf(method.toLowerCase()) !== -1
132}