Skip to content

Commit

Permalink
Replace addContentLengthHeader with ContentLength Middleware
Browse files Browse the repository at this point in the history
This feature isn't needed in core and is better as optional middleware.
  • Loading branch information
akrabat committed Jun 29, 2017
1 parent 4556842 commit 3520c44
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 53 deletions.
13 changes: 0 additions & 13 deletions Slim/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ class App
'responseChunkSize' => 4096,
'determineRouteBeforeAppMiddleware' => false,
'displayErrorDetails' => false,
'addContentLengthHeader' => true,
'routerCacheFile' => false,
];

Expand Down Expand Up @@ -808,18 +807,6 @@ protected function finalize(ResponseInterface $response)
return $response->withoutHeader('Content-Type')->withoutHeader('Content-Length');
}

// Add Content-Length header if `addContentLengthHeader` setting is set
if ($this->getSetting('addContentLengthHeader') == true) {
if (ob_get_length() > 0) {
throw new \RuntimeException("Unexpected data in output buffer. " .
"Maybe you have characters before an opening <?php tag?");
}
$size = $response->getBody()->getSize();
if ($size !== null && !$response->hasHeader('Content-Length')) {
$response = $response->withHeader('Content-Length', (string) $size);
}
}

return $response;
}

Expand Down
1 change: 0 additions & 1 deletion Slim/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ class Container extends PimpleContainer implements ContainerInterface
'outputBuffering' => 'append',
'determineRouteBeforeAppMiddleware' => false,
'displayErrorDetails' => false,
'addContentLengthHeader' => true,
'routerCacheFile' => false,
];

Expand Down
30 changes: 30 additions & 0 deletions Slim/Middleware/ContentLength.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php
namespace Slim\Middleware;

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

class ContentLength
{
/**
* 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)
{
$response = $next($request, $response);

// Add Content-Length header if not already added
$size = $response->getBody()->getSize();
if ($size !== null && !$response->hasHeader('Content-Length')) {
$response = $response->withHeader('Content-Length', (string) $size);
}

return $response;
}
}
43 changes: 4 additions & 39 deletions tests/AppTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,14 @@ public function testAddSettings()
{
$app = new App();
$app->addSettings(['foo' => 'bar']);
$this->assertAttributeContains('foo', 'settings', $app);
$this->assertEquals('bar', $app->getSetting('foo', 'what'));
}

public function testAddSetting()
{
$app = new App();
$app->addSetting('foo', 'bar');
$this->assertAttributeContains('foo', 'settings', $app);
$this->assertEquals('bar', $app->getSetting('foo', 'what'));
}

/********************************************************************************
Expand Down Expand Up @@ -1953,11 +1953,11 @@ public function testFinalize()

$response = new Response();
$response->getBody()->write('foo');
$response = $response->withHeader('Content-Type', 'text/plain');

$response = $method->invoke(new App(), $response);

$this->assertTrue($response->hasHeader('Content-Length'));
$this->assertEquals('3', $response->getHeaderLine('Content-Length'));
$this->assertTrue($response->hasHeader('Content-Type'));
}

public function testFinalizeWithoutBody()
Expand Down Expand Up @@ -2027,41 +2027,6 @@ public function testCallingAnUncallableContainerKeyThrows()
$app->foo('bar');
}

public function testOmittingContentLength()
{
$method = new \ReflectionMethod('Slim\App', 'finalize');
$method->setAccessible(true);

$response = new Response();
$response->getBody()->write('foo');

$app = new App();
$app->addSetting('addContentLengthHeader', false);
$response = $method->invoke($app, $response);

$this->assertFalse($response->hasHeader('Content-Length'));
}

/**
* @expectedException \RuntimeException
* @expectedExceptionMessage Unexpected data in output buffer
*/
public function testForUnexpectedDataInOutputBuffer()
{
$this->expectOutputString('test'); // needed to avoid risky test warning
echo "test";
$method = new \ReflectionMethod('Slim\App', 'finalize');
$method->setAccessible(true);

$response = new Response();
$response->getBody()->write('foo');

$app = new App();
$container = $app->getContainer();
$container['settings']['addContentLengthHeader'] = true;
$response = $method->invoke($app, $response);
}

public function testUnsupportedMethodWithoutRoute()
{
$app = new App();
Expand Down
44 changes: 44 additions & 0 deletions tests/Middleware/ContentLengthTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?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/3.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\Body;
use Slim\Http\Headers;
use Slim\Http\Request;
use Slim\Http\Response;
use Slim\Http\Uri;
use Slim\Middleware\ContentLength;

class ContentLengthTest extends TestCase
{
public function testAddsContentLenght()
{
$mw = new ContentLength('append');

$uri = Uri::createFromString('https://example.com:443/foo/bar?abc=123');
$headers = new Headers();
$cookies = [];
$serverParams = [];
$body = new Body(fopen('php://temp', 'r+'));
$request = new Request('GET', $uri, $headers, $cookies, $serverParams, $body);
$response = new Response();

$next = function (ServerRequestInterface $req, ResponseInterface $res) {
$res->write('Body');
return $res;
};

$newResponse = $mw($request, $response, $next);

$this->assertEquals(4, $newResponse->getHeaderLine('Content-Length'));
}
}

0 comments on commit 3520c44

Please sign in to comment.