public function testIsTreeHashAligned() { $mb = 1024 * 1024; $size = 10 * $mb; $this->assertTrue(TreeHashCheck::isTreeHashAligned($size, $mb * 0, $mb * 1 - 1)); $this->assertTrue(TreeHashCheck::isTreeHashAligned($size, $mb * 0, $mb * 2 - 1)); $this->assertFalse(TreeHashCheck::isTreeHashAligned($size, $mb * 0, $mb * 3 - 1)); $this->assertFalse(TreeHashCheck::isTreeHashAligned($size, $mb * 3, $mb * 5 - 1)); $this->assertFalse(TreeHashCheck::isTreeHashAligned($size, $mb * 4, $mb * 7 - 1)); $size = 10 * $mb; $this->assertTrue(TreeHashCheck::isTreeHashAligned($size, $mb * 6, $mb * 7 - 1)); $size = 6 * $mb + $mb / 2; $this->assertTrue(TreeHashCheck::isTreeHashAligned($size, $mb * 6, $size - 1)); $this->assertFalse(TreeHashCheck::isTreeHashAligned($size, $mb * 7, $mb * 8 - 1)); $size = 100 * $mb; $this->assertTrue(TreeHashCheck::isTreeHashAligned($size, 16777216, 33554431)); }
public function dumpOutput($res, $range = false, $httpRange = false) { if (($archive = $this->getArchive()) === false) { return $res->withStatus(500); } if (($f = fopen($file = $archive->getFile('data'), 'r')) === false) { return $res->withStatus(500); } if ($range) { list($from, $to) = $range; } else { $from = 0; $to = filesize($file) - 1; } if (fseek($f, $from) === -1) { return $res->withStatus(500); } $bufSize = 1024 * 1024 * 1; $readBytes = $to - $from + 1; $contentLength = $readBytes; $bytesWritten = 0; $data = ''; while ($readBytes > 0 && !feof($f)) { $buf = fread($f, max($bufSize, $readBytes)); if ($buf === false) { return $res->withStatus(500); } $readBytes -= strlen($buf); $data .= $buf; } if ($range && $range[0] == 0 && $range[1] == filesize($file) - 1) { $computeTreeHash = true; } else { if ($range) { $computeTreeHash = \Gsandbox\TreeHashCheck::isTreeHashAligned($to + 1, $from, $to); } else { $computeTreeHash = true; } } if ($computeTreeHash) { $hash = new TreeHash(); $hash->update($data); $treeHash = bin2hex($hash->complete()); $res = $res->withHeader('x-amz-sha256-tree-hash', $treeHash); } $res = $res->withHeader('Content-Type', 'application/octet-stream'); $res = $res->withHeader('Content-Length', $contentLength); if ($httpRange) { $res = $res->withHeader('Content-Range', "{$httpRange[0]}-{$httpRange[1]}/{$contentLength}"); } if (fseek($f, $from) === -1) { return $res->withStatus(500); } $readBytes = $to - $from + 1; $dumped = 0; $dumpBufSize = 1024 * 1024 / 2; while ($readBytes > 0 && !feof($f)) { $len = max($bufSize, $readBytes); if ($len > $readBytes) { $len = $readBytes; } $buf = fread($f, $len); if ($buf === false) { return $res->withStatus(500); } while (strlen($buf)) { $dump = substr($buf, 0, $dumpBufSize); $buf = substr($buf, strlen($dump)); $res->getBody()->write($dump); $dumped += strlen($dump); $readBytes -= strlen($dump); } if (isset($GLOBALS['config']['downloadThrottle'])) { $GLOBALS['config']['downloadThrottle'](); } } fclose($f); return $res->withStatus($httpRange ? 206 : 200); }