@@ -18,141 +18,149 @@ const char* TEST_LOG_TAG = "AWS_CHUNKED_STREAM_TEST";
1818class AwsChunkedStreamTest : public Aws ::Testing::AwsCppSdkGTestSuite {
1919protected:
2020 StandardHttpRequest CreateRequestWithChecksum (const std::string& url, const std::string& /* data */ ) {
21- StandardHttpRequest request{url, Http::HttpMethod::HTTP_GET};
21+ StandardHttpRequest request{Http::URI ( Aws::String ( url)) , Http::HttpMethod::HTTP_GET};
2222 auto requestHash = Aws::MakeShared<CRC32>(TEST_LOG_TAG);
2323 request.SetRequestHash (" crc32" , requestHash);
2424 return request;
2525 }
2626
27- std::shared_ptr<Aws::IOStream> CreateChunkedStreamBuf (StandardHttpRequest& request, const std::string& data, size_t bufferSize = 65536 ) {
28- auto inputStream = Aws::MakeShared<StringStream>(TEST_LOG_TAG, data);
29- auto chunkedBuf = Aws::MakeUnique<smithy::client::features::AwsChunkedStreamBuf>(
30- TEST_LOG_TAG, &request, inputStream, bufferSize);
31- return std::shared_ptr<Aws::IOStream>(new Aws::IOStream (chunkedBuf.release ()));
32- }
33-
34- std::string ReadEntireStream (std::shared_ptr<Aws::IOStream> stream) {
27+ std::string ReadEntireStream (Aws::IOStream& stream) {
3528 Aws::StringStream output;
3629 char buffer[100 ];
37- while (stream->read (buffer, sizeof (buffer))) {
38- output.write (buffer, stream->gcount ());
39- }
40- if (stream->gcount () > 0 ) {
41- output.write (buffer, stream->gcount ());
30+ while (stream.read (buffer, sizeof (buffer))) {
31+ output.write (buffer, stream.gcount ());
4232 }
43- return output.str ();
44- }
45-
46- template <size_t BufferSize>
47- std::string ReadEntireStream (std::shared_ptr<AwsChunkedStream<BufferSize>> stream) {
48- Aws::StringStream output;
49- Aws::Utils::Array<char > buffer{100 };
50- size_t bytesRead;
51- while ((bytesRead = stream->BufferedRead (buffer.GetUnderlyingData (), 100 )) > 0 ) {
52- std::copy (buffer.GetUnderlyingData (), buffer.GetUnderlyingData () + bytesRead, std::ostream_iterator<char >(output));
33+ if (stream.gcount () > 0 ) {
34+ output.write (buffer, stream.gcount ());
5335 }
54- return output.str ();
55- }
56-
57- template <size_t BufferSize>
58- std::shared_ptr<AwsChunkedStream<BufferSize>> CreateAwsChunkedStream (StandardHttpRequest& request, const std::string& data) {
59- auto inputStream = Aws::MakeShared<StringStream>(TEST_LOG_TAG, data);
60- return Aws::MakeShared<AwsChunkedStream<BufferSize>>(TEST_LOG_TAG, &request, inputStream);
36+ return output.str ().c_str ();
6137 }
6238};
6339
6440TEST_F (AwsChunkedStreamTest, ChunkedStreamShouldWork) {
65- auto request = CreateRequestWithChecksum (" www.elda.com/will" , " 1234567890123456789012345" );
66- auto chunkedStream = CreateAwsChunkedStream<10 >(request, " 1234567890123456789012345" );
67-
68- const auto encodedStr = ReadEntireStream (chunkedStream);
41+ StandardHttpRequest request{" www.elda.com/will" , Http::HttpMethod::HTTP_GET};
42+ auto requestHash = Aws::MakeShared<CRC32>(TEST_LOG_TAG);
43+ request.SetRequestHash (" crc32" , requestHash);
44+ std::shared_ptr<IOStream> inputStream = Aws::MakeShared<StringStream>(TEST_LOG_TAG, " 1234567890123456789012345" );
45+ AwsChunkedStream<10 > chunkedStream{&request, inputStream};
46+ Aws::Utils::Array<char > outputBuffer{100 };
47+ Aws::StringStream output;
48+ size_t readIterations{4 };
49+ size_t bufferOffset{0 };
50+ while (readIterations > 0 ) {
51+ bufferOffset = chunkedStream.BufferedRead (outputBuffer.GetUnderlyingData (), 10 );
52+ std::copy (outputBuffer.GetUnderlyingData (), outputBuffer.GetUnderlyingData () + bufferOffset, std::ostream_iterator<char >(output));
53+ readIterations--;
54+ }
55+ // Read trailing checksum that is greater than 10 chars
56+ bufferOffset = chunkedStream.BufferedRead (outputBuffer.GetUnderlyingData (), 40 );
57+ EXPECT_EQ (36ul , bufferOffset);
58+ std::copy (outputBuffer.GetUnderlyingData (), outputBuffer.GetUnderlyingData () + bufferOffset, std::ostream_iterator<char >(output));
59+ const auto encodedStr = output.str ();
6960 auto expectedStreamWithChecksum = " A\r\n 1234567890\r\n A\r\n 1234567890\r\n 5\r\n 12345\r\n 0\r\n x-amz-checksum-crc32:78DeVw==\r\n\r\n " ;
7061 EXPECT_EQ (expectedStreamWithChecksum, encodedStr);
7162}
7263
7364TEST_F (AwsChunkedStreamTest, ShouldNotRequireTwoReadsOnSmallChunk) {
74- auto request = CreateRequestWithChecksum (" www.clemar.com/strohl" , " 12345" );
75- auto chunkedStream = CreateAwsChunkedStream<100 >(request, " 12345" );
76-
77- const auto encodedStr = ReadEntireStream (chunkedStream);
65+ StandardHttpRequest request{" www.clemar.com/strohl" , Http::HttpMethod::HTTP_GET};
66+ auto requestHash = Aws::MakeShared<CRC32>(TEST_LOG_TAG);
67+ request.SetRequestHash (" crc32" , requestHash);
68+ std::shared_ptr<IOStream> inputStream = Aws::MakeShared<StringStream>(TEST_LOG_TAG, " 12345" );
69+ AwsChunkedStream<100 > chunkedStream{&request, inputStream};
70+ Aws::Utils::Array<char > outputBuffer{100 };
71+ Aws::StringStream output;
72+ const auto bufferOffset = chunkedStream.BufferedRead (outputBuffer.GetUnderlyingData (), 100 );
73+ std::copy (outputBuffer.GetUnderlyingData (), outputBuffer.GetUnderlyingData () + bufferOffset, std::ostream_iterator<char >(output));
74+ EXPECT_EQ (46ul , bufferOffset);
75+ const auto encodedStr = output.str ();
7876 auto expectedStreamWithChecksum = " 5\r\n 12345\r\n 0\r\n x-amz-checksum-crc32:y/U6HA==\r\n\r\n " ;
7977 EXPECT_EQ (expectedStreamWithChecksum, encodedStr);
8078}
8179
8280TEST_F (AwsChunkedStreamTest, ShouldWorkOnSmallBuffer) {
83- auto request = CreateRequestWithChecksum (" www.eugief.com/hesimay" , " 1234567890" );
84- auto chunkedStream = CreateAwsChunkedStream<5 >(request, " 1234567890" );
85-
86- // Read first chunk
87- char buffer[10 ];
88- auto amountRead = chunkedStream->BufferedRead (buffer, sizeof (buffer));
89- std::string firstRead (buffer, amountRead);
81+ StandardHttpRequest request{" www.eugief.com/hesimay" , Http::HttpMethod::HTTP_GET};
82+ auto requestHash = Aws::MakeShared<CRC32>(TEST_LOG_TAG);
83+ request.SetRequestHash (" crc32" , requestHash);
84+ std::shared_ptr<IOStream> inputStream = Aws::MakeShared<StringStream>(TEST_LOG_TAG, " 1234567890" );
85+ AwsChunkedStream<5 > chunkedStream{&request, inputStream};
86+ Aws::Utils::Array<char > outputBuffer{100 };
87+ // Read first 5 bytes, we get back ten bytes chunk encoded since it is "5\r\n12345\r\n"
88+ Aws::StringStream firstRead;
89+ auto amountRead = chunkedStream.BufferedRead (outputBuffer.GetUnderlyingData (), 100 );
90+ std::copy (outputBuffer.GetUnderlyingData (), outputBuffer.GetUnderlyingData () + amountRead, std::ostream_iterator<char >(firstRead));
9091 EXPECT_EQ (10ul , amountRead);
91- EXPECT_EQ (" 5\r\n 12345\r\n " , firstRead);
92-
93- // Read remaining data
94- char buffer2[50 ];
95- amountRead = chunkedStream->BufferedRead (buffer2, sizeof (buffer2));
96- std::string secondRead (buffer2, amountRead);
92+ auto encodedStr = firstRead.str ();
93+ EXPECT_EQ (" 5\r\n 12345\r\n " , encodedStr);
94+ // Read second 5 bytes, we get back 46 bytes because we exhaust the underlying buffer
95+ // abd write the trailer "5\r\n67890\r\n0\r\nx-amz-checksum-crc32:Jh2u5Q==\r\n\r\n"
96+ Aws::StringStream secondRead;
97+ amountRead = chunkedStream.BufferedRead (outputBuffer.GetUnderlyingData (), 100 );
98+ std::copy (outputBuffer.GetUnderlyingData (), outputBuffer.GetUnderlyingData () + amountRead, std::ostream_iterator<char >(secondRead));
9799 EXPECT_EQ (46ul , amountRead);
98- EXPECT_EQ ( " 5 \r\n 67890 \r\n 0 \r\n x-amz-checksum-crc32:Jh2u5Q== \r\n\r\n " , secondRead);
99-
100- // Any subsequent reads should return 0
101- amountRead = chunkedStream-> BufferedRead (buffer, sizeof (buffer) );
100+ encodedStr = secondRead. str ( );
101+ EXPECT_EQ ( " 5 \r\n 67890 \r\n 0 \r\n x-amz-checksum-crc32:Jh2u5Q== \r\n\r\n " , encodedStr);
102+ // Any subsequent reads will return 0 because all streams are exhausted
103+ amountRead = chunkedStream. BufferedRead (outputBuffer. GetUnderlyingData (), 100 );
102104 EXPECT_EQ (0ul , amountRead);
103105}
104106
105107TEST_F (AwsChunkedStreamTest, ShouldWorkOnEmptyStream) {
106- auto request = CreateRequestWithChecksum (" www.nidia.com/juna" , " " );
107- auto chunkedStream = CreateAwsChunkedStream<5 >(request, " " );
108-
109- const auto encodedStr = ReadEntireStream (chunkedStream);
108+ StandardHttpRequest request{" www.nidia.com/juna" , Http::HttpMethod::HTTP_GET};
109+ auto requestHash = Aws::MakeShared<CRC32>(TEST_LOG_TAG);
110+ request.SetRequestHash (" crc32" , requestHash);
111+ std::shared_ptr<IOStream> inputStream = Aws::MakeShared<StringStream>(TEST_LOG_TAG, " " );
112+ AwsChunkedStream<5 > chunkedStream{&request, inputStream};
113+ Aws::Utils::Array<char > outputBuffer{100 };
114+ Aws::StringStream firstRead;
115+ auto amountRead = chunkedStream.BufferedRead (outputBuffer.GetUnderlyingData (), 100 );
116+ std::copy (outputBuffer.GetUnderlyingData (), outputBuffer.GetUnderlyingData () + amountRead, std::ostream_iterator<char >(firstRead));
117+ EXPECT_EQ (36ul , amountRead);
118+ auto encodedStr = firstRead.str ();
110119 EXPECT_EQ (" 0\r\n x-amz-checksum-crc32:AAAAAA==\r\n\r\n " , encodedStr);
111120}
112121
113- TEST_F (AwsChunkedStreamTest, ChunkingInterceptorStreamBufShouldWork ) {
122+ TEST_F (AwsChunkedStreamTest, ChunkingInterceptorShouldWork ) {
114123 auto request = CreateRequestWithChecksum (" www.elda.com/will" , " 1234567890123456789012345" );
115- auto chunkedBody = CreateChunkedStreamBuf (request, " 1234567890123456789012345" , 10 );
116-
117- const auto encodedStr = ReadEntireStream (chunkedBody);
124+ std::shared_ptr<IOStream> inputStream = Aws::MakeShared<StringStream>(TEST_LOG_TAG, " 1234567890123456789012345" );
125+ auto chunkedBuf = Aws::MakeUnique<smithy::client::features::AwsChunkedStreamBuf>(TEST_LOG_TAG, &request, inputStream, 10 );
126+ Aws::IOStream chunkedStream (chunkedBuf.release ());
127+ const auto encodedStr = ReadEntireStream (chunkedStream);
118128 auto expectedStreamWithChecksum = " A\r\n 1234567890\r\n A\r\n 1234567890\r\n 5\r\n 12345\r\n 0\r\n x-amz-checksum-crc32:78DeVw==\r\n\r\n " ;
119129 EXPECT_EQ (expectedStreamWithChecksum, encodedStr);
120130}
121131
122132TEST_F (AwsChunkedStreamTest, ChunkingInterceptorShouldNotRequireTwoReadsOnSmallChunk) {
123133 auto request = CreateRequestWithChecksum (" www.clemar.com/strohl" , " 12345" );
124- auto chunkedBody = CreateChunkedStreamBuf (request, " 12345" , 100 );
125-
126- const auto encodedStr = ReadEntireStream (chunkedBody);
134+ std::shared_ptr<IOStream> inputStream = Aws::MakeShared<StringStream>(TEST_LOG_TAG, " 12345" );
135+ auto chunkedBuf = Aws::MakeUnique<smithy::client::features::AwsChunkedStreamBuf>(TEST_LOG_TAG, &request, inputStream, 100 );
136+ Aws::IOStream chunkedStream (chunkedBuf.release ());
137+ const auto encodedStr = ReadEntireStream (chunkedStream);
127138 auto expectedStreamWithChecksum = " 5\r\n 12345\r\n 0\r\n x-amz-checksum-crc32:y/U6HA==\r\n\r\n " ;
128139 EXPECT_EQ (expectedStreamWithChecksum, encodedStr);
129140}
130141
131142TEST_F (AwsChunkedStreamTest, ChunkingInterceptorShouldWorkOnSmallBuffer) {
132143 auto request = CreateRequestWithChecksum (" www.eugief.com/hesimay" , " 1234567890" );
133- auto chunkedBody = CreateChunkedStreamBuf (request , " 1234567890" , 5 );
134-
135- // Read first chunk
144+ std::shared_ptr<IOStream> inputStream = Aws::MakeShared<StringStream>(TEST_LOG_TAG , " 1234567890" );
145+ auto chunkedBuf = Aws::MakeUnique<smithy::client::features::AwsChunkedStreamBuf>(TEST_LOG_TAG, &request, inputStream, 5 );
146+ Aws::IOStream chunkedStream (chunkedBuf. release ());
136147 char buffer[10 ];
137- chunkedBody-> read (buffer, sizeof (buffer));
138- std::string firstRead (buffer, chunkedBody-> gcount ());
148+ chunkedStream. read (buffer, sizeof (buffer));
149+ std::string firstRead (buffer, chunkedStream. gcount ());
139150 EXPECT_EQ (" 5\r\n 12345\r\n " , firstRead);
140-
141- // Read remaining data
142151 char buffer2[50 ];
143- chunkedBody-> read (buffer2, sizeof (buffer2));
144- std::string secondRead (buffer2, chunkedBody-> gcount ());
152+ chunkedStream. read (buffer2, sizeof (buffer2));
153+ std::string secondRead (buffer2, chunkedStream. gcount ());
145154 EXPECT_EQ (" 5\r\n 67890\r\n 0\r\n x-amz-checksum-crc32:Jh2u5Q==\r\n\r\n " , secondRead);
146-
147- // Any subsequent reads should return 0
148- chunkedBody->read (buffer, sizeof (buffer));
149- EXPECT_EQ (0 , chunkedBody->gcount ());
155+ chunkedStream.read (buffer, sizeof (buffer));
156+ EXPECT_EQ (0 , chunkedStream.gcount ());
150157}
151158
152159TEST_F (AwsChunkedStreamTest, ChunkingInterceptorShouldWorkOnEmptyStream) {
153160 auto request = CreateRequestWithChecksum (" www.nidia.com/juna" , " " );
154- auto chunkedBody = CreateChunkedStreamBuf (request, " " , 5 );
155-
156- const auto encodedStr = ReadEntireStream (chunkedBody);
161+ std::shared_ptr<IOStream> inputStream = Aws::MakeShared<StringStream>(TEST_LOG_TAG, " " );
162+ auto chunkedBuf = Aws::MakeUnique<smithy::client::features::AwsChunkedStreamBuf>(TEST_LOG_TAG, &request, inputStream, 5 );
163+ Aws::IOStream chunkedStream (chunkedBuf.release ());
164+ const auto encodedStr = ReadEntireStream (chunkedStream);
157165 EXPECT_EQ (" 0\r\n x-amz-checksum-crc32:AAAAAA==\r\n\r\n " , encodedStr);
158166}
0 commit comments