Commit a4fc59cc authored by Richard Weinhold's avatar Richard Weinhold 🎩

fixes hash calculation for file-content in flysystem storage

parent 5e2f2897
Pipeline #5413 passed with stages
in 10 seconds
......@@ -16,6 +16,11 @@ class Stream
*/
protected $handle;
/**
* @var bool
*/
protected $closeOnFree = false;
/**
* @param resource $handle
*/
......@@ -28,6 +33,53 @@ class Stream
$this->handle = $handle;
}
/**
*/
public function __destruct()
{
if ($this->closeOnFree && is_resource($this->handle)) {
\fclose($this->handle);
}
}
/**
* @throws RuntimeException
* @return self
*/
public function rewind(): self
{
if (\fseek($this->handle, 0) !== 0) {
throw new RuntimeException('error while rewinding file', 500);
}
return $this;
}
/**
* auto-close stream on destruction
* @param bool $activate
* @return self
*/
public function closeOnFree(bool $activate = true): self
{
$this->closeOnFree = $activate;
return $this;
}
/**
* [hash description]
* @param string $algo [description]
* @return string [description]
*/
public function hash(string $algo = 'sha256'): string
{
$this->rewind();
$hc = \hash_init($algo);
\hash_update_stream($hc, $this->handle);
return \hash_final($hc);
}
/**
* @param int|null $offset
* @param int|null $length
......@@ -37,9 +89,7 @@ class Stream
public function read(?int $offset = null, ?int $length = null): string
{
if (($offset === null || $length === null)) {
if (\fseek($this->handle, 0) !== 0) {
throw new RuntimeException('error while rewinding file', 500);
}
$this->rewind();
if (0 < $filesize = \fstat($this->handle)['size'] ?? 0) {
if (false !== $buffer = \fread($this->handle, $filesize)) {
......@@ -73,9 +123,7 @@ class Stream
public function send(?int $offset = null, ?int $length = null, int $bufferSize = 1024): void
{
if ($offset === null || $length === null) {
if (\fseek($this->handle, 0) !== 0) {
throw new RuntimeException('error while rewinding file', 500);
}
$this->rewind();
if (\fpassthru($this->handle) !== false) {
\flush();
......
......@@ -292,9 +292,9 @@ class Flysystem extends Storage
}
switch ($mode) {
case Hash::CONTENT: return hash($algo, $this->readFile(), false);
case Hash::CONTENT: return (new Stream($this->getStream()))->closeOnFree()->hash($algo);
case Hash::FILENAME: return hash($algo, $this->path, false);
default: throw new UnsupportedException('file-hashes are not supported by the default flysystem adapters', 500);
default: throw new UnsupportedException('filepath-hashes are not supported by flysystem adapters', 500);
}
}
......
......@@ -45,6 +45,8 @@ class FlysystemTest extends TestCase
'timestamp' => $cmpFile->getTime(),
'size' => $cmpFile->getSize(),
], $file->storage()->getMetadata());
$this->assertSame($cmpFile->getHash(), $file->getHash());
}
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment