/** * Update a command with the content and tree hash headers, as needed. * * @param PreparedEvent $event Event emitted. * * @throws \RuntimeException if the body is not seekable. */ public function onPrepared(PreparedEvent $event) { $command = $event->getCommand(); $name = $command->getName(); // Determine if there is a need to calculate any hashes. $needsHashes = ($name === 'UploadArchive' || $name === 'UploadPart') && (!$command['checksum'] || !$command['ContentSHA256']); if ($needsHashes) { $body = $event->getRequest()->getBody(); if (!$body->isSeekable()) { throw new CouldNotCreateChecksumException('sha256'); } // Add a tree hash if not provided. if (!$command['checksum']) { $body = new HashingStream($body, new TreeHash(), function ($result) use($command, $event) { $event->getRequest()->setHeader('x-amz-sha256-tree-hash', bin2hex($result)); }); } // Add a linear content hash if not provided. if (!$command['ContentSHA256']) { $body = new HashingStream($body, new PhpHash('sha256'), function ($result) use($command) { $command['ContentSHA256'] = bin2hex($result); }); } // Read the stream in order to calculate the hashes. while (!$body->eof()) { $body->read(1048576); } $body->seek(0); } // Set the content hash header if there is a value to set. if ($hash = $command['ContentSHA256']) { $event->getRequest()->addHeader('x-amz-content-sha256', $hash); } }
/** * @param StreamInterface $stream Stream that is validated. * @param HashInterface $hash Hash used to calculate the hash. * @param string $expected The expected hash result. * @param callable $onMismatch Optional function to invoke when there * is a mismatch between the calculated hash and the expected hash. * The callback is called with the resulting hash and the expected hash. * This callback can be used to throw specific exceptions. */ public function __construct(StreamInterface $stream, HashInterface $hash, $expected, $onMismatch = null) { $this->mismatchCallback = $onMismatch; $this->expected = $expected; $that = $this; parent::__construct($stream, $hash, function ($result) use($that) { if ($that->expected !== $result) { $that->mismatch($result); } }); }