Crc32ValidatingParser.php 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. <?php
  2. namespace Aws\Api\Parser;
  3. use Aws\Api\StructureShape;
  4. use Aws\CommandInterface;
  5. use Aws\Exception\AwsException;
  6. use Psr\Http\Message\ResponseInterface;
  7. use Psr\Http\Message\StreamInterface;
  8. use GuzzleHttp\Psr7;
  9. /**
  10. * @internal Decorates a parser and validates the x-amz-crc32 header.
  11. */
  12. class Crc32ValidatingParser extends AbstractParser
  13. {
  14. /**
  15. * @param callable $parser Parser to wrap.
  16. */
  17. public function __construct(callable $parser)
  18. {
  19. $this->parser = $parser;
  20. }
  21. public function __invoke(
  22. CommandInterface $command,
  23. ResponseInterface $response
  24. ) {
  25. if ($expected = $response->getHeaderLine('x-amz-crc32')) {
  26. $hash = hexdec(Psr7\Utils::hash($response->getBody(), 'crc32b'));
  27. if ($expected != $hash) {
  28. throw new AwsException(
  29. "crc32 mismatch. Expected {$expected}, found {$hash}.",
  30. $command,
  31. [
  32. 'code' => 'ClientChecksumMismatch',
  33. 'connection_error' => true,
  34. 'response' => $response
  35. ]
  36. );
  37. }
  38. }
  39. $fn = $this->parser;
  40. return $fn($command, $response);
  41. }
  42. public function parseMemberFromStream(
  43. StreamInterface $stream,
  44. StructureShape $member,
  45. $response
  46. ) {
  47. return $this->parser->parseMemberFromStream($stream, $member, $response);
  48. }
  49. }