77#include < aws/core/http/HttpRequest.h>
88#include < aws/core/http/standard/StandardHttpResponse.h>
99#include < aws/core/utils/StringUtils.h>
10+ #include < aws/core/utils/HashingUtils.h>
1011#include < aws/core/utils/logging/LogMacros.h>
1112#include < aws/core/utils/stream/StreamBufProtectedWriter.h>
1213#include < aws/core/client/ClientConfiguration.h>
@@ -98,14 +99,22 @@ void WinSyncHttpClient::AddHeadersToRequest(const std::shared_ptr<HttpRequest>&
9899bool WinSyncHttpClient::StreamPayloadToRequest (const std::shared_ptr<HttpRequest>& request, void * hHttpRequest, Aws::Utils::RateLimits::RateLimiterInterface* writeLimiter) const
99100{
100101 bool success = true ;
102+ bool isChunked = request->HasTransferEncoding () && request->GetTransferEncoding () == Aws::Http::CHUNKED_VALUE;
103+ bool isAwsChunked = request->HasHeader (Aws::Http::CONTENT_ENCODING_HEADER) &&
104+ request->GetHeaderValue (Aws::Http::CONTENT_ENCODING_HEADER).find (Aws::Http::AWS_CHUNKED_VALUE) != Aws::String::npos;
101105 auto payloadStream = request->GetContentBody ();
106+ const char CRLF[] = " \r\n " ;
102107 if (payloadStream)
103108 {
104109 uint64_t bytesWritten;
105110 uint64_t bytesToRead = HTTP_REQUEST_WRITE_BUFFER_LENGTH;
106111 auto startingPos = payloadStream->tellg ();
107112 bool done = false ;
108- char streamBuffer[HTTP_REQUEST_WRITE_BUFFER_LENGTH];
113+ // aws-chunk = hex(chunk-size) + CRLF + chunk-data + CRLF
114+ // Length of hex(HTTP_REQUEST_WRITE_BUFFER_LENGTH) is 4;
115+ // Length of each CRLF is 2.
116+ // Reserve 8 bytes in total, should the request be aws-chunked.
117+ char streamBuffer[ HTTP_REQUEST_WRITE_BUFFER_LENGTH + 8 ];
109118 while (success && !done)
110119 {
111120 payloadStream->read (streamBuffer, bytesToRead);
@@ -115,7 +124,22 @@ bool WinSyncHttpClient::StreamPayloadToRequest(const std::shared_ptr<HttpRequest
115124 bytesWritten = 0 ;
116125 if (bytesRead > 0 )
117126 {
118- bytesWritten = DoWriteData (hHttpRequest, streamBuffer, bytesRead, false );
127+ if (isAwsChunked)
128+ {
129+ if (request->GetRequestHash ().second != nullptr )
130+ {
131+ request->GetRequestHash ().second ->Update (reinterpret_cast <unsigned char *>(streamBuffer), static_cast <size_t >(bytesRead));
132+ }
133+
134+ Aws::String hex = Aws::Utils::StringUtils::ToHexString (static_cast <uint64_t >(bytesRead));
135+ memcpy (streamBuffer + hex.size () + 2 , streamBuffer, static_cast <size_t >(bytesRead));
136+ memcpy (streamBuffer + hex.size () + 2 + bytesRead, CRLF, 2 );
137+ memcpy (streamBuffer, hex.c_str (), hex.size ());
138+ memcpy (streamBuffer + hex.size (), CRLF, 2 );
139+ bytesRead += hex.size () + 4 ;
140+ }
141+
142+ bytesWritten = DoWriteData (hHttpRequest, streamBuffer, bytesRead, isChunked);
119143 if (!bytesWritten)
120144 {
121145 success = false ;
@@ -140,6 +164,40 @@ bool WinSyncHttpClient::StreamPayloadToRequest(const std::shared_ptr<HttpRequest
140164 success = success && ContinueRequest (*request) && IsRequestProcessingEnabled ();
141165 }
142166
167+ if (success && isAwsChunked)
168+ {
169+ Aws::StringStream chunkedTrailer;
170+ chunkedTrailer << " 0" << CRLF;
171+ if (request->GetRequestHash ().second != nullptr )
172+ {
173+ chunkedTrailer << " x-amz-checksum-" << request->GetRequestHash ().first << " :"
174+ << Aws::Utils::HashingUtils::Base64Encode (request->GetRequestHash ().second ->GetHash ().GetResult ()) << CRLF;
175+ }
176+ chunkedTrailer << CRLF;
177+ bytesWritten = DoWriteData (hHttpRequest, const_cast <char *>(chunkedTrailer.str ().c_str ()), chunkedTrailer.str ().size (), isChunked);
178+ if (!bytesWritten)
179+ {
180+ success = false ;
181+ }
182+ else if (writeLimiter)
183+ {
184+ writeLimiter->ApplyAndPayForCost (bytesWritten);
185+ }
186+ }
187+
188+ if (success && isChunked)
189+ {
190+ bytesWritten = FinalizeWriteData (hHttpRequest);
191+ if (!bytesWritten)
192+ {
193+ success = false ;
194+ }
195+ else if (writeLimiter)
196+ {
197+ writeLimiter->ApplyAndPayForCost (bytesWritten);
198+ }
199+ }
200+
143201 payloadStream->clear ();
144202 payloadStream->seekg (startingPos, payloadStream->beg );
145203 }
0 commit comments