Skip to content
This repository has been archived by the owner on Jan 21, 2020. It is now read-only.

Commit

Permalink
Adds a ContentLengthMiddleware for auto-injecting the Content-Length …
Browse files Browse the repository at this point in the history
…response header

This feature is pulled from zend-diactoros'
`SapiEmitterTrait::injectContentLength() method; a future version will
omit that functionality, in favor of using this new middleware.

This middleware will inject a `Content-Length` response header based on
the body size if:

- no `Content-Length` header is already present AND
- the body size is non-null

Otherwise, it returns the response verbatim.
  • Loading branch information
weierophinney committed Sep 11, 2017
1 parent 788ac67 commit 330e9f1
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 0 deletions.
40 changes: 40 additions & 0 deletions src/ContentLengthMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php
/**
* @see https://github.com/zendframework/zend-expressive-helpers for the canonical source repository
* @copyright Copyright (c) 2017 Zend Technologies USA Inc. (http://www.zend.com)
* @license https://github.com/zendframework/zend-expressive-helpers/blob/master/LICENSE.md New BSD License
*/

namespace Zend\Expressive\Helper;

use Interop\Http\ServerMiddleware\DelegateInterface;
use Interop\Http\ServerMiddleware\MiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface;

/**
* Middleware to inject a Content-Length response header.
*
* If the response returned by a delegate does not contain a Content-Length
* header, and the body size is non-null, this middleware will return a new
* response that contains a Content-Length header based on the body size.
*/
class ContentLengthMiddleware implements MiddlewareInterface
{
/**
* {@inheritDoc}
*/
public function process(ServerRequestInterface $request, DelegateInterface $delegate)
{
$response = $delegate->process($request);
if ($response->hasHeader('Content-Length')) {
return $response;
}

$body = $response->getBody();
if (null === $body->getSize()) {
return $response;
}

return $response->withHeader('Content-Length', (string) $body->getSize());
}
}
59 changes: 59 additions & 0 deletions test/ContentLengthMiddlewareTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
/**
* @see https://github.com/zendframework/zend-expressive-helpers for the canonical source repository
* @copyright Copyright (c) 2017 Zend Technologies USA Inc. (http://www.zend.com)
* @license https://github.com/zendframework/zend-expressive-helpers/blob/master/LICENSE.md New BSD License
*/

namespace ZendTest\Expressive\Helper;

use Interop\Http\ServerMiddleware\DelegateInterface;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface;
use Zend\Expressive\Helper\ContentLengthMiddleware;

class ContentLengthMiddlewareTest extends TestCase
{
public function setUp()
{
$this->response = $response = $this->prophesize(ResponseInterface::class);
$this->request = $request = $this->prophesize(ServerRequestInterface::class)->reveal();
$this->stream = $this->prophesize(StreamInterface::class);

$delegate = $this->prophesize(DelegateInterface::class);
$delegate->process($request)->will([$response, 'reveal']);
$this->delegate = $delegate->reveal();

$this->middleware = new ContentLengthMiddleware();
}

public function testReturnsResponseVerbatimIfContentLengthHeaderPresent()
{
$this->response->hasHeader('Content-Length')->willReturn(true);
$response = $this->middleware->process($this->request, $this->delegate);
$this->assertSame($this->response->reveal(), $response);
}

public function testReturnsResponseVerbatimIfContentLengthHeaderNotPresentAndBodySizeIsNull()
{
$this->stream->getSize()->willReturn(null);
$this->response->hasHeader('Content-Length')->willReturn(false);
$this->response->getBody()->will([$this->stream, 'reveal']);

$response = $this->middleware->process($this->request, $this->delegate);
$this->assertSame($this->response->reveal(), $response);
}

public function testReturnsResponseWithContentLengthHeaderBasedOnBodySize()
{
$this->stream->getSize()->willReturn(42);
$this->response->hasHeader('Content-Length')->willReturn(false);
$this->response->getBody()->will([$this->stream, 'reveal']);
$this->response->withHeader('Content-Length', '42')->will([$this->response, 'reveal']);

$response = $this->middleware->process($this->request, $this->delegate);
$this->assertSame($this->response->reveal(), $response);
}
}

0 comments on commit 330e9f1

Please sign in to comment.