Skip to content

Commit

Permalink
enchance error builder: output body only for json, limit body to 5 Kb (
Browse files Browse the repository at this point in the history
…#405)

fixes #403
supersedes #404
  • Loading branch information
k0ka authored Feb 10, 2024
1 parent 8f2ba03 commit 38a6860
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 2 deletions.
11 changes: 9 additions & 2 deletions src/Common/Error/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
*/
class Builder
{
public const MAX_BODY_LENGTH = 5000;

/**
* The default domain to use for further link documentation.
*
Expand Down Expand Up @@ -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 (false !== strpos($contentType, 'application/json')) {
$body = $message->getBody()->read(self::MAX_BODY_LENGTH);
$msg .= "\r\n\r\n".$body;
if ('' !== $message->getBody()->read(1)) {
$msg .= '...';
}
}

return trim($msg);
Expand Down
3 changes: 3 additions & 0 deletions tests/sample/Compute/v2/ServerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,9 @@ public function testSuspend()
$server->waitUntil('SUSPENDED');
$this->assertEquals('SUSPENDED', $server->status);

// wait for the server to be fully suspended
sleep(5);

return $server;
}

Expand Down
81 changes: 81 additions & 0 deletions tests/unit/Common/Error/BuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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';
Expand Down

0 comments on commit 38a6860

Please sign in to comment.