in src/aws-cpp-sdk-core/source/http/windows/WinSyncHttpClient.cpp [99:210]
bool WinSyncHttpClient::StreamPayloadToRequest(const std::shared_ptr<HttpRequest>& request, void* hHttpRequest, Aws::Utils::RateLimits::RateLimiterInterface* writeLimiter) const
{
bool success = true;
bool isChunked = request->HasTransferEncoding() && request->GetTransferEncoding() == Aws::Http::CHUNKED_VALUE;
bool isAwsChunked = request->HasHeader(Aws::Http::CONTENT_ENCODING_HEADER) &&
request->GetHeaderValue(Aws::Http::CONTENT_ENCODING_HEADER).find(Aws::Http::AWS_CHUNKED_VALUE) != Aws::String::npos;
auto payloadStream = request->GetContentBody();
const char CRLF[] = "\r\n";
if(payloadStream)
{
uint64_t bytesWritten;
uint64_t bytesToRead = HTTP_REQUEST_WRITE_BUFFER_LENGTH;
auto startingPos = payloadStream->tellg();
bool done = false;
// aws-chunk = hex(chunk-size) + CRLF + chunk-data + CRLF
// Length of hex(HTTP_REQUEST_WRITE_BUFFER_LENGTH) is 4;
// Length of each CRLF is 2.
// Reserve 8 bytes in total, should the request be aws-chunked.
char streamBuffer[ HTTP_REQUEST_WRITE_BUFFER_LENGTH + 8 ];
while(success && !done)
{
payloadStream->read(streamBuffer, bytesToRead);
std::streamsize bytesRead = payloadStream->gcount();
success = !payloadStream->bad();
bytesWritten = 0;
if (bytesRead > 0)
{
if (isAwsChunked)
{
if (request->GetRequestHash().second != nullptr)
{
request->GetRequestHash().second->Update(reinterpret_cast<unsigned char*>(streamBuffer), static_cast<size_t>(bytesRead));
}
Aws::String hex = Aws::Utils::StringUtils::ToHexString(static_cast<uint64_t>(bytesRead));
memcpy(streamBuffer + hex.size() + 2, streamBuffer, static_cast<size_t>(bytesRead));
memcpy(streamBuffer + hex.size() + 2 + bytesRead, CRLF, 2);
memcpy(streamBuffer, hex.c_str(), hex.size());
memcpy(streamBuffer + hex.size(), CRLF, 2);
bytesRead += hex.size() + 4;
}
bytesWritten = DoWriteData(hHttpRequest, streamBuffer, bytesRead, isChunked);
if (!bytesWritten)
{
success = false;
}
else if(writeLimiter)
{
writeLimiter->ApplyAndPayForCost(bytesWritten);
}
}
auto& sentHandler = request->GetDataSentEventHandler();
if (sentHandler)
{
sentHandler(request.get(), (long long)bytesWritten);
}
if(!payloadStream->good())
{
done = true;
}
success = success && ContinueRequest(*request) && IsRequestProcessingEnabled();
}
if (success && isAwsChunked)
{
Aws::StringStream chunkedTrailer;
chunkedTrailer << "0" << CRLF;
if (request->GetRequestHash().second != nullptr)
{
chunkedTrailer << "x-amz-checksum-" << request->GetRequestHash().first << ":"
<< Aws::Utils::HashingUtils::Base64Encode(request->GetRequestHash().second->GetHash().GetResult()) << CRLF;
}
chunkedTrailer << CRLF;
bytesWritten = DoWriteData(hHttpRequest, const_cast<char*>(chunkedTrailer.str().c_str()), chunkedTrailer.str().size(), isChunked);
if (!bytesWritten)
{
success = false;
}
else if(writeLimiter)
{
writeLimiter->ApplyAndPayForCost(bytesWritten);
}
}
if (success && isChunked)
{
bytesWritten = FinalizeWriteData(hHttpRequest);
if (!bytesWritten)
{
success = false;
}
else if (writeLimiter)
{
writeLimiter->ApplyAndPayForCost(bytesWritten);
}
}
payloadStream->clear();
payloadStream->seekg(startingPos, payloadStream->beg);
}
if(success)
{
success = DoReceiveResponse(hHttpRequest);
}
return success;
}