Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

koa-methodoverride

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

koa-methodoverride - npm Package Compare versions

Comparing version 0.3.1 to 0.4.0

136

index.js

@@ -0,1 +1,10 @@

/*!
* 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
*/

@@ -5,55 +14,120 @@ 'use strict';

/**
* Module dependences.
* Module dependences.
*/
var debug = require('debug')('method-override')
var methods = require('methods');
var METHOD_OVERRIDE_PARAM_KEY = '_method';
var HTTP_METHOD_OVERRIDE_HEADER = "X-HTTP-Method-Override";
var ALLOWED_METHODS = ['POST'];
/**
* Method Override:
* Method Override:
*
* Provides faux HTTP method support.
* Provides faux HTTP method support.
*
* Pass an optional `key` to use when checking for
* a method override, otherwise defaults to _\_method_.
* The original method is available via `req.originalMethod`.
* Pass an optional `getter` to use when checking for
* a method override.
*
* @param {String} key
* @return {Function}
* @api public
* 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 = function methodOverride(key) {
key = key || '_method';
module.exports = function methodOverride(getter, options){
options = options || {}
// get the getter fn
var get = typeof getter === 'function'
? getter
: createGetter(getter || HTTP_METHOD_OVERRIDE_HEADER)
// get allowed request methods to examine
var methods = options.methods === undefined
? ALLOWED_METHODS
: options.methods
return function *methodOverride(next) {
var method;
var request = this.request;
request.originalMethod = request.originalMethod || request.method;
var method
var val
var req = this.request
// this.request.body
var body = request.body;
if (body && typeof body === 'object' && key in body) {
method = body[key].toLowerCase();
delete body[key];
}
req.originalMethod = req.originalMethod || req.method
// check X-HTTP-Method-Override
var header = request.header;
if (header['x-http-method-override']) {
method = header['x-http-method-override'].toLowerCase();
// validate request is an allowed method
if (methods && methods.indexOf(req.originalMethod) === -1) {
return yield* next
}
val = get(req, this.response)
method = Array.isArray(val)
? val[0]
: val
// replace
if (supports(method)) request.method = method.toUpperCase();
if (method !== undefined && supports(method)) {
req.method = method.toUpperCase()
debug('override %s as %s', req.originalMethod, req.method)
}
yield *next;
};
};
yield* next
}
}
/**
* Check if node supports `method`.
* Create a getter for the given string.
*/
function createGetter(str) {
if (str.substr(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 function(req) {
return req.query[key]
}
}
/**
* Create a getter for the given header name.
*/
function createHeaderGetter(str) {
var header = str.toLowerCase()
return function(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 ~methods.indexOf(method);
return method
&& typeof method === 'string'
&& methods.indexOf(method.toLowerCase()) !== -1
}
{
"name": "koa-methodoverride",
"version": "0.3.1",
"version": "0.4.0",
"description": "HTTP method override for koa",

@@ -11,3 +11,5 @@ "main": "index.js",

"method",
"override"
"override",
"koa",
"middleware"
],

@@ -17,18 +19,13 @@ "author": "fundon <cfddream@gmail.com>",

"dependencies": {
"methods": "^0.1.0"
"debug": "*",
"methods": "*"
},
"devDependencies": {
"should": "^3.2.0-beta1",
"supertest": "^0.10.0",
"koa": "^0.5.2",
"mocha": "^1.18.2",
"co-body": "0.0.1"
"co-body": "*",
"koa": "*",
"mocha": "*",
"should": "*",
"supertest": "*"
},
"repository": {
"type": "git",
"url": "http://github.com/fundon/koa-method-override.git"
},
"bugs": {
"url": "https://github.com/fundon/koa-method-override/issues"
}
"repository": "koa-modules/koa-method-override"
}

@@ -1,4 +0,14 @@

# Method Override [![Build Status](https://travis-ci.org/fundon/koa-method-override.svg)](https://travis-ci.org/fundon/koa-method-override)
> HTTP method override for koa.
# koa-methodoverride
> HTTP method override middleware for koa.
Forked from [Express method-override][]
[![NPM version][npm-img]][npm-url]
[![Build status][travis-img]][travis-url]
[![Test coverage][coveralls-img]][coveralls-url]
[![License][license-img]][license-url]
[![Dependency status][david-img]][david-url]
### Install

@@ -10,33 +20,31 @@

### Usage
### Usage, more [Express method-override][]
```js
var app = require('koa')();
var parse = require('co-body');
var methodOverride = require('koa-methodoverride');
// First, must parse the body, use the `co-body` or the `koa-bodyparser` etc.
app.use(function *(next) {
try {
this.request.body = yield parse(this);
} catch (e) {
this.request.body = null;
}
yield next;
});
app.use(methodOverride());
var key = '_method'; // default
app.use(methodOverride(key));
app.listen(3000);
```
### Dependencies
* [co-body](https://github.com/visionmedia/co-body)
* Or other body parser
### License
MIT
### License
MIT
[Express method-override]: https://github.com/expressjs/method-override
[npm-img]: https://img.shields.io/npm/v/koa-methodoverride.svg?style=flat-square
[npm-url]: https://npmjs.org/package/koa-methodoverride
[travis-img]: https://img.shields.io/travis/koa-modules/koa-methodoverride.svg?style=flat-square
[travis-url]: https://travis-ci.org/koa-modules/koa-methodoverride
[coveralls-img]: https://img.shields.io/coveralls/koa-modules/koa-methodoverride.svg?style=flat-square
[coveralls-url]: https://coveralls.io/r/koa-modules/koa-methodoverride?branch=master
[license-img]: https://img.shields.io/badge/license-MIT-green.svg?style=flat-square
[license-url]: LICENSE
[david-img]: https://img.shields.io/david/koa-modules/koa-methodoverride.svg?style=flat-square
[david-url]: https://david-dm.org/koa-modules/koa-methodoverride
var koa = require('koa');
var parse = require('co-body');
var methodOverride = require('..')
var request = require('supertest');
var app = koa();
app.use(function *(next) {
try {
this.request.body = yield parse(this);
} catch (e) {
this.request.body = null;
}
yield next;
});
app.use(require('../')());
app.use(function *() {
this.body = this.request.method;
});
var request = require('supertest').agent(app.listen());
describe('methodOverride()', function(){
describe('methodOverride(getter)', function(){
it('should not touch the method by default', function(done){
request
var server = createServer()
request(server)
.get('/')

@@ -30,6 +14,6 @@ .expect('GET', done);

it('should be case in-sensitive', function(done){
request
it('should use X-HTTP-Method-Override by default', function(done){
var server = createServer()
request(server)
.post('/')
.set('Content-Type', 'application/x-www-form-urlencoded')
.set('X-HTTP-Method-Override', 'DELETE')

@@ -39,9 +23,161 @@ .expect('DELETE', done);

it('should ignore invalid methods', function(done){
request
.post('/')
.set('Content-Type', 'application/x-www-form-urlencoded')
.set('X-HTTP-Method-Override', 'POST')
.expect('POST', done);
describe('with query', function(){
it('should work missing query', function(done){
var server = createServer('_method')
request(server)
.post('/')
.set('Content-Type', 'application/json')
.expect('POST', done);
})
it('should be case in-sensitive', function(done){
var server = createServer('_method')
request(server)
.post('/?_method=DElete')
.set('Content-Type', 'application/json')
.expect('DELETE', done);
})
it('should handle key referencing array', function(done){
var server = createServer('_method')
var test = request(server).post('/')
test.request().path += '?_method=DELETE&_method=PUT' // supertest mangles query params
test.set('Content-Type', 'application/json')
test.expect('DELETE', done)
})
it('should only work with POST', function(done){
var server = createServer('_method')
request(server)
.delete('/?_method=PATCH')
.set('Content-Type', 'application/json')
.expect('DELETE', done)
})
})
describe('with header', function(){
var server
before(function () {
server = createServer('X-HTTP-Method-Override')
})
it('should work missing header', function(done){
request(server)
.post('/')
.set('Content-Type', 'application/json')
.expect('POST', done)
})
it('should be case in-sensitive', function(done){
request(server)
.post('/')
.set('Content-Type', 'application/json')
.set('X-HTTP-Method-Override', 'DELete')
.expect('DELETE', done)
})
it('should ignore invalid methods', function(done){
request(server)
.post('/')
.set('Content-Type', 'application/json')
.set('X-HTTP-Method-Override', 'BOGUS')
.expect('POST', done)
})
it('should handle multiple headers', function(done){
request(server)
.post('/')
.set('Content-Type', 'application/json')
.set('X-HTTP-Method-Override', 'DELETE, PUT')
.expect('DELETE', done)
})
it('should set Vary header', function(done){
request(server)
.post('/')
.set('Content-Type', 'application/json')
.set('X-HTTP-Method-Override', 'DELETE')
.expect('Vary', 'X-HTTP-Method-Override')
.expect('DELETE', done)
})
it('should set Vary header even with no override', function(done){
request(server)
.post('/')
.set('Content-Type', 'application/json')
.expect('Vary', 'X-HTTP-Method-Override')
.expect('POST', done)
})
})
describe('with function', function(){
var server
before(function () {
server = createServer(function(req){
return req.headers['x-method-override'] || 'PaTcH'
})
})
it('should work missing header', function(done){
request(server)
.post('/')
.set('Content-Type', 'application/json')
.expect('PATCH', done)
})
it('should be case in-sensitive', function(done){
request(server)
.post('/')
.set('Content-Type', 'application/json')
.set('X-Method-Override', 'DELete')
.expect('DELETE', done)
})
it('should ignore invalid methods', function(done){
request(server)
.post('/')
.set('Content-Type', 'application/json')
.set('X-Method-Override', 'BOGUS')
.expect('POST', done)
})
})
describe('given "options.methods"', function(){
it('should allow other methods', function(done){
var server = createServer('X-HTTP-Method-Override', { methods: ['POST', 'PATCH'] })
request(server)
.patch('/')
.set('Content-Type', 'application/json')
.set('X-HTTP-Method-Override', 'DELETE')
.expect('DELETE', done)
})
it('should allow all methods', function(done){
var server = createServer('X-HTTP-Method-Override', { methods: null })
request(server)
.patch('/')
.set('Content-Type', 'application/json')
.set('X-HTTP-Method-Override', 'DELETE')
.expect('DELETE', done)
})
it('should not call getter when method not allowed', function(done){
var server = createServer(function(req){ return 'DELETE' })
request(server)
.patch('/')
.set('Content-Type', 'application/json')
.expect('PATCH', done)
})
})
})
function createServer(getter, opts, fn) {
var app = koa();
fn && app.use(fn);
app.use(methodOverride(getter,opts));
app.use(function *() {
this.body = this.request.method;
});
return app.listen();
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc