Skip to content

Commit

Permalink
Merge branch 'danopz-4.x' into 4.x
Browse files Browse the repository at this point in the history
Closes #2329
  • Loading branch information
akrabat committed Dec 23, 2017
2 parents cc62721 + e5ee18f commit 1306570
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

### Added

- [#2329](https://github.com/slimphp/Slim/pull/2329) Added Middleware\MethodOverrideMiddleware
- [#2288](https://github.com/slimphp/Slim/pull/2288) Separate routing from dispatching
- [#2254](https://github.com/slimphp/Slim/pull/2254) Added Middleware\ContentLengthMiddleware
- [#2166](https://github.com/slimphp/Slim/pull/2166) Added Middleware\OutputBufferingMiddleware
Expand Down
47 changes: 47 additions & 0 deletions Slim/Middleware/MethodOverrideMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?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)
{
$methodHeader = $request->getHeaderLine('X-Http-Method-Override');

if ($methodHeader) {
$request = $request->withMethod($methodHeader);
} elseif (strtoupper($request->getMethod()) == 'POST') {
$body = $request->getParsedBody();

if (!empty($body['_METHOD'])) {
$request = $request->withMethod($body['_METHOD']);
}

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

return $next($request, $response);
}
}
2 changes: 2 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# How to upgrade

* [2329] - If you were overriding the HTTP method using either the custom header or the body param, you need to add the `Middleware\MethodOverrideMiddleware` middleware to be able to override the method like before.
* [2288] - If you were using `determineRouteBeforeAppMiddleware`, you need to add the `Middleware\RoutingMiddleware` middleware to your application just before your call `run()` to maintain the previous behaviour.
* [2254] - You need to add the `Middleware\ContentLengthMiddleware` middleware if you want Slim to add the Content-Length header this automatically.
* [2290] - Slim no longer has a Container so you need to supply your own. As a
Expand All @@ -13,6 +14,7 @@
* [2098] - You need to add the App's router to the container for a straight upgrade. If you've created your own router factory in the container though, then you need to set it into the $app.
* [2102] - You must inject custom route invocation strategy with `$app->getRouter()->setDefaultInvocationStrategy($myStrategy)`

[2329]: https://github.com/slimphp/Slim/pull/2329
[2290]: https://github.com/slimphp/Slim/pull/2290
[2288]: https://github.com/slimphp/Slim/pull/2288
[2254]: https://github.com/slimphp/Slim/pull/2254
Expand Down
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 1306570

Please sign in to comment.