in src/EncryptionClient.php [312:403]
public function getObjectSecurelyAsync(Models\GetObjectRequest $request, array $args = []): GuzzleHttp\Promise\Promise
{
$rangeHeader = null;
$discardCount = 0;
$adjustOffset = 0;
if ($request->rangeHeader != null) {
$ranges = Utils::parseHttpRange($request->rangeHeader);
if ($ranges === false) {
throw new \InvalidArgumentException("request.rangeHeader is invalid, got $request->rangeHeader");
}
$start = $ranges[0] < 0 ? 0 : $ranges[0];
$adjustOffset = $this->adjustRangeStart($start);
$discardCount = $start - $adjustOffset;
if ($discardCount > 0) {
// bytes=0-1023 or bytes=0-
$rangeHeader = sprintf('bytes=%d-', $adjustOffset);
if ($ranges[1] >= 0) {
$rangeHeader .= strval($ranges[1]);
}
}
}
$eRequest = $request;
if ($rangeHeader != null) {
$eRequest = clone $request;
$eRequest->rangeHeader = $rangeHeader;
$eRequest->rangeBehavior = 'standard';
}
// stream mode
if (
isset($args['request_options']) &&
isset($args['request_options']['stream']) &&
$args['request_options']['stream'] === true
) {
/**
* @var Crypto\ContentCipherInterface $contentCipher
*/
$contentCipher = null;
$args['request_options'] = array_merge($args['request_options'], [
'on_headers' => function ($response) use (&$contentCipher) {
$contentCipher = $this->contentCipherfromHeaders($response);
}
]);
return $this->client->getObjectAsync($eRequest, $args)->then(
function (Models\GetObjectResult $result) use (&$adjustOffset, &$discardCount, &$contentCipher) {
$body = $result->body;
if ($contentCipher !== null) {
$cipher = $contentCipher->getCipher($adjustOffset);
$body = new Crypto\ReadDecryptStream($body, $cipher);
}
if ($discardCount > 0) {
$body->read($discardCount);
}
$result = $this->adjustGetObjectResult($result, $discardCount);
$result->body = $body;
return $result;
}
);
}
// non stream mode, and save into
$sink = null;
if (isset($args['request_options']) && isset($args['request_options']['sink'])) {
$sink = $args['request_options']['sink'];
}
$fromFilepath = \is_string($sink);
$stream = $fromFilepath ?
new GuzzleHttp\Psr7\LazyOpenStream($sink, 'w+') : Utils::streamFor($sink);
$esink = new Crypto\LazyDecryptStream(
$stream,
$discardCount,
function ($response) {
return $this->contentCipherfromHeaders($response);
}
);
$args['request_options'] = array_merge($args['request_options'] ?? [], [
'sink' => $esink
]);
return $this->client->getObjectAsync($eRequest, $args)->then(
function (Models\GetObjectResult $result) use (&$discardCount, &$fromFilepath) {
$result = $this->adjustGetObjectResult($result, $discardCount);
// unwrap stream from LazyDecryptStream
if ($result->body instanceof Crypto\LazyDecryptStream) {
$result->body = $fromFilepath ? null : $result->body->unwrap();
}
return $result;
}
);
}