From ba2a2151224609555f3bf905d5b0e9efece89a41 Mon Sep 17 00:00:00 2001 From: Konstantin Babushkin Date: Sat, 10 Feb 2024 10:53:23 +0100 Subject: [PATCH] fix #403 --- src/Common/Error/Builder.php | 11 +++- tests/unit/Common/Error/BuilderTest.php | 81 +++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/src/Common/Error/Builder.php b/src/Common/Error/Builder.php index 7de83710..b4492457 100644 --- a/src/Common/Error/Builder.php +++ b/src/Common/Error/Builder.php @@ -19,6 +19,8 @@ */ class Builder { + public const MAX_BODY_LENGTH = 5000; + /** * The default domain to use for further link documentation. * @@ -96,8 +98,13 @@ public function str(MessageInterface $message, int $verbosity = 0): string return $msg; } - if (ini_get('memory_limit') < 0 || $message->getBody()->getSize() < ini_get('memory_limit')) { - $msg .= "\r\n\r\n".$message->getBody(); + $contentType = strtolower($message->getHeaderLine('content-type')); + if (strpos($contentType, 'application/json') !== false) { + $body = $message->getBody()->read(self::MAX_BODY_LENGTH); + $msg .= "\r\n\r\n".$body; + if ($message->getBody()->read(1) !== '') { + $msg .= '...'; + } } return trim($msg); diff --git a/tests/unit/Common/Error/BuilderTest.php b/tests/unit/Common/Error/BuilderTest.php index 51ce95fb..6f0abc7b 100644 --- a/tests/unit/Common/Error/BuilderTest.php +++ b/tests/unit/Common/Error/BuilderTest.php @@ -4,6 +4,8 @@ use GuzzleHttp\ClientInterface; use GuzzleHttp\Exception\ClientException; +use GuzzleHttp\Psr7\NoSeekStream; +use GuzzleHttp\Psr7\PumpStream; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; use GuzzleHttp\Psr7\Utils; @@ -75,6 +77,85 @@ public function verbosityProvider(): array ]; } + public function test_it_outputs_body_for_json() + { + $value = 'foobar'; + + $request = new Request( + 'POST', + '/servers', + ['Content-Type' => 'application/json'], + json_encode(['foo' => $value]) + ); + + $str = $this->builder->str($request, 2); + $this->assertStringContainsString($value, $str); + } + + public function test_it_skips_body_for_low_verbosity() + { + $value = 'foobar'; + + $request = new Request( + 'POST', + '/servers', + ['Content-Type' => 'application/json'], + json_encode(['foo' => $value]) + ); + + $str = $this->builder->str($request, 1); + $this->assertStringNotContainsString($value, $str); + } + + public function test_it_cuts_big_body_for_json() + { + $value = str_repeat('A', Builder::MAX_BODY_LENGTH); + + $request = new Request( + 'POST', + '/servers', + ['Content-Type' => 'application/json'], + json_encode(['foo' => $value]) + ); + + $str = $this->builder->str($request, 2); + $this->assertStringNotContainsString($value, $str); + $this->assertStringContainsString('AAAAAA...', $str); + } + + public function test_it_did_not_read_full_body_for_json() + { + $value = str_repeat('A', Builder::MAX_BODY_LENGTH + 1); + + $request = new Request( + 'POST', + '/servers', + ['Content-Type' => 'application/json'], + new PumpStream(function ($size) { + return str_repeat('A', $size); + }) + ); + + $str = $this->builder->str($request, 2); + $this->assertStringNotContainsString($value, $str); + $this->assertStringContainsString('AAAAAA...', $str); + } + + public function test_it_skips_body_for_binary() + { + $value = 'foobar'; + + $request = new Request( + 'POST', + '/servers', + ['Content-Type' => 'binary/octet-stream'], + $value + ); + + $str = $this->builder->str($request, 2); + $this->assertStringNotContainsString($value, $str); + } + public function test_it_builds_user_input_errors() { $expected = 'A well-formed string';