static size_t WriteData()

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;
}