diff --git a/src/AccessLogHandler.php b/src/AccessLogHandler.php index 672594a..d0a5c4c 100644 --- a/src/AccessLogHandler.php +++ b/src/AccessLogHandler.php @@ -75,10 +75,18 @@ private function logWhenClosed(ServerRequestInterface $request, ResponseInterfac */ private function log(ServerRequestInterface $request, ResponseInterface $response, int $responseSize, float $time): void { + $method = $request->getMethod(); + $status = $response->getStatusCode(); + + // HEAD requests and `204 No Content` and `304 Not Modified` always use an empty response body + if ($method === 'HEAD' || $status === 204 || $status === 304) { + $responseSize = 0; + } + $this->sapi->log( ($request->getServerParams()['REMOTE_ADDR'] ?? '-') . ' ' . - '"' . $this->escape($request->getMethod()) . ' ' . $this->escape($request->getRequestTarget()) . ' HTTP/' . $request->getProtocolVersion() . '" ' . - $response->getStatusCode() . ' ' . $responseSize . ' ' . sprintf('%.3F', $time < 0 ? 0 : $time) + '"' . $this->escape($method) . ' ' . $this->escape($request->getRequestTarget()) . ' HTTP/' . $request->getProtocolVersion() . '" ' . + $status . ' ' . $responseSize . ' ' . sprintf('%.3F', $time < 0 ? 0 : $time) ); } diff --git a/tests/AccessLogHandlerTest.php b/tests/AccessLogHandlerTest.php index b53c6d2..c4d36fd 100644 --- a/tests/AccessLogHandlerTest.php +++ b/tests/AccessLogHandlerTest.php @@ -48,6 +48,42 @@ public function testInvokePrintsRequestWithEscapedSpecialCharactersInRequestMeth $handler($request, function () use ($response) { return $response; }); } + public function testInvokePrintsRequestLogForHeadRequestWithResponseSizeAsZero() + { + $handler = new AccessLogHandler(); + + $request = new ServerRequest('HEAD', 'http://localhost:8080/users', [], '', '1.1', ['REMOTE_ADDR' => '127.0.0.1']); + $response = new Response(200, [], "HEAD\n"); + + // 2021-01-29 12:22:01.717 127.0.0.1 "HEAD /users HTTP/1.1" 200 0 0.000\n + $this->expectOutputRegex("/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} 127\.0\.0\.1 \"HEAD \/users HTTP\/1\.1\" 200 0 0\.0\d\d" . PHP_EOL . "$/"); + $handler($request, function () use ($response) { return $response; }); + } + + public function testInvokePrintsRequestLogForNoContentResponseWithResponseSizeAsZero() + { + $handler = new AccessLogHandler(); + + $request = new ServerRequest('GET', 'http://localhost:8080/users', [], '', '1.1', ['REMOTE_ADDR' => '127.0.0.1']); + $response = new Response(204, [], "No Content\n"); + + // 2021-01-29 12:22:01.717 127.0.0.1 "GET /users HTTP/1.1" 204 0 0.000\n + $this->expectOutputRegex("/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} 127\.0\.0\.1 \"GET \/users HTTP\/1\.1\" 204 0 0\.0\d\d" . PHP_EOL . "$/"); + $handler($request, function () use ($response) { return $response; }); + } + + public function testInvokePrintsRequestLogForNotModifiedResponseWithResponseSizeAsZero() + { + $handler = new AccessLogHandler(); + + $request = new ServerRequest('GET', 'http://localhost:8080/users', [], '', '1.1', ['REMOTE_ADDR' => '127.0.0.1']); + $response = new Response(304, [], "Not Modified\n"); + + // 2021-01-29 12:22:01.717 127.0.0.1 "GET /users HTTP/1.1" 304 0 0.000\n + $this->expectOutputRegex("/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} 127\.0\.0\.1 \"GET \/users HTTP\/1\.1\" 304 0 0\.0\d\d" . PHP_EOL . "$/"); + $handler($request, function () use ($response) { return $response; }); + } + public function testInvokePrintsPlainProxyRequestLogWithCurrentDateAndTime() { $handler = new AccessLogHandler();