Example #1
0
 public function __invoke(Request $req, Response $res, $args = [])
 {
     $vaultName = $args['vaultName'];
     if (!($vault = Vault::get($vaultName))) {
         return $res->withStatus(404);
     }
     if (!($contentLength = $req->getHeaderLine('Content-Length'))) {
         return $res->withStatus(400)->write('Content-Length header missing.');
     }
     $contentLength = (int) $contentLength;
     if (!($desc = $req->getHeaderLine('x-amz-archive-description'))) {
         $desc = '';
     }
     if (!($contentHash = $req->getHeaderLine('x-amz-content-sha256'))) {
         return $res->withStatus(400)->write('Header x-amz-content-sha256 missing.');
     }
     if (!($treeHash = $req->getHeaderLine('x-amz-sha256-tree-hash'))) {
         return $res->withStatus(400)->write('Header x-amz-sha256-tree-hash missing.');
     }
     $putData = file_get_contents('php://input');
     $actualContentLength = strlen($putData);
     if ($actualContentLength != $contentLength) {
         return $res->withStatus(400)->write("invalid content length (expected: {$contentLength} actual: {$actualContentLength})");
     }
     $hash = new TreeHash();
     $hash->update($putData);
     $actualTreeHash = bin2hex($hash->complete());
     if ($treeHash !== $actualTreeHash) {
         return $res->withStatus(400)->write("tree hash mismatch actual:{$actualTreeHash} exp:{$treeHash}");
     }
     if (isset($GLOBALS['config']['uploadThrottle'])) {
         $GLOBALS['config']['uploadThrottle']();
     }
     $a = new Archive(true, $vault);
     $a->setParam('SHA256TreeHash', $treeHash);
     $a->setParam('Size', (int) $contentLength);
     $a->setParam('Description', $desc);
     if (($ret = file_put_contents($a->getFile('data'), $putData)) !== $contentLength) {
         return $res->withStatus(500)->write("Could not write archive data: " . $a->getFile('data'));
     }
     $vault->invalidateInventory();
     return $res->withStatus(201)->withHeader('x-amz-archive-id', $a->getId())->withHeader('x-amz-sha256-tree-hash', $treeHash);
 }
 public function __invoke(Request $req, Response $res, $args = [])
 {
     $vaultName = $args['vaultName'];
     $multipartID = $args['multipartID'];
     if (!($vault = Vault::get($vaultName))) {
         return $res->withStatus(404);
     }
     if (!($m = $vault->getMultipart($multipartID))) {
         return $res->withStatus(404);
     }
     $contentHash = $req->getHeaderLine('x-amz-content-sha256');
     $treeHash = $req->getHeaderLine('x-amz-sha256-tree-hash');
     $contentRange = $req->getHeaderLine('Content-Range');
     $contentLength = $req->getHeaderLine('Content-Length');
     // 'bytes 0-1048575/*'
     if (!preg_match('@(\\d+)-(\\d+)@', $contentRange, $match)) {
         return $res->withStatus(400)->write('Invalid range');
     }
     $rangeFrom = $match[1];
     $rangeTo = $match[2];
     $putData = file_get_contents('php://input');
     $actualContentLength = strlen($putData);
     if ($actualContentLength != $contentLength) {
         return $res->withStatus(400)->write("invalid content length (expected: {$contentLength} actual: {$actualContentLength})");
     }
     $hash = new TreeHash();
     $hash->update($putData);
     $actualTreeHash = bin2hex($hash->complete());
     if ($treeHash !== $actualTreeHash) {
         return $res->withStatus(400)->write("tree hash mismatch actual:{$actualTreeHash} exp:{$treeHash}");
     }
     if (isset($GLOBALS['config']['uploadThrottle'])) {
         $GLOBALS['config']['uploadThrottle']();
     }
     if (!$m->putPart($rangeFrom, $rangeTo, $contentLength, $putData, $treeHash)) {
         return $res->withStatus(400)->write('putPart failed');
     }
     return $res->withStatus(204)->withHeader('x-amz-sha256-tree-hash', $treeHash);
 }
Example #3
0
use Aws\Glacier\TreeHash;
$I = new ApiTester($scenario);
$I->wantTo('Upload, retrieve and delete an archive.');
$I->haveAuth();
$I->sendPUT('/-/vaults/testvault');
$I->seeResponseCodeIs(201);
$data = '';
$archiveSize = 1024 * 1024 + 10;
for ($i = 0; $i < $archiveSize; $i++) {
    $data .= chr(rand(0, 255));
}
$data[0] = 'A';
$data[1] = 'B';
$data[2] = 'C';
$data[3] = 'D';
$treeHash = new TreeHash();
$treeHash->update($data);
$treeHash = bin2hex($treeHash->complete());
$hash = hash('sha256', $data);
$I->haveHttpHeader('Content-Type', 'application/octet-stream');
$I->haveHttpHeader('x-amz-archive-description', 'test123');
$I->haveHttpHeader('x-amz-sha256-tree-hash', $treeHash);
$I->haveHttpHeader('x-amz-content-sha256', $hash);
$I->sendPOST('/-/vaults/testvault/archives', $data);
$I->seeResponseCodeIs(201);
$I->seeResponseEquals('');
$archiveID = $I->grabHttpHeader('x-amz-archive-id');
$I->haveHttpHeader('Content-Type', 'application/json');
$I->sendPOST('/-/vaults/testvault/jobs', ['Type' => 'archive-retrieval', 'ArchiveId' => $archiveID]);
$I->seeResponseCodeIs(202);
$jobID = $I->grabHttpHeader('x-amz-job-id');
Example #4
0
 protected function getCompleteParamsFn()
 {
     return function () {
         $treeHash = new TreeHash();
         $archiveSize = 0;
         foreach ($this->state->getUploadedParts() as $part) {
             $archiveSize += $part['size'];
             $treeHash->addChecksum($part['checksum']);
         }
         return ['archiveSize' => $archiveSize, 'checksum' => bin2hex($treeHash->complete())];
     };
 }
Example #5
0
 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);
 }