diff --git a/.travis.yml b/.travis.yml index a0931eb..30f4ed9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,19 +1,18 @@ language: php -matrix: - fast_finish: true - include: - - php: 5.5 - - php: 5.6 - - php: 7 - - php: hhvm - allow_failures: - - php: 7 - - php: hhvm +php: + - 5.5 + - 5.6 + - 7.0 + - 7.1 + - hhvm -install: - - travis_retry composer install --no-interaction --ignore-platform-reqs --prefer-source - - composer info -i +env: + - COMPOSER_FLAGS=--prefer-lowest + - COMPOSER_FLAGS= + +before_script: + - composer update --no-interaction --no-suggest --prefer-dist $COMPOSER_FLAGS script: - - ./vendor/bin/phpunit + - vendor/bin/phpunit diff --git a/README.md b/README.md index c6c0e4a..c5d2f99 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,13 @@ # log-http-messages middleware [![Build Status](https://travis-ci.org/php-middleware/log-http-messages.svg)](https://travis-ci.org/php-middleware/log-http-messages) -Middleware for log PSR-7 HTTP messages using PSR-3 logger +PSR-15 middleware for log PSR-7 HTTP messages using PSR-3 logger This middleware provide framework-agnostic possibility to log request and response messages to PSR-3 logger. +Support double and single (PSR-15) pass middleware. ## Installation -```json -{ - "require": { - "php-middleware/log-http-messages": "^2.0.0" - } -} +``` +composer require php-middleware/log-http-messages ``` To log http messages you need pass into `LogRequestMiddleware` implementation of `PhpMiddleware\LogHttpMessages\Formatter\HttpMessagesFormatter`, diff --git a/composer.json b/composer.json index dc25ecd..4b42dc4 100644 --- a/composer.json +++ b/composer.json @@ -1,12 +1,13 @@ { "name": "php-middleware/log-http-messages", - "description": "Request and response middleware logger with PSR-7 and PSR-3", + "description": "PSR-15 middleware for log PSR-7 HTTP messages using PSR-3 logger", "type": "library", "keywords": [ "debug", "middleware", "psr", "psr-7", + "psr-15", "log", "logger", "psr-3" @@ -15,10 +16,11 @@ "php": ">=5.5", "psr/log": "^1.0.0", "psr/http-message": "^1.0", - "zendframework/zend-diactoros": "^1.1.3" + "zendframework/zend-diactoros": "^1.1.3", + "http-interop/http-middleware": "^0.4.1" }, "require-dev": { - "phpunit/phpunit": "^4.8.6" + "phpunit/phpunit": "^4.8" }, "autoload": { "psr-4": { diff --git a/src/LogMiddleware.php b/src/LogMiddleware.php index c1d86e4..5a81f15 100644 --- a/src/LogMiddleware.php +++ b/src/LogMiddleware.php @@ -2,13 +2,16 @@ namespace PhpMiddleware\LogHttpMessages; +use Interop\Http\ServerMiddleware\DelegateInterface; +use Interop\Http\ServerMiddleware\MiddlewareInterface; use PhpMiddleware\LogHttpMessages\Formatter\HttpMessagesFormatter; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as ServerRequest; use Psr\Log\LoggerInterface as Logger; use Psr\Log\LogLevel; +use UnexpectedValueException; -class LogMiddleware +class LogMiddleware implements MiddlewareInterface { /** * @var Logger @@ -26,7 +29,8 @@ class LogMiddleware protected $formatter; /** - * @param LoggerInterface $logger + * @param HttpMessagesFormatter $formatter + * @param Logger $logger * @param int $level */ public function __construct(HttpMessagesFormatter $formatter, Logger $logger, $level = LogLevel::INFO) @@ -41,20 +45,47 @@ public function __construct(HttpMessagesFormatter $formatter, Logger $logger, $l * @param Response $response * @param callable $next * - * @return ResponseInterface + * @return Response */ public function __invoke(ServerRequest $request, Response $response, callable $next) { $outResponse = $next($request, $response); - $messages = $this->formatter->format($request, $outResponse); + $this->logMessages($request, $outResponse); + + return $outResponse; + } + + /** + * @param ServerRequest $request + * @param DelegateInterface $delegate + * + * @return Response + */ + public function process(ServerRequest $request, DelegateInterface $delegate) + { + $response = $delegate->process($request); + + $this->logMessages($request, $response); + + return $response; + } + + /** + * @param ServerRequest $request + * @param Response $response + * + * @throws UnexpectedValueException + */ + private function logMessages(ServerRequest $request, Response $response) + { + $messages = $this->formatter->format($request, $response); if (!is_string($messages)) { - throw new \UnexpectedValueException(sprintf('%s must return string', HttpMessagesFormatter::class)); + throw new UnexpectedValueException(sprintf('%s must return string', HttpMessagesFormatter::class)); } $this->logger->log($this->level, $messages); - - return $outResponse; } + } diff --git a/test/Formatter/BothFormatterTest.php b/test/Formatter/BothFormatterTest.php index d112bb3..586c9d3 100644 --- a/test/Formatter/BothFormatterTest.php +++ b/test/Formatter/BothFormatterTest.php @@ -28,6 +28,6 @@ public function testFormatter() $result = $this->formatter->format($request, $response); - $this->assertSame("Request: GET /php-middleware/log-http-messages HTTP/1.1\r\nAccept: text/html; Response HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/html", $result); + $this->assertContains('; Response ', $result); } } \ No newline at end of file diff --git a/test/LogMiddlewareTest.php b/test/LogMiddlewareTest.php index f831734..ecc4b1e 100644 --- a/test/LogMiddlewareTest.php +++ b/test/LogMiddlewareTest.php @@ -2,6 +2,7 @@ namespace PhpMiddlewareTest\LogHttpMessages; +use Interop\Http\ServerMiddleware\DelegateInterface; use PhpMiddleware\LogHttpMessages\Formatter\HttpMessagesFormatter; use PhpMiddleware\LogHttpMessages\LogMiddleware; use PHPUnit_Framework_TestCase; @@ -9,16 +10,19 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; +use UnexpectedValueException; class LogMiddlewareTest extends PHPUnit_Framework_TestCase { - protected $middleware; + public $middleware; protected $formatter; protected $logger; protected $request; protected $response; protected $next; protected $level; + protected $delegate; + protected $nextResponse; protected function setUp() { @@ -28,6 +32,8 @@ protected function setUp() $this->next = function () { return $this->nextResponse; }; + $this->delegate = $this->getMock(DelegateInterface::class); + $this->delegate->method('process')->willReturn($this->nextResponse); $this->formatter = $this->getMock(HttpMessagesFormatter::class); $this->logger = $this->getMock(LoggerInterface::class); @@ -36,28 +42,48 @@ protected function setUp() $this->middleware = new LogMiddleware($this->formatter, $this->logger, $this->level); } - public function testLogMessage() + /** + * @dataProvider middlewareProvider + */ + public function testLogFormattedMessages($middlewareExecutor) { - $this->formatter->expects($this->once())->method('format')->with($this->request, $this->nextResponse)->willReturn('boo'); - $this->logger->expects($this->once())->method('log')->with($this->level, 'boo'); - - $response = $this->executeMiddleware(); + $this->formatter->method('format')->with($this->request, $this->nextResponse)->willReturn('formattedMessages'); + $this->logger->expects($this->once())->method('log')->with($this->level, 'formattedMessages'); - $this->assertSame($this->nextResponse, $response); + $middlewareExecutor($this); } /** - * @expectedException \UnexpectedValueException + * @dataProvider middlewareProvider */ - public function testTryToLogNullMessage() + public function testTryToLogNullMessage($middlewareExecutor) { - $this->formatter->expects($this->once())->method('format')->willReturn(null); + $this->formatter->method('format')->willReturn(null); + + $this->setExpectedException(UnexpectedValueException::class); + + $middlewareExecutor($this); + } - $this->executeMiddleware(); + public function middlewareProvider() + { + return [ + 'double pass' => [function ($test) { + return $test->executeDoublePassMiddleware(); + }], + 'single pass' => [function ($test) { + return $test->executeSinglePassMiddleware(); + }], + ]; } - public function executeMiddleware() + protected function executeDoublePassMiddleware() { return call_user_func($this->middleware, $this->request, $this->response, $this->next); } -} \ No newline at end of file + + protected function executeSinglePassMiddleware() + { + return $this->middleware->process($this->request, $this->delegate); + } +}