Skip to content

Commit 6c488bf

Browse files
authored
Optimize Rewindable usage (#352)
* Optimize Rewindable usage * Remove GeneratorStream and rename travers * Small fixes
1 parent e96c155 commit 6c488bf

File tree

10 files changed

+50
-17
lines changed

10 files changed

+50
-17
lines changed

src/Signer/SignerV4.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
use AsyncAws\Core\RequestContext;
99
use AsyncAws\Core\Stream\FixedSizeStream;
1010
use AsyncAws\Core\Stream\IterableStream;
11+
use AsyncAws\Core\Stream\ReadOnceResultStream;
1112
use AsyncAws\Core\Stream\RequestStream;
13+
use AsyncAws\Core\Stream\RewindableStream;
1214
use AsyncAws\Core\Stream\StringStream;
1315

1416
/**
@@ -77,6 +79,11 @@ protected function buildBodyDigest(Request $request, bool $isPresign): string
7779
if ($request->hasHeader('x-amz-content-sha256')) {
7880
$hash = ((array) $request->getHeader('x-amz-content-sha256'))[0];
7981
} else {
82+
$body = $request->getBody();
83+
if ($body instanceof ReadOnceResultStream) {
84+
$request->setBody($body = RewindableStream::create($body));
85+
}
86+
8087
$hash = $request->getBody()->hash();
8188
}
8289

@@ -245,6 +252,13 @@ private function convertBodyToStream(Request $request, \DateTimeInterface $now,
245252
$contentLength = $body->length();
246253
}
247254

255+
// If content length is unknown, use the rewindable stream to read it once locally in order to get the length
256+
if (null === $contentLength) {
257+
$request->setBody($body = RewindableStream::create($body));
258+
$body->read();
259+
$contentLength = $body->length();
260+
}
261+
248262
// no need to stream small body. It's simple to convert it to string directly
249263
if ($contentLength < self::CHUNK_SIZE) {
250264
$request->setBody($body = StringStream::create($body));

src/Stream/CallableStream.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
* Convert a "Curl Callable" into a Stream
99
* The Callable must return a chunk at each call. And return an empty string on last call.
1010
*
11-
* @internal
12-
*
1311
* @author Jérémy Derussé <[email protected]>
12+
*
13+
* @internal
1414
*/
15-
final class CallableStream implements RequestStream
15+
final class CallableStream implements ReadOnceResultStream, RequestStream
1616
{
1717
private $content;
1818

src/Stream/FixedSizeStream.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
/**
88
* A Stream decorator that return Chunk with the same exact size.
99
*
10-
* @internal
11-
*
1210
* @author Jérémy Derussé <[email protected]>
11+
*
12+
* @internal
1313
*/
1414
final class FixedSizeStream implements RequestStream
1515
{

src/Stream/IterableStream.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
/**
88
* Convert an iterator into a Stream.
99
*
10-
* @internal
11-
*
1210
* @author Jérémy Derussé <[email protected]>
11+
*
12+
* @internal
1313
*/
14-
final class IterableStream implements RequestStream
14+
final class IterableStream implements ReadOnceResultStream, RequestStream
1515
{
1616
private $content;
1717

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace AsyncAws\Core\Stream;
6+
7+
/**
8+
* Marker for ResultStream that can be read only once.
9+
*/
10+
interface ReadOnceResultStream
11+
{
12+
}

src/Stream/RequestStream.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
/**
66
* Provides method to convert a input into string or chunks.
77
*
8-
* @internal
9-
*
108
* @author Jérémy Derussé <[email protected]>
9+
*
10+
* @internal
1111
*/
1212
interface RequestStream extends \IteratorAggregate
1313
{

src/Stream/ResourceStream.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
/**
88
* Convert a resource into a Stream.
99
*
10-
* @internal
11-
*
1210
* @author Jérémy Derussé <[email protected]>
11+
*
12+
* @internal
1313
*/
1414
final class ResourceStream implements RequestStream
1515
{

src/Stream/RewindableStream.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
* - length
1414
* - hash
1515
*
16-
* @internal
17-
*
1816
* @author Jérémy Derussé <[email protected]>
17+
*
18+
* @internal
1919
*/
2020
final class RewindableStream implements RequestStream
2121
{
@@ -107,4 +107,11 @@ public function hash(string $algo = 'sha256', bool $raw = false): string
107107

108108
return hash_final($ctx, $raw);
109109
}
110+
111+
public function read(): void
112+
{
113+
// Use getIterator() to read stream content to $this->fallback
114+
foreach ($this as $chunk) {
115+
}
116+
}
110117
}

src/Stream/StreamFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public static function create($content): RequestStream
1717
return StringStream::create($content ?? '');
1818
}
1919
if (\is_callable($content)) {
20-
return RewindableStream::create(CallableStream::create($content));
20+
return CallableStream::create($content);
2121
}
2222
if (\is_iterable($content)) {
2323
return IterableStream::create($content);

src/Stream/StringStream.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
/**
88
* Convert a string into a Stream.
99
*
10-
* @internal
11-
*
1210
* @author Jérémy Derussé <[email protected]>
11+
*
12+
* @internal
1313
*/
1414
final class StringStream implements RequestStream
1515
{

0 commit comments

Comments
 (0)