Skip to content

Commit

Permalink
add HTTP method override middleware #2040
Browse files Browse the repository at this point in the history
  • Loading branch information
danopz committed Nov 4, 2017
1 parent 6e1d776 commit 8f3747f
Show file tree
Hide file tree
Showing 2 changed files with 171 additions and 0 deletions.
60 changes: 60 additions & 0 deletions Slim/Middleware/MethodOverrideMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @link https://github.com/slimphp/Slim
* @copyright Copyright (c) 2011-2017 Josh Lockhart
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
namespace Slim\Middleware;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

/**
* Override HTTP Request method by given body param or custom header
*/
class MethodOverrideMiddleware
{
/**
* Invoke
*
* @param ServerRequestInterface $request PSR7 server request
* @param ResponseInterface $response PSR7 response
* @param callable $next Middleware callable
* @return ResponseInterface PSR7 response
*/
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next)
{
$method = $this->getOverrideMethod($request);

return $next($request->withMethod($method), $response);
}

/**
* @param ServerRequestInterface $request
* @return string
*/
protected function getOverrideMethod(ServerRequestInterface $request)
{
$method = $request->getHeaderLine('X-Http-Method-Override');

if (!$method && strtoupper($request->getMethod()) == 'POST') {
$body = $request->getParsedBody();

if (!empty($body['_METHOD'])) {
$method = $body['_METHOD'];
}

if ($request->getBody()->eof()) {
$request->getBody()->rewind();
}
}

if (!$method) {
$method = $request->getMethod();
}

return $method;
}
}
111 changes: 111 additions & 0 deletions tests/Middleware/MethodOverrideMiddlewareTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @link https://github.com/slimphp/Slim
* @copyright Copyright (c) 2011-2017 Josh Lockhart
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
namespace Slim\Tests\Middleware;

use PHPUnit\Framework\TestCase;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Http\Headers;
use Slim\Http\Request;
use Slim\Http\RequestBody;
use Slim\Http\Response;
use Slim\Http\Uri;
use Slim\Middleware\MethodOverrideMiddleware;

/**
* @covers \Slim\Middleware\MethodOverrideMiddleware
*/
class MethodOverrideMiddlewareTest extends TestCase
{
public function testHeader()
{
$mw = new MethodOverrideMiddleware();

$uri = new Uri('http', 'example.com');
$headers = new Headers([
'HTTP_X_HTTP_METHOD_OVERRIDE' => 'PUT',
]);
$request = new Request('GET', $uri, $headers, [], [], new RequestBody());
$response = new Response();

$next = function (ServerRequestInterface $req, ResponseInterface $res) {
$this->assertEquals('PUT', $req->getMethod());

return $res;
};
\Closure::bind($next, $this);

$mw($request, $response, $next);
}

public function testBodyParam()
{
$mw = new MethodOverrideMiddleware();

$uri = new Uri('http', 'example.com');
$body = new RequestBody();
$body->write('_METHOD=PUT');
$headers = new Headers([
'Content-Type' => 'application/x-www-form-urlencoded',
]);
$request = new Request('POST', $uri, $headers, [], [], $body);
$response = new Response();

$next = function (ServerRequestInterface $req, ResponseInterface $res) {
$this->assertEquals('PUT', $req->getMethod());

return $res;
};
\Closure::bind($next, $this);

$mw($request, $response, $next);
}

public function testHeaderPreferred()
{
$mw = new MethodOverrideMiddleware();

$uri = new Uri('http', 'example.com');
$body = new RequestBody();
$body->write('_METHOD=PUT');
$headers = new Headers([
'Content-Type' => 'application/x-www-form-urlencoded',
'HTTP_X_HTTP_METHOD_OVERRIDE' => 'DELETE',
]);
$request = new Request('POST', $uri, $headers, [], [], $body);
$response = new Response();

$next = function (ServerRequestInterface $req, ResponseInterface $res) {
$this->assertEquals('DELETE', $req->getMethod());

return $res;
};
\Closure::bind($next, $this);

$mw($request, $response, $next);
}

public function testNoOverride()
{
$mw = new MethodOverrideMiddleware();

$uri = new Uri('http', 'example.com');
$request = new Request('POST', $uri, new Headers(), [], [], new RequestBody());
$response = new Response();

$next = function (ServerRequestInterface $req, ResponseInterface $res) {
$this->assertEquals('POST', $req->getMethod());

return $res;
};
\Closure::bind($next, $this);

$mw($request, $response, $next);
}
}

0 comments on commit 8f3747f

Please sign in to comment.