in src/aws-cpp-sdk-core/source/http/curl/CurlHttpClient.cpp [190:270]
static size_t WriteData(char* ptr, size_t size, size_t nmemb, void* userdata)
{
if (ptr)
{
CurlWriteCallbackContext* context = reinterpret_cast<CurlWriteCallbackContext*>(userdata);
const CurlHttpClient* client = context->m_client;
if(!client->ContinueRequest(*context->m_request) || !client->IsRequestProcessingEnabled())
{
return 0;
}
HttpResponse* response = context->m_response;
auto& headersHandler = context->m_request->GetHeadersReceivedEventHandler();
if (context->m_numBytesResponseReceived == 0 && headersHandler)
{
headersHandler(context->m_request, context->m_response);
}
size_t sizeToWrite = size * nmemb;
if (context->m_rateLimiter)
{
context->m_rateLimiter->ApplyAndPayForCost(static_cast<int64_t>(sizeToWrite));
}
for (const auto& hashIterator : context->m_request->GetResponseValidationHashes())
{
std::stringstream headerStr;
headerStr<<"x-amz-checksum-"<<hashIterator.first;
if(context->m_response->HasHeader(headerStr.str().c_str()))
{
hashIterator.second->Update(reinterpret_cast<unsigned char*>(ptr), sizeToWrite);
break;
}
}
if (response->GetResponseBody().fail()) {
const auto& ref = response->GetResponseBody();
AWS_LOGSTREAM_ERROR(CURL_HTTP_CLIENT_TAG, "Response output stream in bad state (eof: "
<< ref.eof() << ", bad: " << ref.bad() << ")");
return 0;
}
auto cur = response->GetResponseBody().tellp();
if (response->GetResponseBody().fail()) {
const auto& ref = response->GetResponseBody();
AWS_LOGSTREAM_ERROR(CURL_HTTP_CLIENT_TAG, "Unable to query response output position (eof: "
<< ref.eof() << ", bad: " << ref.bad() << ")");
return 0;
}
response->GetResponseBody().write(ptr, static_cast<std::streamsize>(sizeToWrite));
if (response->GetResponseBody().fail()) {
const auto& ref = response->GetResponseBody();
AWS_LOGSTREAM_ERROR(CURL_HTTP_CLIENT_TAG, "Failed to write " << size << " / " << sizeToWrite << " B response"
<< " at " << cur << " (eof: " << ref.eof() << ", bad: " << ref.bad() << ")");
return 0;
}
if ((context->m_request->IsEventStreamRequest() || context->m_request->HasEventStreamResponse() )
&& !response->HasHeader(Aws::Http::X_AMZN_ERROR_TYPE))
{
response->GetResponseBody().flush();
if (response->GetResponseBody().fail()) {
const auto& ref = response->GetResponseBody();
AWS_LOGSTREAM_ERROR(CURL_HTTP_CLIENT_TAG, "Failed to flush event response (eof: "
<< ref.eof() << ", bad: " << ref.bad() << ")");
return 0;
}
}
auto& receivedHandler = context->m_request->GetDataReceivedEventHandler();
if (receivedHandler)
{
receivedHandler(context->m_request, context->m_response, static_cast<long long>(sizeToWrite));
}
AWS_LOGSTREAM_TRACE(CURL_HTTP_CLIENT_TAG, sizeToWrite << " bytes written to response.");
context->m_numBytesResponseReceived += sizeToWrite;
return sizeToWrite;
}
return 0;
}