HttpResponseOutcome AWSClient::AttemptOneRequest()

in src/aws-cpp-sdk-core/source/client/AWSClient.cpp [546:622]


HttpResponseOutcome AWSClient::AttemptOneRequest(const std::shared_ptr<Aws::Http::HttpRequest>& httpRequest, const Aws::AmazonWebServiceRequest& request,
    const char* signerName, const char* signerRegionOverride, const char* signerServiceNameOverride) const
{
    TracingUtils::MakeCallWithTiming(
        [&]() -> void {
            BuildHttpRequest(request, httpRequest);
        },
        TracingUtils::SMITHY_CLIENT_SERIALIZATION_METRIC,
        *m_telemetryProvider->getMeter(this->GetServiceClientName(), {}),
        {{TracingUtils::SMITHY_METHOD_DIMENSION, request.GetServiceRequestName()},{TracingUtils::SMITHY_SERVICE_DIMENSION, this->GetServiceClientName()}});

    InterceptorContext context{request};
    context.SetTransmitRequest(httpRequest);
    for (const auto& interceptor : m_interceptors)
    {
        const auto modifiedRequest = interceptor->ModifyBeforeSigning(context);
        if (!modifiedRequest.IsSuccess())
        {
            return modifiedRequest.GetError();
        }
    }

    auto signer = GetSignerByName(signerName);
    auto signedRequest = TracingUtils::MakeCallWithTiming<bool>([&]() -> bool {
            return signer->SignRequest(*httpRequest, signerRegionOverride, signerServiceNameOverride, true);
        },
        TracingUtils::SMITHY_CLIENT_SIGNING_METRIC,
        *m_telemetryProvider->getMeter(this->GetServiceClientName(), {}),
        {{TracingUtils::SMITHY_METHOD_DIMENSION, request.GetServiceRequestName()},{TracingUtils::SMITHY_SERVICE_DIMENSION, this->GetServiceClientName()}});
    if (!signedRequest)
    {
        AWS_LOGSTREAM_ERROR(AWS_CLIENT_LOG_TAG, "Request signing failed. Returning error.");
        return HttpResponseOutcome(AWSError<CoreErrors>(CoreErrors::CLIENT_SIGNING_FAILURE, "", "SDK failed to sign the request", false/*retryable*/));
    }

    if (request.GetRequestSignedHandler())
    {
        request.GetRequestSignedHandler()(*httpRequest);
    }

    AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Request Successfully signed");
    auto httpResponse = TracingUtils::MakeCallWithTiming<std::shared_ptr<HttpResponse>>(
        [&]() -> std::shared_ptr<HttpResponse> {
            return m_httpClient->MakeRequest(httpRequest, m_readRateLimiter.get(), m_writeRateLimiter.get());
        },
        TracingUtils::SMITHY_CLIENT_SERVICE_CALL_METRIC,
        *m_telemetryProvider->getMeter(this->GetServiceClientName(), {}),
        {{TracingUtils::SMITHY_METHOD_DIMENSION, request.GetServiceRequestName()},{TracingUtils::SMITHY_SERVICE_DIMENSION, this->GetServiceClientName()}});

    context.SetTransmitResponse(httpResponse);
    for (const auto& interceptor : m_interceptors)
    {
        const auto modifiedRequest = interceptor->ModifyBeforeDeserialization(context);
        if (!modifiedRequest.IsSuccess())
        {
            return modifiedRequest.GetError();
        }
    }

    if (DoesResponseGenerateError(httpResponse) )
    {
        AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Request returned error. Attempting to generate appropriate error codes from response");
        auto error = BuildAWSError(httpResponse);
        return HttpResponseOutcome(std::move(error));
    }
    else if(request.HasEmbeddedError(httpResponse->GetResponseBody(), httpResponse->GetHeaders()))
    {
        AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Response has embedded errors");

        auto error = GetErrorMarshaller()->Marshall(*httpResponse);
        return HttpResponseOutcome(std::move(error) );
    }

    AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Request returned successful response.");

    return HttpResponseOutcome(std::move(httpResponse));
}