Skip to content

Commit

Permalink
Chunking NG: SHA1 checksumming of whole file #11811
Browse files Browse the repository at this point in the history
  • Loading branch information
guruz committed Nov 8, 2016
1 parent 7822fb4 commit b15a74f
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 0 deletions.
4 changes: 4 additions & 0 deletions apps/dav/lib/Capabilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ public function getCapabilities() {
'dav' => [
'chunking' => '1.0',
]
,
'checksums' => [
'supportedTypes' => ['SHA1']
]
];
}
}
13 changes: 13 additions & 0 deletions apps/dav/lib/Connector/Sabre/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,18 @@ public function put($data) {
throw new Exception('Error while copying file to target location (copied bytes: ' . $count . ', expected filesize: ' . $expected . ' )');
}

if (substr( stream_get_meta_data($data)['uri'], 0, 11 ) == "assembly://") {
$assemblyStream = (stream_get_meta_data($data)['wrapper_data']);
$checksum = $assemblyStream->getChecksum();
// Only verify if it was actually computed and actually sent by client
if ($checksum && isset($_SERVER['HTTP_OC_CHECKSUM'])) {
if (strpos($_SERVER['HTTP_OC_CHECKSUM'], $checksum) === false) {
// We use "strpos" because client might send multiple checksums
throw new BadRequest('invalid checksum computed ' . $checksum . ' got ' . $_SERVER['HTTP_OC_CHECKSUM']);
}
}
}

// if content length is sent by client:
// double check if the file was fully received
// compare expected and actual size
Expand Down Expand Up @@ -216,6 +228,7 @@ public function put($data) {

$this->refreshInfo();

// FIXME: We're not doing verification yet here #11811
if (isset($request->server['HTTP_OC_CHECKSUM'])) {
$checksum = trim($request->server['HTTP_OC_CHECKSUM']);
$this->fileView->putFileInfo($this->path, ['checksum' => $checksum]);
Expand Down
24 changes: 24 additions & 0 deletions apps/dav/lib/Upload/AssemblyStream.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ public function stream_open($path, $mode, $options, &$opened_path) {
$start += $size;
$this->size = $start;
}

// Calculate the sha1 iteratively in stream_read
$this->hasher = hash_init("sha1");

return true;
}

Expand Down Expand Up @@ -137,6 +141,8 @@ public function stream_read($count) {

// update position
$this->pos += $read;

hash_update($this->hasher, $data);
return $data;
}

Expand Down Expand Up @@ -273,4 +279,22 @@ private function getStream(IFile $node) {
return fopen('data://text/plain,' . $data,'r');
}

protected $hasher = null;
protected $sha1 = null;
/**
* Call this only after having read the whole stream!
* @return string
*/
public function getChecksum() {
if ($this->hasher) {
$this->sha1 = hash_final($this->hasher);
$this->hasher = null;
}
if ($this->sha1) {
return "SHA1:" . $this->sha1; // Same format we use at other places
}

return null;
}

}
6 changes: 6 additions & 0 deletions apps/dav/tests/unit/Upload/AssemblyStreamTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ public function testGetContents($expected, $nodes) {
$content = stream_get_contents($stream);

$this->assertEquals($expected, $content);

$obj = (stream_get_meta_data($stream)['wrapper_data']);
$this->assertEquals($obj->getChecksum(), "SHA1:".sha1($expected));
}

/**
Expand All @@ -46,6 +49,9 @@ public function testGetContentsFread($expected, $nodes) {
}

$this->assertEquals($expected, $content);

$obj = (stream_get_meta_data($stream)['wrapper_data']);
$this->assertEquals($obj->getChecksum(), "SHA1:".sha1($expected));
}

function providesNodes() {
Expand Down

0 comments on commit b15a74f

Please sign in to comment.