aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client
diff options
context:
space:
mode:
authordakovalkov <dakovalkov@yandex-team.com>2023-12-03 13:33:55 +0300
committerdakovalkov <dakovalkov@yandex-team.com>2023-12-03 14:04:39 +0300
commit2a718325637e5302334b6d0a6430f63168f8dbb3 (patch)
tree64be81080b7df9ec1d86d053a0c394ae53fcf1fe /contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client
parente0d94a470142d95c3007e9c5d80380994940664a (diff)
downloadydb-2a718325637e5302334b6d0a6430f63168f8dbb3.tar.gz
Update contrib/libs/aws-sdk-cpp to 1.11.37
Diffstat (limited to 'contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client')
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSClient.cpp686
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp19
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSJsonClient.cpp212
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSUrlPresigner.cpp236
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSXmlClient.cpp180
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AdaptiveRetryStrategy.cpp228
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/ClientConfiguration.cpp322
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/CoreErrors.cpp20
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/DefaultRetryStrategy.cpp2
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/GenericClientConfiguration.cpp103
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RequestCompression.cpp336
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RetryStrategy.cpp14
12 files changed, 1917 insertions, 441 deletions
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSClient.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSClient.cpp
index 4b2a38b4e6..d1a6f262c9 100644
--- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSClient.cpp
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSClient.cpp
@@ -7,11 +7,13 @@
#include <aws/core/AmazonWebServiceRequest.h>
#include <aws/core/auth/AWSAuthSigner.h>
#include <aws/core/auth/AWSAuthSignerProvider.h>
+#include <aws/core/client/AWSUrlPresigner.h>
#include <aws/core/client/AWSError.h>
#include <aws/core/client/AWSErrorMarshaller.h>
#include <aws/core/client/ClientConfiguration.h>
#include <aws/core/client/CoreErrors.h>
#include <aws/core/client/RetryStrategy.h>
+#include <aws/core/client/RequestCompression.h>
#include <aws/core/http/HttpClient.h>
#include <aws/core/http/HttpClientFactory.h>
#include <aws/core/http/HttpResponse.h>
@@ -27,6 +29,9 @@
#include <aws/core/Globals.h>
#include <aws/core/utils/EnumParseOverflowContainer.h>
#include <aws/core/utils/crypto/MD5.h>
+#include <aws/core/utils/crypto/CRC32.h>
+#include <aws/core/utils/crypto/Sha256.h>
+#include <aws/core/utils/crypto/Sha1.h>
#include <aws/core/utils/HashingUtils.h>
#include <aws/core/utils/crypto/Factories.h>
#include <aws/core/utils/event/EventStream.h>
@@ -35,10 +40,12 @@
#include <aws/core/Region.h>
#include <aws/core/utils/DNS.h>
#include <aws/core/Version.h>
+#include <aws/core/platform/Environment.h>
#include <aws/core/platform/OSVersionInfo.h>
#include <cstring>
#include <cassert>
+#include <iomanip>
using namespace Aws;
using namespace Aws::Client;
@@ -51,12 +58,15 @@ static const int SUCCESS_RESPONSE_MIN = 200;
static const int SUCCESS_RESPONSE_MAX = 299;
static const char AWS_CLIENT_LOG_TAG[] = "AWSClient";
+static const char AWS_LAMBDA_FUNCTION_NAME[] = "AWS_LAMBDA_FUNCTION_NAME";
+static const char X_AMZN_TRACE_ID[] = "_X_AMZN_TRACE_ID";
+
//4 Minutes
static const std::chrono::milliseconds TIME_DIFF_MAX = std::chrono::minutes(4);
//-4 Minutes
static const std::chrono::milliseconds TIME_DIFF_MIN = std::chrono::minutes(-4);
-static CoreErrors GuessBodylessErrorType(Aws::Http::HttpResponseCode responseCode)
+CoreErrors AWSClient::GuessBodylessErrorType(Aws::Http::HttpResponseCode responseCode)
{
switch (responseCode)
{
@@ -70,6 +80,14 @@ static CoreErrors GuessBodylessErrorType(Aws::Http::HttpResponseCode responseCod
}
}
+bool AWSClient::DoesResponseGenerateError(const std::shared_ptr<HttpResponse>& response)
+{
+ if (response->HasClientError()) return true;
+
+ int responseCode = static_cast<int>(response->GetResponseCode());
+ return responseCode < SUCCESS_RESPONSE_MIN || responseCode > SUCCESS_RESPONSE_MAX;
+}
+
struct RequestInfo
{
Aws::Utils::DateTime ttl;
@@ -107,9 +125,10 @@ AWSClient::AWSClient(const Aws::Client::ClientConfiguration& configuration,
m_customizedUserAgent(!m_userAgent.empty()),
m_hash(Aws::Utils::Crypto::CreateMD5Implementation()),
m_requestTimeoutMs(configuration.requestTimeoutMs),
- m_enableClockSkewAdjustment(configuration.enableClockSkewAdjustment)
+ m_enableClockSkewAdjustment(configuration.enableClockSkewAdjustment),
+ m_requestCompressionConfig(configuration.requestCompressionConfig)
{
- SetServiceClientName("AWSBaseClient");
+ AWSClient::SetServiceClientName("AWSBaseClient");
}
AWSClient::AWSClient(const Aws::Client::ClientConfiguration& configuration,
@@ -126,9 +145,10 @@ AWSClient::AWSClient(const Aws::Client::ClientConfiguration& configuration,
m_customizedUserAgent(!m_userAgent.empty()),
m_hash(Aws::Utils::Crypto::CreateMD5Implementation()),
m_requestTimeoutMs(configuration.requestTimeoutMs),
- m_enableClockSkewAdjustment(configuration.enableClockSkewAdjustment)
+ m_enableClockSkewAdjustment(configuration.enableClockSkewAdjustment),
+ m_requestCompressionConfig(configuration.requestCompressionConfig)
{
- SetServiceClientName("AWSBaseClient");
+ AWSClient::SetServiceClientName("AWSBaseClient");
}
void AWSClient::SetServiceClientName(const Aws::String& name)
@@ -136,10 +156,7 @@ void AWSClient::SetServiceClientName(const Aws::String& name)
m_serviceName = name;
if (!m_customizedUserAgent)
{
- Aws::StringStream ss;
- ss << "aws-sdk-cpp/" << Version::GetVersionString() << " " << Aws::OSVersionInfo::ComputeOSVersionString()
- << " " << Version::GetCompilerVersionString();
- m_userAgent = ss.str();
+ m_userAgent = Aws::Client::ComputeUserAgentString();
}
}
@@ -232,16 +249,24 @@ HttpResponseOutcome AWSClient::AttemptExhaustively(const Aws::Http::URI& uri,
const char* signerRegion = signerRegionOverride;
Aws::String regionFromResponse;
- Aws::String invocationId = UUID::RandomUUID();
+ Aws::String invocationId = Aws::Utils::UUID::RandomUUID();
RequestInfo requestInfo;
requestInfo.attempt = 1;
requestInfo.maxAttempts = 0;
httpRequest->SetHeaderValue(Http::SDK_INVOCATION_ID_HEADER, invocationId);
httpRequest->SetHeaderValue(Http::SDK_REQUEST_HEADER, requestInfo);
+ AppendRecursionDetectionHeader(httpRequest);
for (long retries = 0;; retries++)
{
- m_retryStrategy->GetSendToken();
+ if(!m_retryStrategy->HasSendToken())
+ {
+ return HttpResponseOutcome(AWSError<CoreErrors>(CoreErrors::SLOW_DOWN,
+ "",
+ "Unable to acquire enough send tokens to execute request.",
+ false/*retryable*/));
+
+ };
httpRequest->SetEventStreamRequest(request.IsEventStreamRequest());
outcome = AttemptOneRequest(httpRequest, request, signerName, signerRegion, signerServiceNameOverride);
@@ -358,16 +383,24 @@ HttpResponseOutcome AWSClient::AttemptExhaustively(const Aws::Http::URI& uri,
const char* signerRegion = signerRegionOverride;
Aws::String regionFromResponse;
- Aws::String invocationId = UUID::RandomUUID();
+ Aws::String invocationId = Aws::Utils::UUID::RandomUUID();
RequestInfo requestInfo;
requestInfo.attempt = 1;
requestInfo.maxAttempts = 0;
httpRequest->SetHeaderValue(Http::SDK_INVOCATION_ID_HEADER, invocationId);
httpRequest->SetHeaderValue(Http::SDK_REQUEST_HEADER, requestInfo);
+ AppendRecursionDetectionHeader(httpRequest);
for (long retries = 0;; retries++)
{
- m_retryStrategy->GetSendToken();
+ if(!m_retryStrategy->HasSendToken())
+ {
+ return HttpResponseOutcome(AWSError<CoreErrors>(CoreErrors::SLOW_DOWN,
+ "",
+ "Unable to acquire enough send tokens to execute request.",
+ false/*retryable*/));
+
+ };
outcome = AttemptOneRequest(httpRequest, signerName, requestName, signerRegion, signerServiceNameOverride);
if (retries == 0)
{
@@ -452,15 +485,6 @@ HttpResponseOutcome AWSClient::AttemptExhaustively(const Aws::Http::URI& uri,
return outcome;
}
-static bool DoesResponseGenerateError(const std::shared_ptr<HttpResponse>& response)
-{
- if (response->HasClientError()) return true;
-
- int responseCode = static_cast<int>(response->GetResponseCode());
- return responseCode < SUCCESS_RESPONSE_MIN || responseCode > SUCCESS_RESPONSE_MAX;
-
-}
-
HttpResponseOutcome AWSClient::AttemptOneRequest(const std::shared_ptr<HttpRequest>& httpRequest, const Aws::AmazonWebServiceRequest& request,
const char* signerName, const char* signerRegionOverride, const char* signerServiceNameOverride) const
{
@@ -481,7 +505,31 @@ HttpResponseOutcome AWSClient::AttemptOneRequest(const std::shared_ptr<HttpReque
std::shared_ptr<HttpResponse> httpResponse(
m_httpClient->MakeRequest(httpRequest, m_readRateLimiter.get(), m_writeRateLimiter.get()));
- if (DoesResponseGenerateError(httpResponse))
+ if (request.ShouldValidateResponseChecksum())
+ {
+ for (const auto& hashIterator : httpRequest->GetResponseValidationHashes())
+ {
+ Aws::String checksumHeaderKey = Aws::String("x-amz-checksum-") + hashIterator.first;
+ // TODO: If checksum ends with -#, then skip
+ if (httpResponse->HasHeader(checksumHeaderKey.c_str()))
+ {
+ Aws::String checksumHeaderValue = httpResponse->GetHeader(checksumHeaderKey.c_str());
+ if (HashingUtils::Base64Encode(hashIterator.second->GetHash().GetResult()) != checksumHeaderValue)
+ {
+ AWSError<CoreErrors> error(CoreErrors::VALIDATION, "", "Response checksums mismatch", false/*retryable*/);
+ error.SetResponseHeaders(httpResponse->GetHeaders());
+ error.SetResponseCode(httpResponse->GetResponseCode());
+ error.SetRemoteHostIpAddress(httpResponse->GetOriginatingRequest().GetResolvedRemoteHost());
+ AWS_LOGSTREAM_ERROR(AWS_CLIENT_LOG_TAG, error);
+ return HttpResponseOutcome(error);
+ }
+ // Validate only a single checksum returned in an HTTP response
+ break;
+ }
+ }
+ }
+
+ if (DoesResponseGenerateError(httpResponse) || request.HasEmbeddedError(httpResponse->GetResponseBody(), httpResponse->GetHeaders()))
{
AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Request returned error. Attempting to generate appropriate error codes from response");
auto error = BuildAWSError(httpResponse);
@@ -560,6 +608,54 @@ StreamOutcome AWSClient::MakeRequestWithUnparsedResponse(const Aws::Http::URI& u
return StreamOutcome(std::move(httpResponseOutcome));
}
+StreamOutcome AWSClient::MakeRequestWithUnparsedResponse(const Aws::AmazonWebServiceRequest& request,
+ const Aws::Endpoint::AWSEndpoint& endpoint,
+ Http::HttpMethod method,
+ const char* signerName,
+ const char* signerRegionOverride,
+ const char* signerServiceNameOverride) const
+{
+ const Aws::Http::URI& uri = endpoint.GetURI();
+ if (endpoint.GetAttributes()) {
+ signerName = endpoint.GetAttributes()->authScheme.GetName().c_str();
+ if (endpoint.GetAttributes()->authScheme.GetSigningRegion()) {
+ signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegion()->c_str();
+ }
+ if (endpoint.GetAttributes()->authScheme.GetSigningRegionSet()) {
+ signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegionSet()->c_str();
+ }
+ if (endpoint.GetAttributes()->authScheme.GetSigningName()) {
+ signerServiceNameOverride = endpoint.GetAttributes()->authScheme.GetSigningName()->c_str();
+ }
+ }
+
+ return MakeRequestWithUnparsedResponse(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride);
+}
+
+XmlOutcome AWSXMLClient::MakeRequestWithEventStream(const Aws::AmazonWebServiceRequest& request,
+ const Aws::Endpoint::AWSEndpoint& endpoint,
+ Http::HttpMethod method,
+ const char* signerName,
+ const char* signerRegionOverride,
+ const char* signerServiceNameOverride) const
+{
+ const Aws::Http::URI& uri = endpoint.GetURI();
+ if (endpoint.GetAttributes()) {
+ signerName = endpoint.GetAttributes()->authScheme.GetName().c_str();
+ if (endpoint.GetAttributes()->authScheme.GetSigningRegion()) {
+ signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegion()->c_str();
+ }
+ if (endpoint.GetAttributes()->authScheme.GetSigningRegionSet()) {
+ signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegionSet()->c_str();
+ }
+ if (endpoint.GetAttributes()->authScheme.GetSigningName()) {
+ signerServiceNameOverride = endpoint.GetAttributes()->authScheme.GetSigningName()->c_str();
+ }
+ }
+
+ return MakeRequestWithEventStream(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride);
+}
+
XmlOutcome AWSXMLClient::MakeRequestWithEventStream(const Aws::Http::URI& uri,
const Aws::AmazonWebServiceRequest& request,
Http::HttpMethod method,
@@ -603,6 +699,119 @@ void AWSClient::AddHeadersToRequest(const std::shared_ptr<Aws::Http::HttpRequest
AddCommonHeaders(*httpRequest);
}
+void AWSClient::AppendHeaderValueToRequest(const std::shared_ptr<HttpRequest> &httpRequest, const String header, const String value) const
+{
+ if (!httpRequest->HasHeader(header.c_str()))
+ {
+ httpRequest->SetHeaderValue(header, value);
+ }
+ else
+ {
+ Aws::String contentEncoding = httpRequest->GetHeaderValue(header.c_str());
+ contentEncoding.append(",").append(value);
+ httpRequest->SetHeaderValue(header, contentEncoding);
+ }
+}
+
+void AWSClient::AddChecksumToRequest(const std::shared_ptr<Aws::Http::HttpRequest>& httpRequest,
+ const Aws::AmazonWebServiceRequest& request) const
+{
+ Aws::String checksumAlgorithmName = Aws::Utils::StringUtils::ToLower(request.GetChecksumAlgorithmName().c_str());
+
+ // Request checksums
+ if (!checksumAlgorithmName.empty())
+ {
+ // For non-streaming payload, the resolved checksum location is always header.
+ // For streaming payload, the resolved checksum location depends on whether it is an unsigned payload, we let AwsAuthSigner decide it.
+ if (checksumAlgorithmName == "crc32")
+ {
+ if (request.IsStreaming())
+ {
+ httpRequest->SetRequestHash("crc32", Aws::MakeShared<Crypto::CRC32>(AWS_CLIENT_LOG_TAG));
+ }
+ else
+ {
+ httpRequest->SetHeaderValue("x-amz-checksum-crc32", HashingUtils::Base64Encode(HashingUtils::CalculateCRC32(*(GetBodyStream(request)))));
+ }
+ }
+ else if (checksumAlgorithmName == "crc32c")
+ {
+ if (request.IsStreaming())
+ {
+ httpRequest->SetRequestHash("crc32c", Aws::MakeShared<Crypto::CRC32C>(AWS_CLIENT_LOG_TAG));
+ }
+ else
+ {
+ httpRequest->SetHeaderValue("x-amz-checksum-crc32c", HashingUtils::Base64Encode(HashingUtils::CalculateCRC32C(*(GetBodyStream(request)))));
+ }
+ }
+ else if (checksumAlgorithmName == "sha256")
+ {
+ if (request.IsStreaming())
+ {
+ httpRequest->SetRequestHash("sha256", Aws::MakeShared<Crypto::Sha256>(AWS_CLIENT_LOG_TAG));
+ }
+ else
+ {
+ httpRequest->SetHeaderValue("x-amz-checksum-sha256", HashingUtils::Base64Encode(HashingUtils::CalculateSHA256(*(GetBodyStream(request)))));
+ }
+ }
+ else if (checksumAlgorithmName == "sha1")
+ {
+ if (request.IsStreaming())
+ {
+ httpRequest->SetRequestHash("sha1", Aws::MakeShared<Crypto::Sha1>(AWS_CLIENT_LOG_TAG));
+ }
+ else
+ {
+ httpRequest->SetHeaderValue("x-amz-checksum-sha1", HashingUtils::Base64Encode(HashingUtils::CalculateSHA1(*(GetBodyStream(request)))));
+ }
+ }
+ else if (checksumAlgorithmName == "md5")
+ {
+ httpRequest->SetHeaderValue(Http::CONTENT_MD5_HEADER, HashingUtils::Base64Encode(HashingUtils::CalculateMD5(*(GetBodyStream(request)))));
+ }
+ else
+ {
+ AWS_LOGSTREAM_WARN(AWS_CLIENT_LOG_TAG, "Checksum algorithm: " << checksumAlgorithmName << "is not supported by SDK.");
+ }
+ }
+
+ // Response checksums
+ if (request.ShouldValidateResponseChecksum())
+ {
+ for (const Aws::String& responseChecksumAlgorithmName : request.GetResponseChecksumAlgorithmNames())
+ {
+ checksumAlgorithmName = Aws::Utils::StringUtils::ToLower(responseChecksumAlgorithmName.c_str());
+
+ if (checksumAlgorithmName == "crc32c")
+ {
+ std::shared_ptr<Aws::Utils::Crypto::CRC32C> crc32c = Aws::MakeShared<Aws::Utils::Crypto::CRC32C>(AWS_CLIENT_LOG_TAG);
+ httpRequest->AddResponseValidationHash("crc32c", crc32c);
+ }
+ else if (checksumAlgorithmName == "crc32")
+ {
+ std::shared_ptr<Aws::Utils::Crypto::CRC32> crc32 = Aws::MakeShared<Aws::Utils::Crypto::CRC32>(AWS_CLIENT_LOG_TAG);
+ httpRequest->AddResponseValidationHash("crc", crc32);
+ }
+ else if (checksumAlgorithmName == "sha1")
+ {
+ std::shared_ptr<Aws::Utils::Crypto::Sha1> sha1 = Aws::MakeShared<Aws::Utils::Crypto::Sha1>(AWS_CLIENT_LOG_TAG);
+ httpRequest->AddResponseValidationHash("sha1", sha1);
+ }
+ else if (checksumAlgorithmName == "sha256")
+ {
+ std::shared_ptr<Aws::Utils::Crypto::Sha256> sha256 = Aws::MakeShared<Aws::Utils::Crypto::Sha256>(AWS_CLIENT_LOG_TAG);
+ httpRequest->AddResponseValidationHash("sha256", sha256);
+ }
+ else
+ {
+ AWS_LOGSTREAM_WARN(AWS_CLIENT_LOG_TAG, "Checksum algorithm: " << checksumAlgorithmName << " is not supported in validating response body yet.");
+ }
+ }
+ }
+}
+
void AWSClient::AddContentBodyToRequest(const std::shared_ptr<Aws::Http::HttpRequest>& httpRequest,
const std::shared_ptr<Aws::IOStream>& body, bool needsContentMd5, bool isChunked) const
{
@@ -610,7 +819,7 @@ void AWSClient::AddContentBodyToRequest(const std::shared_ptr<Aws::Http::HttpReq
//If there is no body, we have a content length of 0
//note: we also used to remove content-type, but S3 actually needs content-type on InitiateMultipartUpload and it isn't
- //forbiden by the spec. If we start getting weird errors related to this, make sure it isn't caused by this removal.
+ //forbidden by the spec. If we start getting weird errors related to this, make sure it isn't caused by this removal.
if (!body)
{
AWS_LOGSTREAM_TRACE(AWS_CLIENT_LOG_TAG, "No content body, content-length headers");
@@ -682,11 +891,11 @@ Aws::String Aws::Client::GetAuthorizationHeader(const Aws::Http::HttpRequest& ht
return authHeader.substr(signaturePosition + strlen(Aws::Auth::SIGNATURE) + 1);
}
-void AWSClient::BuildHttpRequest(const Aws::AmazonWebServiceRequest& request,
- const std::shared_ptr<HttpRequest>& httpRequest) const
+void AWSClient::BuildHttpRequest(const Aws::AmazonWebServiceRequest& request, const std::shared_ptr<HttpRequest>& httpRequest) const
{
- //do headers first since the request likely will set content-length as it's own header.
+ //do headers first since the request likely will set content-length as its own header.
AddHeadersToRequest(httpRequest, request.GetHeaders());
+ AddHeadersToRequest(httpRequest, request.GetAdditionalCustomHeaders());
if (request.IsEventStreamRequest())
{
@@ -694,9 +903,31 @@ void AWSClient::BuildHttpRequest(const Aws::AmazonWebServiceRequest& request,
}
else
{
- AddContentBodyToRequest(httpRequest, request.GetBody(), request.ShouldComputeContentMd5(), request.IsStreaming() && request.IsChunked() && m_httpClient->SupportsChunkedTransferEncoding());
+ //Check if compression is required
+ CompressionAlgorithm selectedCompressionAlgorithm =
+ request.GetSelectedCompressionAlgorithm(m_requestCompressionConfig);
+ if (Aws::Client::CompressionAlgorithm::NONE != selectedCompressionAlgorithm) {
+ Aws::Client::RequestCompression rc;
+ auto compressOutcome = rc.compress(request.GetBody(), selectedCompressionAlgorithm);
+
+ if (compressOutcome.IsSuccess()) {
+ Aws::String compressionAlgorithmId = Aws::Client::GetCompressionAlgorithmId(selectedCompressionAlgorithm);
+ AppendHeaderValueToRequest(httpRequest, CONTENT_ENCODING_HEADER, compressionAlgorithmId);
+ AddContentBodyToRequest(
+ httpRequest, compressOutcome.GetResult(),
+ request.ShouldComputeContentMd5(),
+ request.IsStreaming() && request.IsChunked() &&
+ m_httpClient->SupportsChunkedTransferEncoding());
+ } else {
+ AWS_LOGSTREAM_ERROR(AWS_CLIENT_LOG_TAG, "Failed to compress request, submitting uncompressed");
+ AddContentBodyToRequest(httpRequest, request.GetBody(), request.ShouldComputeContentMd5(), request.IsStreaming() && request.IsChunked() && m_httpClient->SupportsChunkedTransferEncoding());
+ }
+ } else {
+ AddContentBodyToRequest(httpRequest, request.GetBody(), request.ShouldComputeContentMd5(), request.IsStreaming() && request.IsChunked() && m_httpClient->SupportsChunkedTransferEncoding());
+ }
}
+ AddChecksumToRequest(httpRequest, request);
// Pass along handlers for processing data sent/received in bytes
httpRequest->SetDataReceivedEventHandler(request.GetDataReceivedEventHandler());
httpRequest->SetDataSentEventHandler(request.GetDataSentEventHandler());
@@ -710,389 +941,132 @@ void AWSClient::AddCommonHeaders(HttpRequest& httpRequest) const
httpRequest.SetUserAgent(m_userAgent);
}
-Aws::String AWSClient::GeneratePresignedUrl(URI& uri, HttpMethod method, long long expirationInSeconds)
+Aws::String AWSClient::GeneratePresignedUrl(const URI& uri, HttpMethod method, long long expirationInSeconds)
{
- std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
- auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER);
- if (signer->PresignRequest(*request, expirationInSeconds))
- {
- return request->GetURIString();
- }
-
- return {};
-}
-
-Aws::String AWSClient::GeneratePresignedUrl(URI& uri, HttpMethod method, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds)
-{
- std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
- for (const auto& it: customizedHeaders)
- {
- request->SetHeaderValue(it.first.c_str(), it.second);
- }
- auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER);
- if (signer->PresignRequest(*request, expirationInSeconds))
- {
- return request->GetURIString();
- }
-
- return {};
+ return AWSUrlPresigner(*this).GeneratePresignedUrl(uri, method, expirationInSeconds);
}
-Aws::String AWSClient::GeneratePresignedUrl(URI& uri, HttpMethod method, const char* region, long long expirationInSeconds) const
+Aws::String AWSClient::GeneratePresignedUrl(const URI& uri, HttpMethod method, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds)
{
- std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
- auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER);
- if (signer->PresignRequest(*request, region, expirationInSeconds))
- {
- return request->GetURIString();
- }
-
- return {};
+ return AWSUrlPresigner(*this).GeneratePresignedUrl(uri, method, customizedHeaders, expirationInSeconds);
}
-Aws::String AWSClient::GeneratePresignedUrl(URI& uri, HttpMethod method, const char* region, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds)
+Aws::String AWSClient::GeneratePresignedUrl(const URI& uri, HttpMethod method, const char* region, long long expirationInSeconds) const
{
- std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
- for (const auto& it: customizedHeaders)
- {
- request->SetHeaderValue(it.first.c_str(), it.second);
- }
- auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER);
- if (signer->PresignRequest(*request, region, expirationInSeconds))
- {
- return request->GetURIString();
- }
-
- return {};
+ return AWSUrlPresigner(*this).GeneratePresignedUrl(uri, method, region, expirationInSeconds);
}
-Aws::String AWSClient::GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, long long expirationInSeconds) const
+Aws::String AWSClient::GeneratePresignedUrl(const URI& uri, HttpMethod method, const char* region, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds)
{
- std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
- auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER);
- if (signer->PresignRequest(*request, region, serviceName, expirationInSeconds))
- {
- return request->GetURIString();
- }
-
- return {};
+ return AWSUrlPresigner(*this).GeneratePresignedUrl(uri, method, region, customizedHeaders, expirationInSeconds);
}
-Aws::String AWSClient::GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds)
+Aws::String AWSClient::GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, long long expirationInSeconds) const
{
- std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
- for (const auto& it: customizedHeaders)
- {
- request->SetHeaderValue(it.first.c_str(), it.second);
- }
- auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER);
- if (signer->PresignRequest(*request, region, serviceName, expirationInSeconds))
- {
- return request->GetURIString();
- }
-
- return {};
+ return AWSUrlPresigner(*this).GeneratePresignedUrl(uri, method, region, serviceName, expirationInSeconds);
}
-Aws::String AWSClient::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region,
- const Aws::Http::QueryStringParameterCollection& extraParams, long long expirationInSeconds) const
+Aws::String AWSClient::GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds)
{
- std::shared_ptr<HttpRequest> httpRequest =
- ConvertToRequestForPresigning(request, uri, method, extraParams);
- auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER);
- if (signer->PresignRequest(*httpRequest, region, expirationInSeconds))
- {
- return httpRequest->GetURIString();
- }
-
- return {};
+ return AWSUrlPresigner(*this).GeneratePresignedUrl(uri, method, region, serviceName, customizedHeaders, expirationInSeconds);
}
-Aws::String AWSClient::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName,
-const Aws::Http::QueryStringParameterCollection& extraParams, long long expirationInSeconds) const
+Aws::String AWSClient::GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, const char* signerName, long long expirationInSeconds) const
{
- std::shared_ptr<HttpRequest> httpRequest =
- ConvertToRequestForPresigning(request, uri, method, extraParams);
- auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER);
- if (signer->PresignRequest(*httpRequest, region, serviceName, expirationInSeconds))
- {
- return httpRequest->GetURIString();
- }
-
- return {};
+ return AWSUrlPresigner(*this).GeneratePresignedUrl(uri, method, region, serviceName, signerName, expirationInSeconds);
}
-Aws::String AWSClient::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, Aws::Http::HttpMethod method,
- const Aws::Http::QueryStringParameterCollection& extraParams, long long expirationInSeconds) const
+Aws::String AWSClient::GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, const char* signerName, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds)
{
- std::shared_ptr<HttpRequest> httpRequest =
- ConvertToRequestForPresigning(request, uri, method, extraParams);
- auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER);
- if (signer->PresignRequest(*httpRequest, expirationInSeconds))
- {
- return httpRequest->GetURIString();
- }
-
- return {};
+ return AWSUrlPresigner(*this).GeneratePresignedUrl(uri, method, region, serviceName, signerName, customizedHeaders, expirationInSeconds);
}
-std::shared_ptr<Aws::Http::HttpRequest> AWSClient::ConvertToRequestForPresigning(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri,
- Aws::Http::HttpMethod method, const Aws::Http::QueryStringParameterCollection& extraParams) const
+Aws::String AWSClient::GeneratePresignedUrl(const Aws::Endpoint::AWSEndpoint& endpoint,
+ Aws::Http::HttpMethod method /* = Http::HttpMethod::HTTP_POST */,
+ const Aws::Http::HeaderValueCollection& customizedHeaders /* = {} */,
+ uint64_t expirationInSeconds /* = 0 */,
+ const char* signerName /* = Aws::Auth::SIGV4_SIGNER */,
+ const char* signerRegionOverride /* = nullptr */,
+ const char* signerServiceNameOverride /* = nullptr */)
{
- request.PutToPresignedUrl(uri);
- std::shared_ptr<HttpRequest> httpRequest = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
-
- for (auto& param : extraParams)
- {
- httpRequest->AddQueryStringParameter(param.first.c_str(), param.second);
- }
-
- return httpRequest;
+ return AWSUrlPresigner(*this).GeneratePresignedUrl(endpoint, method, customizedHeaders, expirationInSeconds, signerName, signerRegionOverride, signerServiceNameOverride);
}
-std::shared_ptr<Aws::Http::HttpResponse> AWSClient::MakeHttpRequest(std::shared_ptr<Aws::Http::HttpRequest>& request) const
+Aws::String AWSClient::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region,
+ const Aws::Http::QueryStringParameterCollection& extraParams, long long expirationInSeconds) const
{
- return m_httpClient->MakeRequest(request, m_readRateLimiter.get(), m_writeRateLimiter.get());
+ return AWSUrlPresigner(*this).GeneratePresignedUrl(request, uri, method, region, extraParams, expirationInSeconds);
}
-
-////////////////////////////////////////////////////////////////////////////
-AWSJsonClient::AWSJsonClient(const Aws::Client::ClientConfiguration& configuration,
- const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer,
- const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) :
- BASECLASS(configuration, signer, errorMarshaller)
+Aws::String AWSClient::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName,
+ const Aws::Http::QueryStringParameterCollection& extraParams, long long expirationInSeconds) const
{
+ return AWSUrlPresigner(*this).GeneratePresignedUrl(request, uri, method, region, serviceName, extraParams, expirationInSeconds);
}
-AWSJsonClient::AWSJsonClient(const Aws::Client::ClientConfiguration& configuration,
- const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider,
- const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) :
- BASECLASS(configuration, signerProvider, errorMarshaller)
+Aws::String AWSClient::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request,
+ const Aws::Http::URI& uri,
+ Aws::Http::HttpMethod method,
+ const char* region,
+ const char* serviceName,
+ const char* signerName,
+ const Aws::Http::QueryStringParameterCollection& extraParams,
+ long long expirationInSeconds) const
{
+ return AWSUrlPresigner(*this).GeneratePresignedUrl(request, uri, method, region, serviceName, signerName, extraParams, expirationInSeconds);
}
-
-JsonOutcome AWSJsonClient::MakeRequest(const Aws::Http::URI& uri,
- const Aws::AmazonWebServiceRequest& request,
- Http::HttpMethod method,
- const char* signerName,
- const char* signerRegionOverride,
- const char* signerServiceNameOverride) const
+Aws::String AWSClient::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, const Aws::Http::URI& uri, Aws::Http::HttpMethod method,
+ const Aws::Http::QueryStringParameterCollection& extraParams, long long expirationInSeconds) const
{
- HttpResponseOutcome httpOutcome(BASECLASS::AttemptExhaustively(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride));
- if (!httpOutcome.IsSuccess())
- {
- return JsonOutcome(std::move(httpOutcome));
- }
-
- if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0)
- //this is stupid, but gcc doesn't pick up the covariant on the dereference so we have to give it a little hint.
- return JsonOutcome(AmazonWebServiceResult<JsonValue>(JsonValue(httpOutcome.GetResult()->GetResponseBody()),
- httpOutcome.GetResult()->GetHeaders(),
- httpOutcome.GetResult()->GetResponseCode()));
-
- else
- return JsonOutcome(AmazonWebServiceResult<JsonValue>(JsonValue(), httpOutcome.GetResult()->GetHeaders()));
+ return AWSUrlPresigner(*this).GeneratePresignedUrl(request, uri, method, extraParams, expirationInSeconds);
}
-JsonOutcome AWSJsonClient::MakeRequest(const Aws::Http::URI& uri,
- Http::HttpMethod method,
- const char* signerName,
- const char* requestName,
- const char* signerRegionOverride,
- const char* signerServiceNameOverride) const
-{
- HttpResponseOutcome httpOutcome(BASECLASS::AttemptExhaustively(uri, method, signerName, requestName, signerRegionOverride, signerServiceNameOverride));
- if (!httpOutcome.IsSuccess())
- {
- return JsonOutcome(std::move(httpOutcome));
- }
-
- if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0)
- {
- JsonValue jsonValue(httpOutcome.GetResult()->GetResponseBody());
- if (!jsonValue.WasParseSuccessful())
- {
- return JsonOutcome(AWSError<CoreErrors>(CoreErrors::UNKNOWN, "Json Parser Error", jsonValue.GetErrorMessage(), false));
- }
-
- //this is stupid, but gcc doesn't pick up the covariant on the dereference so we have to give it a little hint.
- return JsonOutcome(AmazonWebServiceResult<JsonValue>(std::move(jsonValue),
- httpOutcome.GetResult()->GetHeaders(),
- httpOutcome.GetResult()->GetResponseCode()));
+std::shared_ptr<Aws::IOStream> AWSClient::GetBodyStream(const Aws::AmazonWebServiceRequest& request) const {
+ if (request.GetBody() != nullptr) {
+ return request.GetBody();
}
-
- return JsonOutcome(AmazonWebServiceResult<JsonValue>(JsonValue(), httpOutcome.GetResult()->GetHeaders()));
+ // Return an empty string stream for no body
+ return Aws::MakeShared<Aws::StringStream>(AWS_CLIENT_LOG_TAG, "");
}
-JsonOutcome AWSJsonClient::MakeEventStreamRequest(std::shared_ptr<Aws::Http::HttpRequest>& request) const
+std::shared_ptr<Aws::Http::HttpResponse> AWSClient::MakeHttpRequest(std::shared_ptr<Aws::Http::HttpRequest>& request) const
{
- // request is assumed to be signed
- std::shared_ptr<HttpResponse> httpResponse = MakeHttpRequest(request);
-
- 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 JsonOutcome(std::move(error));
- }
-
- AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Request returned successful response.");
-
- HttpResponseOutcome httpOutcome(std::move(httpResponse));
-
- if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0)
- {
- JsonValue jsonValue(httpOutcome.GetResult()->GetResponseBody());
- if (!jsonValue.WasParseSuccessful())
- {
- return JsonOutcome(AWSError<CoreErrors>(CoreErrors::UNKNOWN, "Json Parser Error", jsonValue.GetErrorMessage(), false));
- }
-
- //this is stupid, but gcc doesn't pick up the covariant on the dereference so we have to give it a little hint.
- return JsonOutcome(AmazonWebServiceResult<JsonValue>(std::move(jsonValue),
- httpOutcome.GetResult()->GetHeaders(),
- httpOutcome.GetResult()->GetResponseCode()));
- }
-
- return JsonOutcome(AmazonWebServiceResult<JsonValue>(JsonValue(), httpOutcome.GetResult()->GetHeaders()));
+ return m_httpClient->MakeRequest(request, m_readRateLimiter.get(), m_writeRateLimiter.get());
}
-AWSError<CoreErrors> AWSJsonClient::BuildAWSError(
- const std::shared_ptr<Aws::Http::HttpResponse>& httpResponse) const
+void AWSClient::AppendRecursionDetectionHeader(std::shared_ptr<Aws::Http::HttpRequest> ioRequest)
{
- AWSError<CoreErrors> error;
- if (httpResponse->HasClientError())
- {
- bool retryable = httpResponse->GetClientErrorType() == CoreErrors::NETWORK_CONNECTION ? true : false;
- error = AWSError<CoreErrors>(httpResponse->GetClientErrorType(), "", httpResponse->GetClientErrorMessage(), retryable);
+ if(!ioRequest || ioRequest->HasHeader(Aws::Http::X_AMZN_TRACE_ID_HEADER)) {
+ return;
}
- else if (!httpResponse->GetResponseBody() || httpResponse->GetResponseBody().tellp() < 1)
- {
- auto responseCode = httpResponse->GetResponseCode();
- auto errorCode = GuessBodylessErrorType(responseCode);
-
- Aws::StringStream ss;
- ss << "No response body.";
- error = AWSError<CoreErrors>(errorCode, "", ss.str(),
- IsRetryableHttpResponseCode(responseCode));
- }
- else
- {
- assert(httpResponse->GetResponseCode() != HttpResponseCode::OK);
- error = GetErrorMarshaller()->Marshall(*httpResponse);
+ Aws::String awsLambdaFunctionName = Aws::Environment::GetEnv(AWS_LAMBDA_FUNCTION_NAME);
+ if(awsLambdaFunctionName.empty()) {
+ return;
}
-
- error.SetResponseHeaders(httpResponse->GetHeaders());
- error.SetResponseCode(httpResponse->GetResponseCode());
- error.SetRemoteHostIpAddress(httpResponse->GetOriginatingRequest().GetResolvedRemoteHost());
- AWS_LOGSTREAM_ERROR(AWS_CLIENT_LOG_TAG, error);
- return error;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-AWSXMLClient::AWSXMLClient(const Aws::Client::ClientConfiguration& configuration,
- const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer,
- const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) :
- BASECLASS(configuration, signer, errorMarshaller)
-{
-}
-
-AWSXMLClient::AWSXMLClient(const Aws::Client::ClientConfiguration& configuration,
- const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider,
- const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) :
- BASECLASS(configuration, signerProvider, errorMarshaller)
-{
-}
-
-XmlOutcome AWSXMLClient::MakeRequest(const Aws::Http::URI& uri,
- const Aws::AmazonWebServiceRequest& request,
- Http::HttpMethod method,
- const char* signerName,
- const char* signerRegionOverride,
- const char* signerServiceNameOverride) const
-{
- HttpResponseOutcome httpOutcome(BASECLASS::AttemptExhaustively(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride));
- if (!httpOutcome.IsSuccess())
- {
- return XmlOutcome(std::move(httpOutcome));
+ Aws::String xAmznTraceIdVal = Aws::Environment::GetEnv(X_AMZN_TRACE_ID);
+ if(xAmznTraceIdVal.empty()) {
+ return;
}
- if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0)
+ // Escape all non-printable ASCII characters by percent encoding
+ Aws::OStringStream xAmznTraceIdValEncodedStr;
+ for(const char ch : xAmznTraceIdVal)
{
- XmlDocument xmlDoc = XmlDocument::CreateFromXmlStream(httpOutcome.GetResult()->GetResponseBody());
-
- if (!xmlDoc.WasParseSuccessful())
+ if (ch >= 0x20 && ch <= 0x7e) // ascii chars [32-126] or [' ' to '~'] are not escaped
{
- AWS_LOGSTREAM_ERROR(AWS_CLIENT_LOG_TAG, "Xml parsing for error failed with message " << xmlDoc.GetErrorMessage().c_str());
- return AWSError<CoreErrors>(CoreErrors::UNKNOWN, "Xml Parse Error", xmlDoc.GetErrorMessage(), false);
+ xAmznTraceIdValEncodedStr << ch;
}
-
- return XmlOutcome(AmazonWebServiceResult<XmlDocument>(std::move(xmlDoc),
- httpOutcome.GetResult()->GetHeaders(), httpOutcome.GetResult()->GetResponseCode()));
- }
-
- return XmlOutcome(AmazonWebServiceResult<XmlDocument>(XmlDocument(), httpOutcome.GetResult()->GetHeaders()));
-}
-
-XmlOutcome AWSXMLClient::MakeRequest(const Aws::Http::URI& uri,
- Http::HttpMethod method,
- const char* signerName,
- const char* requestName,
- const char* signerRegionOverride,
- const char* signerServiceNameOverride) const
-{
- HttpResponseOutcome httpOutcome(BASECLASS::AttemptExhaustively(uri, method, signerName, requestName, signerRegionOverride, signerServiceNameOverride));
- if (!httpOutcome.IsSuccess())
- {
- return XmlOutcome(std::move(httpOutcome));
- }
-
- if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0)
- {
- return XmlOutcome(AmazonWebServiceResult<XmlDocument>(
- XmlDocument::CreateFromXmlStream(httpOutcome.GetResult()->GetResponseBody()),
- httpOutcome.GetResult()->GetHeaders(), httpOutcome.GetResult()->GetResponseCode()));
- }
-
- return XmlOutcome(AmazonWebServiceResult<XmlDocument>(XmlDocument(), httpOutcome.GetResult()->GetHeaders()));
-}
-
-AWSError<CoreErrors> AWSXMLClient::BuildAWSError(const std::shared_ptr<Http::HttpResponse>& httpResponse) const
-{
- AWSError<CoreErrors> error;
- if (httpResponse->HasClientError())
- {
- bool retryable = httpResponse->GetClientErrorType() == CoreErrors::NETWORK_CONNECTION ? true : false;
- error = AWSError<CoreErrors>(httpResponse->GetClientErrorType(), "", httpResponse->GetClientErrorMessage(), retryable);
- }
- else if (!httpResponse->GetResponseBody() || httpResponse->GetResponseBody().tellp() < 1)
- {
- auto responseCode = httpResponse->GetResponseCode();
- auto errorCode = GuessBodylessErrorType(responseCode);
-
- Aws::StringStream ss;
- ss << "No response body.";
- error = AWSError<CoreErrors>(errorCode, "", ss.str(), IsRetryableHttpResponseCode(responseCode));
- }
- else
- {
- assert(httpResponse->GetResponseCode() != HttpResponseCode::OK);
-
- // When trying to build an AWS Error from a response which is an FStream, we need to rewind the
- // file pointer back to the beginning in order to correctly read the input using the XML string iterator
- if ((httpResponse->GetResponseBody().tellp() > 0)
- && (httpResponse->GetResponseBody().tellg() > 0))
+ else
{
- httpResponse->GetResponseBody().seekg(0);
+ // A percent-encoded octet is encoded as a character triplet
+ xAmznTraceIdValEncodedStr << '%' // consisting of the percent character "%"
+ << std::hex << std::setfill('0') << std::setw(2) << std::uppercase
+ << (size_t) ch //followed by the two hexadecimal digits representing that octet's numeric value
+ << std::dec << std::setfill(' ') << std::setw(0) << std::nouppercase;
}
-
- error = GetErrorMarshaller()->Marshall(*httpResponse);
}
+ xAmznTraceIdVal = xAmznTraceIdValEncodedStr.str();
- error.SetResponseHeaders(httpResponse->GetHeaders());
- error.SetResponseCode(httpResponse->GetResponseCode());
- error.SetRemoteHostIpAddress(httpResponse->GetOriginatingRequest().GetResolvedRemoteHost());
- AWS_LOGSTREAM_ERROR(AWS_CLIENT_LOG_TAG, error);
- return error;
+ ioRequest->SetHeaderValue(Aws::Http::X_AMZN_TRACE_ID_HEADER, xAmznTraceIdVal);
}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp
index f5fa676f98..a905dddb5c 100644
--- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp
@@ -23,6 +23,7 @@ AWS_CORE_API extern const char MESSAGE_LOWER_CASE[] = "message";
AWS_CORE_API extern const char MESSAGE_CAMEL_CASE[] = "Message";
AWS_CORE_API extern const char ERROR_TYPE_HEADER[] = "x-amzn-ErrorType";
AWS_CORE_API extern const char REQUEST_ID_HEADER[] = "x-amzn-RequestId";
+AWS_CORE_API extern const char QUERY_ERROR_HEADER[] = "x-amzn-query-error";
AWS_CORE_API extern const char TYPE[] = "__type";
AWSError<CoreErrors> JsonErrorMarshaller::Marshall(const Aws::Http::HttpResponse& httpResponse) const
@@ -50,6 +51,24 @@ AWSError<CoreErrors> JsonErrorMarshaller::Marshall(const Aws::Http::HttpResponse
error = FindErrorByHttpResponseCode(httpResponse.GetResponseCode());
error.SetMessage(message);
}
+
+ if (httpResponse.HasHeader(QUERY_ERROR_HEADER))
+ {
+ auto errorCodeString = httpResponse.GetHeader(QUERY_ERROR_HEADER);
+ auto locationOfSemicolon = errorCodeString.find_first_of(';');
+ Aws::String errorCode;
+
+ if (locationOfSemicolon != Aws::String::npos)
+ {
+ errorCode = errorCodeString.substr(0, locationOfSemicolon);
+ }
+ else
+ {
+ errorCode = errorCodeString;
+ }
+
+ error.SetExceptionName(errorCode);
+ }
}
else
{
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSJsonClient.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSJsonClient.cpp
new file mode 100644
index 0000000000..b3e19d9977
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSJsonClient.cpp
@@ -0,0 +1,212 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/client/AWSJsonClient.h>
+#include <aws/core/AmazonWebServiceRequest.h>
+#include <aws/core/auth/AWSAuthSignerProvider.h>
+#include <aws/core/client/AWSError.h>
+#include <aws/core/client/AWSErrorMarshaller.h>
+#include <aws/core/client/ClientConfiguration.h>
+#include <aws/core/client/CoreErrors.h>
+#include <aws/core/client/RetryStrategy.h>
+#include <aws/core/http/HttpClient.h>
+#include <aws/core/http/HttpResponse.h>
+#include <aws/core/http/URI.h>
+#include <aws/core/utils/json/JsonSerializer.h>
+#include <aws/core/utils/Outcome.h>
+#include <aws/core/utils/xml/XmlSerializer.h>
+#include <aws/core/utils/memory/stl/AWSStringStream.h>
+#include <aws/core/utils/logging/LogMacros.h>
+#include <aws/core/utils/event/EventStream.h>
+#include <aws/core/utils/UUID.h>
+#include <aws/core/monitoring/MonitoringManager.h>
+
+#include <cassert>
+
+
+using namespace Aws;
+using namespace Aws::Client;
+using namespace Aws::Http;
+using namespace Aws::Utils;
+using namespace Aws::Utils::Json;
+
+static const char AWS_JSON_CLIENT_LOG_TAG[] = "AWSJsonClient";
+
+AWSJsonClient::AWSJsonClient(const Aws::Client::ClientConfiguration& configuration,
+ const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer,
+ const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) :
+ BASECLASS(configuration, signer, errorMarshaller)
+{
+}
+
+AWSJsonClient::AWSJsonClient(const Aws::Client::ClientConfiguration& configuration,
+ const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider,
+ const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) :
+ BASECLASS(configuration, signerProvider, errorMarshaller)
+{
+}
+
+JsonOutcome AWSJsonClient::MakeRequest(const Aws::AmazonWebServiceRequest& request,
+ const Aws::Endpoint::AWSEndpoint& endpoint,
+ Http::HttpMethod method /* = Http::HttpMethod::HTTP_POST */,
+ const char* signerName /* = Aws::Auth::NULL_SIGNER */,
+ const char* signerRegionOverride /* = nullptr */,
+ const char* signerServiceNameOverride /* = nullptr */) const
+{
+ const Aws::Http::URI& uri = endpoint.GetURI();
+ if (endpoint.GetAttributes()) {
+ signerName = endpoint.GetAttributes()->authScheme.GetName().c_str();
+ if (endpoint.GetAttributes()->authScheme.GetSigningRegion()) {
+ signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegion()->c_str();
+ }
+ if (endpoint.GetAttributes()->authScheme.GetSigningRegionSet()) {
+ signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegionSet()->c_str();
+ }
+ if (endpoint.GetAttributes()->authScheme.GetSigningName()) {
+ signerServiceNameOverride = endpoint.GetAttributes()->authScheme.GetSigningName()->c_str();
+ }
+ }
+ return MakeRequest(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride);
+}
+
+JsonOutcome AWSJsonClient::MakeRequest(const Aws::Endpoint::AWSEndpoint& endpoint,
+ Http::HttpMethod method /* = Http::HttpMethod::HTTP_POST */,
+ const char* signerName /* = Aws::Auth::NULL_SIGNER */,
+ const char* signerRegionOverride /* = nullptr */,
+ const char* signerServiceNameOverride /* = nullptr */) const
+{
+ const Aws::Http::URI& uri = endpoint.GetURI();
+ if (endpoint.GetAttributes()) {
+ signerName = endpoint.GetAttributes()->authScheme.GetName().c_str();
+ if (endpoint.GetAttributes()->authScheme.GetSigningRegion()) {
+ signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegion()->c_str();
+ }
+ if (endpoint.GetAttributes()->authScheme.GetSigningRegionSet()) {
+ signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegionSet()->c_str();
+ }
+ if (endpoint.GetAttributes()->authScheme.GetSigningName()) {
+ signerServiceNameOverride = endpoint.GetAttributes()->authScheme.GetSigningName()->c_str();
+ }
+ }
+ return MakeRequest(uri, method, signerName, signerRegionOverride, signerServiceNameOverride);
+}
+
+JsonOutcome AWSJsonClient::MakeRequest(const Aws::Http::URI& uri,
+ const Aws::AmazonWebServiceRequest& request,
+ Http::HttpMethod method,
+ const char* signerName,
+ const char* signerRegionOverride,
+ const char* signerServiceNameOverride) const
+{
+ HttpResponseOutcome httpOutcome(BASECLASS::AttemptExhaustively(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride));
+ if (!httpOutcome.IsSuccess())
+ {
+ return JsonOutcome(std::move(httpOutcome));
+ }
+
+ if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0)
+ //this is stupid, but gcc doesn't pick up the covariant on the dereference so we have to give it a little hint.
+ return JsonOutcome(AmazonWebServiceResult<JsonValue>(JsonValue(httpOutcome.GetResult()->GetResponseBody()),
+ httpOutcome.GetResult()->GetHeaders(),
+ httpOutcome.GetResult()->GetResponseCode()));
+
+ else
+ return JsonOutcome(AmazonWebServiceResult<JsonValue>(JsonValue(), httpOutcome.GetResult()->GetHeaders()));
+}
+
+JsonOutcome AWSJsonClient::MakeRequest(const Aws::Http::URI& uri,
+ Http::HttpMethod method,
+ const char* signerName,
+ const char* requestName,
+ const char* signerRegionOverride,
+ const char* signerServiceNameOverride) const
+{
+ HttpResponseOutcome httpOutcome(BASECLASS::AttemptExhaustively(uri, method, signerName, requestName, signerRegionOverride, signerServiceNameOverride));
+ if (!httpOutcome.IsSuccess())
+ {
+ return JsonOutcome(std::move(httpOutcome));
+ }
+
+ if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0)
+ {
+ JsonValue jsonValue(httpOutcome.GetResult()->GetResponseBody());
+ if (!jsonValue.WasParseSuccessful())
+ {
+ return JsonOutcome(AWSError<CoreErrors>(CoreErrors::UNKNOWN, "Json Parser Error", jsonValue.GetErrorMessage(), false));
+ }
+
+ //this is stupid, but gcc doesn't pick up the covariant on the dereference so we have to give it a little hint.
+ return JsonOutcome(AmazonWebServiceResult<JsonValue>(std::move(jsonValue),
+ httpOutcome.GetResult()->GetHeaders(),
+ httpOutcome.GetResult()->GetResponseCode()));
+ }
+
+ return JsonOutcome(AmazonWebServiceResult<JsonValue>(JsonValue(), httpOutcome.GetResult()->GetHeaders()));
+}
+
+JsonOutcome AWSJsonClient::MakeEventStreamRequest(std::shared_ptr<Aws::Http::HttpRequest>& request) const
+{
+ // request is assumed to be signed
+ std::shared_ptr<HttpResponse> httpResponse = MakeHttpRequest(request);
+
+ if (DoesResponseGenerateError(httpResponse))
+ {
+ AWS_LOGSTREAM_DEBUG(AWS_JSON_CLIENT_LOG_TAG, "Request returned error. Attempting to generate appropriate error codes from response");
+ auto error = BuildAWSError(httpResponse);
+ return JsonOutcome(std::move(error));
+ }
+
+ AWS_LOGSTREAM_DEBUG(AWS_JSON_CLIENT_LOG_TAG, "Request returned successful response.");
+
+ HttpResponseOutcome httpOutcome(std::move(httpResponse));
+
+ if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0)
+ {
+ JsonValue jsonValue(httpOutcome.GetResult()->GetResponseBody());
+ if (!jsonValue.WasParseSuccessful())
+ {
+ return JsonOutcome(AWSError<CoreErrors>(CoreErrors::UNKNOWN, "Json Parser Error", jsonValue.GetErrorMessage(), false));
+ }
+
+ //this is stupid, but gcc doesn't pick up the covariant on the dereference so we have to give it a little hint.
+ return JsonOutcome(AmazonWebServiceResult<JsonValue>(std::move(jsonValue),
+ httpOutcome.GetResult()->GetHeaders(),
+ httpOutcome.GetResult()->GetResponseCode()));
+ }
+
+ return JsonOutcome(AmazonWebServiceResult<JsonValue>(JsonValue(), httpOutcome.GetResult()->GetHeaders()));
+}
+
+AWSError<CoreErrors> AWSJsonClient::BuildAWSError(
+ const std::shared_ptr<Aws::Http::HttpResponse>& httpResponse) const
+{
+ AWSError<CoreErrors> error;
+ if (httpResponse->HasClientError())
+ {
+ bool retryable = httpResponse->GetClientErrorType() == CoreErrors::NETWORK_CONNECTION ? true : false;
+ error = AWSError<CoreErrors>(httpResponse->GetClientErrorType(), "", httpResponse->GetClientErrorMessage(), retryable);
+ }
+ else if (!httpResponse->GetResponseBody() || httpResponse->GetResponseBody().tellp() < 1)
+ {
+ auto responseCode = httpResponse->GetResponseCode();
+ auto errorCode = AWSClient::GuessBodylessErrorType(responseCode);
+
+ Aws::StringStream ss;
+ ss << "No response body.";
+ error = AWSError<CoreErrors>(errorCode, "", ss.str(),
+ IsRetryableHttpResponseCode(responseCode));
+ }
+ else
+ {
+ assert(httpResponse->GetResponseCode() != HttpResponseCode::OK);
+ error = GetErrorMarshaller()->Marshall(*httpResponse);
+ }
+
+ error.SetResponseHeaders(httpResponse->GetHeaders());
+ error.SetResponseCode(httpResponse->GetResponseCode());
+ error.SetRemoteHostIpAddress(httpResponse->GetOriginatingRequest().GetResolvedRemoteHost());
+ AWS_LOGSTREAM_ERROR(AWS_JSON_CLIENT_LOG_TAG, error);
+ return error;
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSUrlPresigner.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSUrlPresigner.cpp
new file mode 100644
index 0000000000..a0bc808838
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSUrlPresigner.cpp
@@ -0,0 +1,236 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/client/AWSUrlPresigner.h>
+#include <aws/core/client/AWSClient.h>
+#include <aws/core/http/HttpClientFactory.h>
+
+namespace Aws
+{
+namespace Client
+{
+
+using HttpRequest = Http::HttpRequest;
+using HttpMethod = Http::HttpMethod;
+using URI = Http::URI;
+
+
+AWSUrlPresigner::AWSUrlPresigner(const AWSClient& client)
+ : m_awsClient(client)
+{}
+
+
+Aws::Client::AWSAuthSigner* AWSUrlPresigner::GetSignerByName(const char* name) const
+{
+ return m_awsClient.GetSignerByName(name);
+}
+
+std::shared_ptr<Aws::Http::HttpRequest>
+ConvertToRequestForPresigning(const Aws::AmazonWebServiceRequest& request,
+ const Aws::Http::URI& uri,
+ Aws::Http::HttpMethod method,
+ const Aws::Http::QueryStringParameterCollection& extraParams)
+{
+ Aws::Http::URI uriCopy = uri;
+ request.PutToPresignedUrl(uriCopy);
+ std::shared_ptr<HttpRequest> httpRequest = CreateHttpRequest(uriCopy, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
+
+ for (auto& param : extraParams)
+ {
+ httpRequest->AddQueryStringParameter(param.first.c_str(), param.second);
+ }
+
+ return httpRequest;
+}
+
+Aws::String AWSUrlPresigner::GeneratePresignedUrl(const URI& uri,
+ HttpMethod method,
+ long long expirationInSeconds) const
+{
+ const char* regionOverride = nullptr;
+ const char* serviceNameOverride = nullptr;
+ const char* signerName = Aws::Auth::SIGV4_SIGNER;
+ return GeneratePresignedUrl(uri, method, regionOverride, serviceNameOverride, signerName, expirationInSeconds);
+}
+
+Aws::String AWSUrlPresigner::GeneratePresignedUrl(const URI& uri,
+ HttpMethod method,
+ const Aws::Http::HeaderValueCollection& customizedHeaders,
+ long long expirationInSeconds) const
+{
+ const char* regionOverride = nullptr;
+ const char* serviceNameOverride = nullptr;
+ const char* signerName = Aws::Auth::SIGV4_SIGNER;
+ return GeneratePresignedUrl(uri, method, regionOverride, serviceNameOverride, signerName, customizedHeaders, expirationInSeconds);
+}
+
+Aws::String AWSUrlPresigner::GeneratePresignedUrl(const URI& uri,
+ HttpMethod method,
+ const char* regionOverride,
+ long long expirationInSeconds) const
+{
+ const char* serviceNameOverride = nullptr;
+ const char* signerName = Aws::Auth::SIGV4_SIGNER;
+ return GeneratePresignedUrl(uri, method, regionOverride, serviceNameOverride, signerName, expirationInSeconds);
+}
+
+Aws::String AWSUrlPresigner::GeneratePresignedUrl(const URI& uri,
+ HttpMethod method,
+ const char* regionOverride,
+ const Aws::Http::HeaderValueCollection& customizedHeaders,
+ long long expirationInSeconds) const
+{
+ const char* serviceNameOverride = nullptr;
+ const char* signerName = Aws::Auth::SIGV4_SIGNER;
+ return GeneratePresignedUrl(uri, method, regionOverride, serviceNameOverride, signerName, customizedHeaders, expirationInSeconds);
+}
+
+Aws::String AWSUrlPresigner::GeneratePresignedUrl(const Aws::Http::URI& uri,
+ Aws::Http::HttpMethod method,
+ const char* regionOverride,
+ const char* serviceNameOverride,
+ long long expirationInSeconds) const
+{
+ const char* signerName = Aws::Auth::SIGV4_SIGNER;
+ return GeneratePresignedUrl(uri, method, regionOverride, serviceNameOverride, signerName, expirationInSeconds);
+}
+
+Aws::String AWSUrlPresigner::GeneratePresignedUrl(const Aws::Http::URI& uri,
+ Aws::Http::HttpMethod method,
+ const char* regionOverride,
+ const char* serviceNameOverride,
+ const Aws::Http::HeaderValueCollection& customizedHeaders,
+ long long expirationInSeconds) const
+{
+ const char* signerName = Aws::Auth::SIGV4_SIGNER;
+ return GeneratePresignedUrl(uri, method, regionOverride, serviceNameOverride, signerName, customizedHeaders, expirationInSeconds);
+}
+
+Aws::String AWSUrlPresigner::GeneratePresignedUrl(const Aws::Http::URI& uri,
+ Aws::Http::HttpMethod method,
+ const char* regionOverride,
+ const char* serviceNameOverride,
+ const char* signerName,
+ long long expirationInSeconds) const
+{
+ const Aws::Http::HeaderValueCollection& customizedHeaders = {};
+ return GeneratePresignedUrl(uri, method, regionOverride, serviceNameOverride, signerName, customizedHeaders, expirationInSeconds);
+}
+
+Aws::String AWSUrlPresigner::GeneratePresignedUrl(const Aws::Http::URI& uri,
+ Aws::Http::HttpMethod method,
+ const char* region,
+ const char* serviceName,
+ const char* signerName,
+ const Aws::Http::HeaderValueCollection& customizedHeaders,
+ long long expirationInSeconds) const
+{
+ /* a real method implementation */
+ if (!signerName) {
+ signerName = Aws::Auth::SIGV4_SIGNER;
+ }
+ std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
+ for (const auto& it: customizedHeaders)
+ {
+ request->SetHeaderValue(it.first.c_str(), it.second);
+ }
+ auto signer = GetSignerByName(signerName);
+ if (signer->PresignRequest(*request, region, serviceName, expirationInSeconds))
+ {
+ return request->GetURIString();
+ }
+
+ return {};
+}
+
+Aws::String AWSUrlPresigner::GeneratePresignedUrl(const Aws::Endpoint::AWSEndpoint& endpoint,
+ Aws::Http::HttpMethod method /* = Http::HttpMethod::HTTP_POST */,
+ const Aws::Http::HeaderValueCollection& customizedHeaders /* = {} */,
+ uint64_t expirationInSeconds /* = 0 */,
+ const char* signerName /* = Aws::Auth::SIGV4_SIGNER */,
+ const char* signerRegionOverride /* = nullptr */,
+ const char* signerServiceNameOverride /* = nullptr */) const
+{
+ const Aws::Http::URI& uri = endpoint.GetURI();
+ if (endpoint.GetAttributes()) {
+ signerName = endpoint.GetAttributes()->authScheme.GetName().c_str();
+ if (endpoint.GetAttributes()->authScheme.GetSigningRegion()) {
+ signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegion()->c_str();
+ }
+ if (endpoint.GetAttributes()->authScheme.GetSigningRegionSet()) {
+ signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegionSet()->c_str();
+ }
+ if (endpoint.GetAttributes()->authScheme.GetSigningName()) {
+ signerServiceNameOverride = endpoint.GetAttributes()->authScheme.GetSigningName()->c_str();
+ }
+ }
+
+ return GeneratePresignedUrl(uri, method, signerRegionOverride, signerServiceNameOverride, signerName, customizedHeaders, expirationInSeconds);
+}
+
+Aws::String AWSUrlPresigner::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request,
+ const Aws::Http::URI& uri,
+ Aws::Http::HttpMethod method,
+ const char* regionOverride,
+ const Aws::Http::QueryStringParameterCollection& extraParams,
+ long long expirationInSeconds) const
+{
+ const char* serviceNameOverride = nullptr;
+ const char* signerName = Aws::Auth::SIGV4_SIGNER;
+
+ return GeneratePresignedUrl(request, uri, method, regionOverride, serviceNameOverride, signerName, extraParams, expirationInSeconds);
+}
+
+Aws::String AWSUrlPresigner::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request,
+ const Aws::Http::URI& uri,
+ Aws::Http::HttpMethod method,
+ const char* regionOverride,
+ const char* serviceNameOverride,
+ const char* signerName,
+ const Aws::Http::QueryStringParameterCollection& extraParams,
+ long long expirationInSeconds) const
+{
+ /* a real method implementation */
+ if (!signerName) {
+ signerName = Aws::Auth::SIGV4_SIGNER;
+ }
+ std::shared_ptr<HttpRequest> httpRequest =
+ ConvertToRequestForPresigning(request, uri, method, extraParams);
+ auto signer = GetSignerByName(signerName);
+ if (signer->PresignRequest(*httpRequest, regionOverride, serviceNameOverride, expirationInSeconds))
+ {
+ return httpRequest->GetURIString();
+ }
+
+ return {};
+}
+
+Aws::String AWSUrlPresigner::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request,
+ const Aws::Http::URI& uri,
+ Aws::Http::HttpMethod method,
+ const char* regionOverride,
+ const char* serviceNameOverride,
+ const Aws::Http::QueryStringParameterCollection& extraParams,
+ long long expirationInSeconds) const
+{
+ const char* signerName = Aws::Auth::SIGV4_SIGNER;
+ return GeneratePresignedUrl(request, uri, method, regionOverride, serviceNameOverride, signerName, extraParams, expirationInSeconds);
+}
+
+Aws::String AWSUrlPresigner::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request,
+ const Aws::Http::URI& uri,
+ Aws::Http::HttpMethod method,
+ const Aws::Http::QueryStringParameterCollection& extraParams,
+ long long expirationInSeconds) const
+{
+ const char* regionOverride = nullptr;
+ const char* serviceNameOverride = nullptr;
+ const char* signerName = Aws::Auth::SIGV4_SIGNER;
+
+ return GeneratePresignedUrl(request, uri, method, regionOverride, serviceNameOverride, signerName, extraParams, expirationInSeconds);
+}
+
+} // namespace Client
+} // namespace Aws \ No newline at end of file
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSXmlClient.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSXmlClient.cpp
new file mode 100644
index 0000000000..129595b917
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSXmlClient.cpp
@@ -0,0 +1,180 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/client/AWSXmlClient.h>
+#include <aws/core/AmazonWebServiceRequest.h>
+#include <aws/core/auth/AWSAuthSignerProvider.h>
+#include <aws/core/client/AWSError.h>
+#include <aws/core/client/AWSErrorMarshaller.h>
+#include <aws/core/client/ClientConfiguration.h>
+#include <aws/core/client/CoreErrors.h>
+#include <aws/core/client/RetryStrategy.h>
+#include <aws/core/http/HttpClient.h>
+#include <aws/core/http/HttpResponse.h>
+#include <aws/core/http/URI.h>
+#include <aws/core/utils/Outcome.h>
+#include <aws/core/utils/xml/XmlSerializer.h>
+#include <aws/core/utils/memory/stl/AWSStringStream.h>
+#include <aws/core/utils/logging/LogMacros.h>
+#include <aws/core/utils/event/EventStream.h>
+#include <aws/core/utils/UUID.h>
+
+using namespace Aws;
+using namespace Aws::Client;
+using namespace Aws::Http;
+using namespace Aws::Utils;
+using namespace Aws::Utils::Xml;
+
+static const char AWS_XML_CLIENT_LOG_TAG[] = "AWSXmlClient";
+
+AWSXMLClient::AWSXMLClient(const Aws::Client::ClientConfiguration& configuration,
+ const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer,
+ const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) :
+ BASECLASS(configuration, signer, errorMarshaller)
+{
+}
+
+AWSXMLClient::AWSXMLClient(const Aws::Client::ClientConfiguration& configuration,
+ const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider,
+ const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) :
+ BASECLASS(configuration, signerProvider, errorMarshaller)
+{
+}
+
+XmlOutcome AWSXMLClient::MakeRequest(const Aws::AmazonWebServiceRequest& request,
+ const Aws::Endpoint::AWSEndpoint& endpoint,
+ Http::HttpMethod method /* = Http::HttpMethod::HTTP_POST */,
+ const char* signerName /* = Aws::Auth::NULL_SIGNER */,
+ const char* signerRegionOverride /* = nullptr */,
+ const char* signerServiceNameOverride /* = nullptr */) const
+{
+ const Aws::Http::URI& uri = endpoint.GetURI();
+ if (endpoint.GetAttributes()) {
+ signerName = endpoint.GetAttributes()->authScheme.GetName().c_str();
+ if (endpoint.GetAttributes()->authScheme.GetSigningRegion()) {
+ signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegion()->c_str();
+ }
+ if (endpoint.GetAttributes()->authScheme.GetSigningRegionSet()) {
+ signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegionSet()->c_str();
+ }
+ if (endpoint.GetAttributes()->authScheme.GetSigningName()) {
+ signerServiceNameOverride = endpoint.GetAttributes()->authScheme.GetSigningName()->c_str();
+ }
+ }
+ return MakeRequest(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride);
+}
+
+XmlOutcome AWSXMLClient::MakeRequest(const Aws::Endpoint::AWSEndpoint& endpoint,
+ const char* requestName /* = "" */,
+ Http::HttpMethod method /* = Http::HttpMethod::HTTP_POST */,
+ const char* signerName /* = Aws::Auth::NULL_SIGNER */,
+ const char* signerRegionOverride /* = nullptr */,
+ const char* signerServiceNameOverride /* = nullptr */) const
+{
+ const Aws::Http::URI& uri = endpoint.GetURI();
+ if (endpoint.GetAttributes()) {
+ signerName = endpoint.GetAttributes()->authScheme.GetName().c_str();
+ if (endpoint.GetAttributes()->authScheme.GetSigningRegion()) {
+ signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegion()->c_str();
+ }
+ if (endpoint.GetAttributes()->authScheme.GetSigningRegionSet()) {
+ signerRegionOverride = endpoint.GetAttributes()->authScheme.GetSigningRegionSet()->c_str();
+ }
+ if (endpoint.GetAttributes()->authScheme.GetSigningName()) {
+ signerServiceNameOverride = endpoint.GetAttributes()->authScheme.GetSigningName()->c_str();
+ }
+ }
+ return MakeRequest(uri, method, signerName, requestName, signerRegionOverride, signerServiceNameOverride);
+}
+
+XmlOutcome AWSXMLClient::MakeRequest(const Aws::Http::URI& uri,
+ const Aws::AmazonWebServiceRequest& request,
+ Http::HttpMethod method,
+ const char* signerName,
+ const char* signerRegionOverride,
+ const char* signerServiceNameOverride) const
+{
+ HttpResponseOutcome httpOutcome(BASECLASS::AttemptExhaustively(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride));
+ if (!httpOutcome.IsSuccess())
+ {
+ return XmlOutcome(std::move(httpOutcome));
+ }
+
+ if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0)
+ {
+ XmlDocument xmlDoc = XmlDocument::CreateFromXmlStream(httpOutcome.GetResult()->GetResponseBody());
+
+ if (!xmlDoc.WasParseSuccessful())
+ {
+ AWS_LOGSTREAM_ERROR(AWS_XML_CLIENT_LOG_TAG, "Xml parsing for error failed with message " << xmlDoc.GetErrorMessage().c_str());
+ return AWSError<CoreErrors>(CoreErrors::UNKNOWN, "Xml Parse Error", xmlDoc.GetErrorMessage(), false);
+ }
+
+ return XmlOutcome(AmazonWebServiceResult<XmlDocument>(std::move(xmlDoc),
+ httpOutcome.GetResult()->GetHeaders(), httpOutcome.GetResult()->GetResponseCode()));
+ }
+
+ return XmlOutcome(AmazonWebServiceResult<XmlDocument>(XmlDocument(), httpOutcome.GetResult()->GetHeaders()));
+}
+
+XmlOutcome AWSXMLClient::MakeRequest(const Aws::Http::URI& uri,
+ Http::HttpMethod method,
+ const char* signerName,
+ const char* requestName,
+ const char* signerRegionOverride,
+ const char* signerServiceNameOverride) const
+{
+ HttpResponseOutcome httpOutcome(BASECLASS::AttemptExhaustively(uri, method, signerName, requestName, signerRegionOverride, signerServiceNameOverride));
+ if (!httpOutcome.IsSuccess())
+ {
+ return XmlOutcome(std::move(httpOutcome));
+ }
+
+ if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0)
+ {
+ return XmlOutcome(AmazonWebServiceResult<XmlDocument>(
+ XmlDocument::CreateFromXmlStream(httpOutcome.GetResult()->GetResponseBody()),
+ httpOutcome.GetResult()->GetHeaders(), httpOutcome.GetResult()->GetResponseCode()));
+ }
+
+ return XmlOutcome(AmazonWebServiceResult<XmlDocument>(XmlDocument(), httpOutcome.GetResult()->GetHeaders()));
+}
+
+AWSError<CoreErrors> AWSXMLClient::BuildAWSError(const std::shared_ptr<Http::HttpResponse>& httpResponse) const
+{
+ AWSError<CoreErrors> error;
+ if (httpResponse->HasClientError())
+ {
+ bool retryable = httpResponse->GetClientErrorType() == CoreErrors::NETWORK_CONNECTION ? true : false;
+ error = AWSError<CoreErrors>(httpResponse->GetClientErrorType(), "", httpResponse->GetClientErrorMessage(), retryable);
+ }
+ else if (!httpResponse->GetResponseBody() || httpResponse->GetResponseBody().tellp() < 1)
+ {
+ auto responseCode = httpResponse->GetResponseCode();
+ auto errorCode = AWSClient::GuessBodylessErrorType(responseCode);
+
+ Aws::StringStream ss;
+ ss << "No response body.";
+ error = AWSError<CoreErrors>(errorCode, "", ss.str(), IsRetryableHttpResponseCode(responseCode));
+ }
+ else
+ {
+ // When trying to build an AWS Error from a response which is an FStream, we need to rewind the
+ // file pointer back to the beginning in order to correctly read the input using the XML string iterator
+ if ((httpResponse->GetResponseBody().tellp() > 0)
+ && (httpResponse->GetResponseBody().tellg() > 0))
+ {
+ httpResponse->GetResponseBody().seekg(0);
+ }
+
+ error = GetErrorMarshaller()->Marshall(*httpResponse);
+ }
+
+ error.SetResponseHeaders(httpResponse->GetHeaders());
+ error.SetResponseCode(httpResponse->GetResponseCode());
+ error.SetRemoteHostIpAddress(httpResponse->GetOriginatingRequest().GetResolvedRemoteHost());
+ AWS_LOGSTREAM_ERROR(AWS_XML_CLIENT_LOG_TAG, error);
+ return error;
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AdaptiveRetryStrategy.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AdaptiveRetryStrategy.cpp
new file mode 100644
index 0000000000..0907b81137
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AdaptiveRetryStrategy.cpp
@@ -0,0 +1,228 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/client/AdaptiveRetryStrategy.h>
+
+#include <aws/core/client/AWSError.h>
+#include <aws/core/client/CoreErrors.h>
+#include <aws/core/utils/memory/stl/AWSSet.h>
+
+#include <cmath>
+#include <thread>
+
+using namespace Aws::Utils::Threading;
+
+namespace Aws
+{
+ namespace Client
+ {
+ static const double MIN_FILL_RATE = 0.5;
+ static const double MIN_CAPACITY = 1;
+
+ static const double SMOOTH = 0.8;
+ static const double BETA = 0.7;
+ static const double SCALE_CONSTANT = 0.4;
+
+ // A static list containing all service exception names classified as throttled.
+ static const char* THROTTLING_EXCEPTIONS[] {
+ "Throttling", "ThrottlingException", "ThrottledException", "RequestThrottledException",
+ "TooManyRequestsException", "ProvisionedThroughputExceededException", "TransactionInProgressException",
+ "RequestLimitExceeded", "BandwidthLimitExceeded", "LimitExceededException", "RequestThrottled",
+ "SlowDown", "PriorRequestNotComplete", "EC2ThrottledException"};
+ static const size_t THROTTLING_EXCEPTIONS_SZ = sizeof(THROTTLING_EXCEPTIONS) / sizeof(THROTTLING_EXCEPTIONS[0]);
+
+
+ // C-tor for unit testing
+ RetryTokenBucket::RetryTokenBucket(double fillRate, double maxCapacity, double currentCapacity,
+ const Aws::Utils::DateTime& lastTimestamp, double measuredTxRate, double lastTxRateBucket,
+ size_t requestCount, bool enabled, double lastMaxRate, const Aws::Utils::DateTime& lastThrottleTime)
+ :
+ m_fillRate(fillRate), m_maxCapacity(maxCapacity), m_currentCapacity(currentCapacity),
+ m_lastTimestamp(lastTimestamp), m_measuredTxRate(measuredTxRate),
+ m_lastTxRateBucket(lastTxRateBucket), m_requestCount(requestCount), m_enabled(enabled),
+ m_lastMaxRate(lastMaxRate), m_lastThrottleTime(lastThrottleTime)
+ {}
+
+ bool RetryTokenBucket::Acquire(size_t amount, bool fastFail)
+ {
+ std::lock_guard<std::recursive_mutex> locker(m_mutex);
+ if (!m_enabled)
+ {
+ return true;
+ }
+ Refill();
+ bool notEnough = amount > m_currentCapacity;
+ if (notEnough && fastFail) {
+ return false;
+ }
+ // If all the tokens couldn't be acquired immediately, wait enough
+ // time to fill the remainder.
+ if (notEnough) {
+ std::chrono::duration<double> waitTime((amount - m_currentCapacity) / m_fillRate);
+ std::this_thread::sleep_for(waitTime);
+ Refill();
+ }
+ m_currentCapacity -= amount;
+ return true;
+ }
+
+ void RetryTokenBucket::Refill(const Aws::Utils::DateTime& now)
+ {
+ std::lock_guard<std::recursive_mutex> locker(m_mutex);
+
+ if (0 == m_lastTimestamp.Millis()) {
+ m_lastTimestamp = now;
+ return;
+ }
+
+ double fillAmount = (std::abs(now.Millis() - m_lastTimestamp.Millis()))/1000.0 * m_fillRate;
+ m_currentCapacity = (std::min)(m_maxCapacity, m_currentCapacity + fillAmount);
+ m_lastTimestamp = now;
+ }
+
+ void RetryTokenBucket::UpdateRate(double newRps, const Aws::Utils::DateTime& now)
+ {
+ std::lock_guard<std::recursive_mutex> locker(m_mutex);
+
+ Refill(now);
+ m_fillRate = (std::max)(newRps, MIN_FILL_RATE);
+ m_maxCapacity = (std::max)(newRps, MIN_CAPACITY);
+ m_currentCapacity = (std::min)(m_currentCapacity, m_maxCapacity);
+ }
+
+ void RetryTokenBucket::UpdateMeasuredRate(const Aws::Utils::DateTime& now)
+ {
+ std::lock_guard<std::recursive_mutex> locker(m_mutex);
+
+ double t = now.Millis() / 1000.0;
+ double timeBucket = floor(t * 2.0) / 2.0;
+ m_requestCount += 1;
+ if (timeBucket > m_lastTxRateBucket) {
+ double currentRate = m_requestCount / (timeBucket - m_lastTxRateBucket);
+ m_measuredTxRate = (currentRate * SMOOTH) + (m_measuredTxRate * (1 - SMOOTH));
+ m_requestCount = 0;
+ m_lastTxRateBucket = timeBucket;
+ }
+ }
+
+ void RetryTokenBucket::UpdateClientSendingRate(bool isThrottlingResponse, const Aws::Utils::DateTime& now)
+ {
+ std::lock_guard<std::recursive_mutex> locker(m_mutex);
+
+ UpdateMeasuredRate(now);
+
+ double calculatedRate = 0.0;
+ if (isThrottlingResponse)
+ {
+ double rateToUse = m_measuredTxRate;
+ if (m_enabled)
+ rateToUse = (std::min)(rateToUse, m_fillRate);
+
+ m_lastMaxRate = rateToUse;
+ m_lastThrottleTime = now;
+
+ calculatedRate = CUBICThrottle(rateToUse);
+ Enable();
+ }
+ else
+ {
+ double timeWindow = CalculateTimeWindow();
+ calculatedRate = CUBICSuccess(now, timeWindow);
+ }
+
+ double newRate = (std::min)(calculatedRate, 2.0 * m_measuredTxRate);
+ UpdateRate(newRate, now);
+ }
+
+ void RetryTokenBucket::Enable()
+ {
+ std::lock_guard<std::recursive_mutex> locker(m_mutex);
+ m_enabled = true;
+ }
+
+ double RetryTokenBucket::CalculateTimeWindow() const
+ {
+ return pow(((m_lastMaxRate * (1.0 - BETA)) / SCALE_CONSTANT), (1.0 / 3));
+ }
+
+ double RetryTokenBucket::CUBICSuccess(const Aws::Utils::DateTime& timestamp, const double timeWindow) const
+ {
+ double dt = (timestamp.Millis() - m_lastThrottleTime.Millis()) / 1000.0;
+ double calculatedRate = SCALE_CONSTANT * pow(dt - timeWindow, 3.0) + m_lastMaxRate;
+ return calculatedRate;
+ }
+
+ double RetryTokenBucket::CUBICThrottle(const double rateToUse) const
+ {
+ double calculatedRate = rateToUse * BETA;
+ return calculatedRate;
+ }
+
+
+ AdaptiveRetryStrategy::AdaptiveRetryStrategy(long maxAttempts) :
+ StandardRetryStrategy(maxAttempts)
+ {}
+
+ AdaptiveRetryStrategy::AdaptiveRetryStrategy(std::shared_ptr<RetryQuotaContainer> retryQuotaContainer, long maxAttempts) :
+ StandardRetryStrategy(retryQuotaContainer, maxAttempts)
+ {}
+
+ bool AdaptiveRetryStrategy::HasSendToken()
+ {
+ return m_retryTokenBucket.Acquire(1, m_fastFail);
+ }
+
+ void AdaptiveRetryStrategy::RequestBookkeeping(const HttpResponseOutcome& httpResponseOutcome)
+ {
+ if (httpResponseOutcome.IsSuccess())
+ {
+ m_retryQuotaContainer->ReleaseRetryQuota(Aws::Client::NO_RETRY_INCREMENT);
+ m_retryTokenBucket.UpdateClientSendingRate(false);
+ }
+ else
+ {
+ m_retryTokenBucket.UpdateClientSendingRate(IsThrottlingResponse(httpResponseOutcome));
+ }
+ }
+
+ void AdaptiveRetryStrategy::RequestBookkeeping(const HttpResponseOutcome& httpResponseOutcome, const AWSError<CoreErrors>& lastError)
+ {
+ if (httpResponseOutcome.IsSuccess())
+ {
+ m_retryQuotaContainer->ReleaseRetryQuota(lastError);
+ m_retryTokenBucket.UpdateClientSendingRate(false);
+ }
+ else
+ {
+ m_retryTokenBucket.UpdateClientSendingRate(IsThrottlingResponse(httpResponseOutcome));
+ }
+ }
+
+ bool AdaptiveRetryStrategy::IsThrottlingResponse(const HttpResponseOutcome& httpResponseOutcome)
+ {
+ if(httpResponseOutcome.IsSuccess())
+ return false;
+
+ const AWSError<CoreErrors>& error = httpResponseOutcome.GetError();
+ const Aws::Client::CoreErrors enumValue = error.GetErrorType();
+ switch(enumValue)
+ {
+ case Aws::Client::CoreErrors::THROTTLING:
+ case Aws::Client::CoreErrors::SLOW_DOWN:
+ return true;
+ default:
+ break;
+ }
+
+ if(std::find(THROTTLING_EXCEPTIONS,
+ THROTTLING_EXCEPTIONS + THROTTLING_EXCEPTIONS_SZ, error.GetExceptionName()) != THROTTLING_EXCEPTIONS + THROTTLING_EXCEPTIONS_SZ)
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/ClientConfiguration.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/ClientConfiguration.cpp
index e517379a77..647c6e3f49 100644
--- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/ClientConfiguration.cpp
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/ClientConfiguration.cpp
@@ -4,8 +4,10 @@
*/
#include <aws/core/client/ClientConfiguration.h>
+#include <aws/core/config/defaults/ClientConfigurationDefaults.h>
#include <aws/core/auth/AWSCredentialsProvider.h>
#include <aws/core/client/DefaultRetryStrategy.h>
+#include <aws/core/client/AdaptiveRetryStrategy.h>
#include <aws/core/platform/Environment.h>
#include <aws/core/platform/OSVersionInfo.h>
#include <aws/core/utils/memory/AWSMemory.h>
@@ -26,43 +28,217 @@ namespace Client
{
static const char* CLIENT_CONFIG_TAG = "ClientConfiguration";
+static const char* USE_REQUEST_COMPRESSION_ENV_VAR = "USE_REQUEST_COMPRESSION";
+static const char* USE_REQUEST_COMPRESSION_CONFIG_VAR = "use_request_compression";
+static const char* REQUEST_MIN_COMPRESSION_SIZE_BYTES_ENV_VAR = "REQUEST_MIN_COMPRESSION_SIZE_BYTES";
+static const char* REQUEST_MIN_COMPRESSION_SIZE_BYTES_CONFIG_VAR = "request_min_compression_size_bytes";
-AWS_CORE_API Aws::String ComputeUserAgentString()
+Aws::String ComputeUserAgentString()
{
Aws::StringStream ss;
- ss << "aws-sdk-cpp/" << Version::GetVersionString() << " " << Aws::OSVersionInfo::ComputeOSVersionString()
- << " " << Version::GetCompilerVersionString();
+ ss << "aws-sdk-cpp/" << Version::GetVersionString() << " "
+#if defined(AWS_USER_AGENT_CUSTOMIZATION)
+#define XSTR(V) STR(V)
+#define STR(V) #V
+ << XSTR(AWS_USER_AGENT_CUSTOMIZATION) << " "
+#undef STR
+#undef XSTR
+#endif
+ << Aws::OSVersionInfo::ComputeOSVersionString() << " "
+ << Version::GetCompilerVersionString();
return ss.str();
}
-ClientConfiguration::ClientConfiguration() :
- scheme(Aws::Http::Scheme::HTTPS),
- useDualStack(false),
- maxConnections(25),
- httpRequestTimeoutMs(0),
- requestTimeoutMs(3000),
- connectTimeoutMs(1000),
- enableTcpKeepAlive(true),
- tcpKeepAliveIntervalMs(30000),
- lowSpeedLimit(1),
- proxyScheme(Aws::Http::Scheme::HTTP),
- proxyPort(0),
- executor(Aws::MakeShared<Aws::Utils::Threading::DefaultExecutor>(CLIENT_CONFIG_TAG)),
- verifySSL(true),
- writeRateLimiter(nullptr),
- readRateLimiter(nullptr),
- httpLibOverride(Aws::Http::TransferLibType::DEFAULT_CLIENT),
- followRedirects(FollowRedirectsPolicy::DEFAULT),
- disableExpectHeader(false),
- enableClockSkewAdjustment(true),
- enableHostPrefixInjection(true),
- enableEndpointDiscovery(false),
- profileName(Aws::Auth::GetConfigProfileName())
+void setLegacyClientConfigurationParameters(ClientConfiguration& clientConfig)
{
- AWS_LOGSTREAM_DEBUG(CLIENT_CONFIG_TAG, "ClientConfiguration will use SDK Auto Resolved profile: [" << profileName << "] if not specified by users.");
+ clientConfig.scheme = Aws::Http::Scheme::HTTPS;
+ clientConfig.useDualStack = false;
+ clientConfig.useFIPS = false;
+ clientConfig.maxConnections = 25;
+ clientConfig.httpRequestTimeoutMs = 0;
+ clientConfig.requestTimeoutMs = 3000;
+ clientConfig.connectTimeoutMs = 1000;
+ clientConfig.enableTcpKeepAlive = true;
+ clientConfig.tcpKeepAliveIntervalMs = 30000;
+ clientConfig.lowSpeedLimit = 1;
+ clientConfig.proxyScheme = Aws::Http::Scheme::HTTP;
+ clientConfig.proxyPort = 0;
+ clientConfig.executor = Aws::MakeShared<Aws::Utils::Threading::DefaultExecutor>(CLIENT_CONFIG_TAG);
+ clientConfig.verifySSL = true;
+ clientConfig.writeRateLimiter = nullptr;
+ clientConfig.readRateLimiter = nullptr;
+ clientConfig.httpLibOverride = Aws::Http::TransferLibType::DEFAULT_CLIENT;
+ clientConfig.followRedirects = FollowRedirectsPolicy::DEFAULT;
+ clientConfig.disableExpectHeader = false;
+ clientConfig.enableClockSkewAdjustment = true;
+ clientConfig.enableHostPrefixInjection = true;
+ clientConfig.profileName = Aws::Auth::GetConfigProfileName();
- // Initialize Retry Strategy
- int maxAttempts;
+ Aws::String useCompressionConfig = clientConfig.LoadConfigFromEnvOrProfile(
+ USE_REQUEST_COMPRESSION_ENV_VAR,
+ Aws::Auth::GetConfigProfileName(),
+ USE_REQUEST_COMPRESSION_CONFIG_VAR,
+ {"ENABLE", "DISABLE", "enable", "disable"},
+ "ENABLE"
+ );
+
+ if (Aws::Utils::StringUtils::ToLower(useCompressionConfig.c_str()) == "disable") {
+ clientConfig.requestCompressionConfig.useRequestCompression = Aws::Client::UseRequestCompression::DISABLE;
+ AWS_LOGSTREAM_DEBUG(CLIENT_CONFIG_TAG, "Request Compression disabled");
+ } else {
+ //Using default to true for forward compatibility in case new config is added but SDK is not updated.
+ clientConfig.requestCompressionConfig.useRequestCompression = Aws::Client::UseRequestCompression::ENABLE;
+ AWS_LOGSTREAM_DEBUG(CLIENT_CONFIG_TAG, "Request Compression enabled");
+ }
+
+ // Getting min request compression length
+ Aws::String minRequestCompressionString = Aws::Environment::GetEnv(REQUEST_MIN_COMPRESSION_SIZE_BYTES_ENV_VAR);
+ if (minRequestCompressionString.empty())
+ {
+ minRequestCompressionString = Aws::Config::GetCachedConfigValue(REQUEST_MIN_COMPRESSION_SIZE_BYTES_CONFIG_VAR);
+ }
+ if (!minRequestCompressionString.empty()) {
+ clientConfig.requestCompressionConfig.requestMinCompressionSizeBytes = static_cast<int>(Aws::Utils::StringUtils::ConvertToInt32(minRequestCompressionString.c_str()));
+ if (clientConfig.requestCompressionConfig.requestMinCompressionSizeBytes > 10485760) {
+ AWS_LOGSTREAM_ERROR(CLIENT_CONFIG_TAG, "ClientConfiguration for MinReqCompression is unsupported, received: " << clientConfig.requestCompressionConfig.requestMinCompressionSizeBytes);
+ }
+ }
+ AWS_LOGSTREAM_DEBUG(CLIENT_CONFIG_TAG, "ClientConfiguration will use MinReqCompression: " << clientConfig.requestCompressionConfig.requestMinCompressionSizeBytes);
+
+ AWS_LOGSTREAM_DEBUG(CLIENT_CONFIG_TAG, "ClientConfiguration will use SDK Auto Resolved profile: [" << clientConfig.profileName << "] if not specified by users.");
+
+ // Automatically determine the AWS region from environment variables, configuration file and EC2 metadata.
+ clientConfig.region = Aws::Environment::GetEnv("AWS_DEFAULT_REGION");
+ if (!clientConfig.region.empty())
+ {
+ return;
+ }
+
+ clientConfig.region = Aws::Environment::GetEnv("AWS_REGION");
+ if (!clientConfig.region.empty())
+ {
+ return;
+ }
+
+ clientConfig.region = Aws::Config::GetCachedConfigValue("region");
+ if (!clientConfig.region.empty())
+ {
+ return;
+ }
+
+ // Set the endpoint to interact with EC2 instance's metadata service
+ Aws::String ec2MetadataServiceEndpoint = Aws::Environment::GetEnv("AWS_EC2_METADATA_SERVICE_ENDPOINT");
+ if (! ec2MetadataServiceEndpoint.empty())
+ {
+ //By default we use the IPv4 default metadata service address
+ auto client = Aws::Internal::GetEC2MetadataClient();
+ if (client != nullptr)
+ {
+ client->SetEndpoint(ec2MetadataServiceEndpoint);
+ }
+ }
+}
+
+ClientConfiguration::ClientConfiguration()
+{
+ this->disableIMDS = false;
+ setLegacyClientConfigurationParameters(*this);
+ retryStrategy = InitRetryStrategy();
+
+ if (!this->disableIMDS &&
+ region.empty() &&
+ Aws::Utils::StringUtils::ToLower(Aws::Environment::GetEnv("AWS_EC2_METADATA_DISABLED").c_str()) != "true")
+ {
+ auto client = Aws::Internal::GetEC2MetadataClient();
+ if (client)
+ {
+ region = client->GetCurrentRegion();
+ }
+ }
+ if (!region.empty())
+ {
+ return;
+ }
+ region = Aws::String(Aws::Region::US_EAST_1);
+}
+
+ClientConfiguration::ClientConfiguration(const char* profile, bool shouldDisableIMDS)
+{
+ this->disableIMDS = shouldDisableIMDS;
+ setLegacyClientConfigurationParameters(*this);
+ // Call EC2 Instance Metadata service only once
+ Aws::String ec2MetadataRegion;
+ bool hasEc2MetadataRegion = false;
+ if (!this->disableIMDS &&
+ region.empty() &&
+ Aws::Utils::StringUtils::ToLower(Aws::Environment::GetEnv("AWS_EC2_METADATA_DISABLED").c_str()) != "true") {
+ auto client = Aws::Internal::GetEC2MetadataClient();
+ if (client)
+ {
+ ec2MetadataRegion = client->GetCurrentRegion();
+ hasEc2MetadataRegion = true;
+ region = ec2MetadataRegion;
+ }
+ }
+
+ if(region.empty())
+ {
+ region = Aws::String(Aws::Region::US_EAST_1);
+ }
+
+ if (profile && Aws::Config::HasCachedConfigProfile(profile)) {
+ this->profileName = Aws::String(profile);
+ AWS_LOGSTREAM_DEBUG(CLIENT_CONFIG_TAG,
+ "Use user specified profile: [" << this->profileName << "] for ClientConfiguration.");
+ auto tmpRegion = Aws::Config::GetCachedConfigProfile(this->profileName).GetRegion();
+ if (!tmpRegion.empty()) {
+ region = tmpRegion;
+ }
+
+ Aws::String profileDefaultsMode = Aws::Config::GetCachedConfigProfile(this->profileName).GetDefaultsMode();
+ Aws::Config::Defaults::SetSmartDefaultsConfigurationParameters(*this, profileDefaultsMode,
+ hasEc2MetadataRegion, ec2MetadataRegion);
+ return;
+ }
+ if (!retryStrategy)
+ {
+ retryStrategy = InitRetryStrategy();
+ }
+
+ AWS_LOGSTREAM_WARN(CLIENT_CONFIG_TAG, "User specified profile: [" << profile << "] is not found, will use the SDK resolved one.");
+}
+
+ClientConfiguration::ClientConfiguration(bool /*useSmartDefaults*/, const char* defaultMode, bool shouldDisableIMDS)
+{
+ this->disableIMDS = shouldDisableIMDS;
+ setLegacyClientConfigurationParameters(*this);
+
+ // Call EC2 Instance Metadata service only once
+ Aws::String ec2MetadataRegion;
+ bool hasEc2MetadataRegion = false;
+ if (!this->disableIMDS &&
+ region.empty() &&
+ Aws::Utils::StringUtils::ToLower(Aws::Environment::GetEnv("AWS_EC2_METADATA_DISABLED").c_str()) != "true")
+ {
+ auto client = Aws::Internal::GetEC2MetadataClient();
+ if (client)
+ {
+ ec2MetadataRegion = client->GetCurrentRegion();
+ hasEc2MetadataRegion = true;
+ region = ec2MetadataRegion;
+ }
+ }
+ if (region.empty())
+ {
+ region = Aws::String(Aws::Region::US_EAST_1);
+ }
+
+ Aws::Config::Defaults::SetSmartDefaultsConfigurationParameters(*this, defaultMode, hasEc2MetadataRegion, ec2MetadataRegion);
+}
+
+std::shared_ptr<RetryStrategy> InitRetryStrategy(Aws::String retryMode)
+{
+ int maxAttempts = 0;
Aws::String maxAttemptsString = Aws::Environment::GetEnv("AWS_MAX_ATTEMPTS");
if (maxAttemptsString.empty())
{
@@ -83,15 +259,21 @@ ClientConfiguration::ClientConfiguration() :
}
}
- Aws::String retryMode = Aws::Environment::GetEnv("AWS_RETRY_MODE");
+ if (retryMode.empty())
+ {
+ retryMode = Aws::Environment::GetEnv("AWS_RETRY_MODE");
+ }
if (retryMode.empty())
{
retryMode = Aws::Config::GetCachedConfigValue("retry_mode");
}
+
+ std::shared_ptr<RetryStrategy> retryStrategy;
if (retryMode == "standard")
{
if (maxAttempts < 0)
{
+ // negative value set above force usage of default max attempts
retryStrategy = Aws::MakeShared<StandardRetryStrategy>(CLIENT_CONFIG_TAG);
}
else
@@ -99,61 +281,55 @@ ClientConfiguration::ClientConfiguration() :
retryStrategy = Aws::MakeShared<StandardRetryStrategy>(CLIENT_CONFIG_TAG, maxAttempts);
}
}
- else
- {
- retryStrategy = Aws::MakeShared<DefaultRetryStrategy>(CLIENT_CONFIG_TAG);
- }
-
- // Automatically determine the AWS region from environment variables, configuration file and EC2 metadata.
- region = Aws::Environment::GetEnv("AWS_DEFAULT_REGION");
- if (!region.empty())
- {
- return;
- }
-
- region = Aws::Environment::GetEnv("AWS_REGION");
- if (!region.empty())
+ else if (retryMode == "adaptive")
{
- return;
- }
-
- region = Aws::Config::GetCachedConfigValue("region");
- if (!region.empty())
- {
- return;
- }
-
- if (Aws::Utils::StringUtils::ToLower(Aws::Environment::GetEnv("AWS_EC2_METADATA_DISABLED").c_str()) != "true")
- {
- auto client = Aws::Internal::GetEC2MetadataClient();
- if (client)
+ if (maxAttempts < 0)
{
- region = client->GetCurrentRegion();
+ // negative value set above force usage of default max attempts
+ retryStrategy = Aws::MakeShared<AdaptiveRetryStrategy>(CLIENT_CONFIG_TAG);
+ }
+ else
+ {
+ retryStrategy = Aws::MakeShared<AdaptiveRetryStrategy>(CLIENT_CONFIG_TAG, maxAttempts);
}
}
-
- if (!region.empty())
+ else
{
- return;
+ retryStrategy = Aws::MakeShared<DefaultRetryStrategy>(CLIENT_CONFIG_TAG);
}
- region = Aws::String(Aws::Region::US_EAST_1);
+ return retryStrategy;
}
-ClientConfiguration::ClientConfiguration(const char* profile) : ClientConfiguration()
+Aws::String ClientConfiguration::LoadConfigFromEnvOrProfile(const Aws::String& envKey,
+ const Aws::String& profile,
+ const Aws::String& profileProperty,
+ const Aws::Vector<Aws::String>& allowedValues,
+ const Aws::String& defaultValue)
{
- if (profile && Aws::Config::HasCachedConfigProfile(profile))
- {
- this->profileName = Aws::String(profile);
- AWS_LOGSTREAM_DEBUG(CLIENT_CONFIG_TAG, "Use user specified profile: [" << this->profileName << "] for ClientConfiguration.");
- auto tmpRegion = Aws::Config::GetCachedConfigProfile(this->profileName).GetRegion();
- if (!tmpRegion.empty())
- {
- region = tmpRegion;
+ Aws::String option = Aws::Environment::GetEnv(envKey.c_str());
+ if (option.empty()) {
+ option = Aws::Config::GetCachedConfigValue(profile, profileProperty);
+ }
+ option = Aws::Utils::StringUtils::ToLower(option.c_str());
+ if (option.empty()) {
+ return defaultValue;
+ }
+
+ if (!allowedValues.empty() && std::find(allowedValues.cbegin(), allowedValues.cend(), option) == allowedValues.cend()) {
+ Aws::OStringStream expectedStr;
+ expectedStr << "[";
+ for(const auto& allowed : allowedValues) {
+ expectedStr << allowed << ";";
}
- return;
+ expectedStr << "]";
+
+ AWS_LOGSTREAM_WARN(CLIENT_CONFIG_TAG, "Unrecognised value for " << envKey << ": " << option <<
+ ". Using default instead: " << defaultValue <<
+ ". Expected empty or one of: " << expectedStr.str());
+ option = defaultValue;
}
- AWS_LOGSTREAM_WARN(CLIENT_CONFIG_TAG, "User specified profile: [" << profile << "] is not found, will use the SDK resolved one.");
+ return option;
}
} // namespace Client
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/CoreErrors.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/CoreErrors.cpp
index 8c2c288dcd..50a7f9308d 100644
--- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/CoreErrors.cpp
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/CoreErrors.cpp
@@ -18,7 +18,8 @@ using namespace Aws::Http;
#pragma warning(disable : 4592)
#endif
-static Aws::UniquePtr<Aws::Map<Aws::String, AWSError<CoreErrors> > > s_CoreErrorsMapper(nullptr);
+using ErrorsMapperContainer = Aws::Map<Aws::String, AWSError<CoreErrors> >;
+static ErrorsMapperContainer* s_CoreErrorsMapper(nullptr);
#ifdef _MSC_VER
#pragma warning(pop)
@@ -30,7 +31,7 @@ void CoreErrorsMapper::InitCoreErrorsMapper()
{
return;
}
- s_CoreErrorsMapper = Aws::MakeUnique<Aws::Map<Aws::String, AWSError<CoreErrors> > >("InitCoreErrorsMapper");
+ s_CoreErrorsMapper = Aws::New<ErrorsMapperContainer>("InitCoreErrorsMapper");
s_CoreErrorsMapper->emplace("IncompleteSignature", AWSError<CoreErrors>(CoreErrors::INCOMPLETE_SIGNATURE, false));
s_CoreErrorsMapper->emplace("IncompleteSignatureException", AWSError<CoreErrors>(CoreErrors::INCOMPLETE_SIGNATURE, false));
@@ -92,10 +93,8 @@ void CoreErrorsMapper::InitCoreErrorsMapper()
void CoreErrorsMapper::CleanupCoreErrorsMapper()
{
- if (s_CoreErrorsMapper)
- {
- s_CoreErrorsMapper = nullptr;
- }
+ Aws::Delete(s_CoreErrorsMapper);
+ s_CoreErrorsMapper = nullptr;
}
AWSError<CoreErrors> CoreErrorsMapper::GetErrorForName(const char* errorName)
@@ -149,3 +148,12 @@ AWS_CORE_API AWSError<CoreErrors> CoreErrorsMapper::GetErrorForHttpResponseCode(
error.SetResponseCode(code);
return error;
}
+
+/**
+ * Overload ostream operator<< for CoreErrors enum class for a prettier output such as "103" and not "<67-00 00-00>"
+ */
+Aws::OStream& Aws::Client::operator<< (Aws::OStream& oStream, CoreErrors code)
+{
+ oStream << Aws::Utils::StringUtils::to_string(static_cast<typename std::underlying_type<HttpResponseCode>::type>(code));
+ return oStream;
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/DefaultRetryStrategy.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/DefaultRetryStrategy.cpp
index 7e57c79ffc..405d7566cf 100644
--- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/DefaultRetryStrategy.cpp
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/DefaultRetryStrategy.cpp
@@ -28,5 +28,5 @@ long DefaultRetryStrategy::CalculateDelayBeforeNextRetry(const AWSError<CoreErro
return 0;
}
- return (1 << attemptedRetries) * m_scaleFactor;
+ return (1UL << attemptedRetries) * m_scaleFactor;
}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/GenericClientConfiguration.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/GenericClientConfiguration.cpp
new file mode 100644
index 0000000000..f0a4e91d5b
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/GenericClientConfiguration.cpp
@@ -0,0 +1,103 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/client/GenericClientConfiguration.h>
+#include <aws/core/platform/Environment.h>
+#include <aws/core/utils/memory/AWSMemory.h>
+#include <aws/core/utils/threading/Executor.h>
+
+
+namespace Aws
+{
+namespace Client
+{
+template struct AWS_CORE_API GenericClientConfiguration<false>;
+
+bool IsEndpointDiscoveryEnabled(const Aws::String& endpointOverride, const Aws::String &profileName)
+{
+ bool enabled = true; // default value for AWS Services with enabled discovery trait
+ if (!endpointOverride.empty())
+ {
+ enabled = false;
+ }
+ else
+ {
+ static const char* AWS_ENABLE_ENDPOINT_DISCOVERY_ENV_KEY = "AWS_ENABLE_ENDPOINT_DISCOVERY";
+ static const char* AWS_ENABLE_ENDPOINT_DISCOVERY_PROFILE_KEY = "AWS_ENABLE_ENDPOINT_DISCOVERY";
+ static const char* AWS_ENABLE_ENDPOINT_ENABLED = "true";
+ static const char* AWS_ENABLE_ENDPOINT_DISABLED = "false";
+
+ Aws::String enableEndpointDiscovery = ClientConfiguration::LoadConfigFromEnvOrProfile(AWS_ENABLE_ENDPOINT_DISCOVERY_ENV_KEY,
+ profileName,
+ AWS_ENABLE_ENDPOINT_DISCOVERY_PROFILE_KEY,
+ {AWS_ENABLE_ENDPOINT_ENABLED, AWS_ENABLE_ENDPOINT_DISABLED},
+ AWS_ENABLE_ENDPOINT_ENABLED);
+
+ if (AWS_ENABLE_ENDPOINT_DISABLED == enableEndpointDiscovery)
+ {
+ // enabled by default unless explicitly disabled in ENV, profile config file, or programmatically later
+ enabled = false;
+ }
+ }
+ return enabled;
+}
+
+GenericClientConfiguration<true>::GenericClientConfiguration()
+ : ClientConfiguration(),
+ enableHostPrefixInjection(ClientConfiguration::enableHostPrefixInjection),
+ enableEndpointDiscovery(ClientConfiguration::enableEndpointDiscovery)
+{
+ enableEndpointDiscovery = IsEndpointDiscoveryEnabled(this->endpointOverride, this->profileName);
+ enableHostPrefixInjection = false; // disabled by default in the SDK
+}
+
+GenericClientConfiguration<true>::GenericClientConfiguration(const char* inputProfileName, bool shouldDisableIMDS)
+ : ClientConfiguration(inputProfileName, shouldDisableIMDS),
+ enableHostPrefixInjection(ClientConfiguration::enableHostPrefixInjection),
+ enableEndpointDiscovery(ClientConfiguration::enableEndpointDiscovery)
+{
+ enableEndpointDiscovery = IsEndpointDiscoveryEnabled(this->endpointOverride, this->profileName);
+ enableHostPrefixInjection = false; // disabled by default in the SDK
+}
+
+GenericClientConfiguration<true>::GenericClientConfiguration(bool useSmartDefaults, const char* inputDefaultMode, bool shouldDisableIMDS)
+ : ClientConfiguration(useSmartDefaults, inputDefaultMode, shouldDisableIMDS),
+ enableHostPrefixInjection(ClientConfiguration::enableHostPrefixInjection),
+ enableEndpointDiscovery(ClientConfiguration::enableEndpointDiscovery)
+{
+ enableEndpointDiscovery = IsEndpointDiscoveryEnabled(this->endpointOverride, this->profileName);
+ enableHostPrefixInjection = false; // disabled by default in the SDK
+}
+
+GenericClientConfiguration<true>::GenericClientConfiguration(const ClientConfiguration& config)
+ : ClientConfiguration(config),
+ enableHostPrefixInjection(ClientConfiguration::enableHostPrefixInjection),
+ enableEndpointDiscovery(ClientConfiguration::enableEndpointDiscovery)
+{
+ enableEndpointDiscovery = IsEndpointDiscoveryEnabled(this->endpointOverride, this->profileName);
+ enableHostPrefixInjection = false; // disabled by default in the SDK
+}
+
+GenericClientConfiguration<true>::GenericClientConfiguration(const GenericClientConfiguration<true>& other)
+ : ClientConfiguration(static_cast<ClientConfiguration>(other)),
+ enableHostPrefixInjection(ClientConfiguration::enableHostPrefixInjection),
+ enableEndpointDiscovery(ClientConfiguration::enableEndpointDiscovery)
+{
+ if (other.enableEndpointDiscovery) {
+ enableEndpointDiscovery = other.enableEndpointDiscovery.value();
+ }
+ enableHostPrefixInjection = other.enableHostPrefixInjection;
+}
+
+GenericClientConfiguration<true>& GenericClientConfiguration<true>::operator=(const GenericClientConfiguration<true>& other)
+{
+ if (this != &other) {
+ *static_cast<ClientConfiguration*>(this) = static_cast<ClientConfiguration>(other);
+ }
+ return *this;
+}
+
+} // namespace Client
+} // namespace Aws
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RequestCompression.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RequestCompression.cpp
new file mode 100644
index 0000000000..e51a49049b
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RequestCompression.cpp
@@ -0,0 +1,336 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/client/RequestCompression.h>
+#include <aws/core/utils/logging/LogMacros.h>
+#include <aws/core/utils/memory/AWSMemory.h>
+#include <algorithm>
+#include <aws/core/utils/memory/stl/AWSAllocator.h>
+
+#ifdef ENABLED_ZLIB_REQUEST_COMPRESSION
+#include "zlib.h"
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+#include <fcntl.h>
+#include <io.h>
+#define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+#define SET_BINARY_MODE(file)
+#endif // defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+// Defining zlib chunks to be 256k
+static const size_t ZLIB_CHUNK=263144;
+static const char AWS_REQUEST_COMPRESSION_ALLOCATION_TAG[] =
+ "RequestCompressionAlloc";
+#endif // ENABLED_ZLIB_REQUEST_COMPRESSION
+
+static const char AWS_REQUEST_COMPRESSION_LOG_TAG[] = "RequestCompression";
+
+Aws::String Aws::Client::GetCompressionAlgorithmId(const CompressionAlgorithm &algorithm)
+{
+ switch (algorithm)
+ {
+ case CompressionAlgorithm::GZIP:
+ return "gzip";
+ default:
+ return "";
+ }
+}
+
+#ifdef ENABLED_ZLIB_REQUEST_COMPRESSION
+#ifdef USE_AWS_MEMORY_MANAGEMENT
+static const char* ZlibMemTag = "zlib";
+static const size_t offset = sizeof(size_t); // to make space for size of the array
+//Define custom memory allocation for zlib
+// if fail to allocate, return Z_NULL
+void* aws_zalloc(void * /* opaque */, unsigned items, unsigned size)
+{
+ unsigned sizeToAllocate = items*size;
+ size_t sizeToAllocateWithOffset = sizeToAllocate + offset;
+ if ((size != 0 && sizeToAllocate / size != items)
+ || (sizeToAllocateWithOffset <= sizeToAllocate ))
+ {
+ return Z_NULL;
+ }
+ char* newMem = reinterpret_cast<char*>(Aws::Malloc(ZlibMemTag, sizeToAllocateWithOffset));
+ if (newMem != nullptr) {
+ std::size_t* pointerToSize = reinterpret_cast<std::size_t*>(newMem);
+ *pointerToSize = size;
+ return reinterpret_cast<void*>(newMem + offset);
+ }
+ else
+ {
+ return Z_NULL;
+ }
+}
+
+void aws_zfree(void * /* opaque */, void * ptr)
+{
+ if(ptr)
+ {
+ char* shiftedMemory = reinterpret_cast<char*>(ptr);
+ Aws::Free(shiftedMemory - offset);
+ }
+}
+
+#endif // AWS_CUSTOM_MEMORY_MANAGEMENT
+#endif // ENABLED_ZLIB_REQUEST_COMPRESSION
+
+
+iostream_outcome Aws::Client::RequestCompression::compress(std::shared_ptr<Aws::IOStream> input,
+ const CompressionAlgorithm &algorithm) const
+{
+#ifdef ENABLED_ZLIB_REQUEST_COMPRESSION
+ if (algorithm == CompressionAlgorithm::GZIP)
+ {
+ // calculating stream size
+ input->seekg(0, input->end);
+ size_t streamSize = input->tellg();
+ input->seekg(0, input->beg);
+
+ AWS_LOGSTREAM_TRACE(AWS_REQUEST_COMPRESSION_LOG_TAG, "Compressing request of " << streamSize << " bytes.");
+
+ // Preparing output
+ std::shared_ptr<Aws::IOStream> output = Aws::MakeShared<Aws::StringStream>(AWS_REQUEST_COMPRESSION_ALLOCATION_TAG);
+ if(!output)
+ {
+ AWS_LOGSTREAM_ERROR(AWS_REQUEST_COMPRESSION_LOG_TAG, "Failed to allocate output while compressing")
+ return false;
+ }
+ // Prepare ZLIB to compress
+ int ret = Z_NULL;
+ int flush = Z_NO_FLUSH;
+ z_stream strm = {};
+ auto in = Aws::MakeUniqueArray<unsigned char>(ZLIB_CHUNK, AWS_REQUEST_COMPRESSION_ALLOCATION_TAG);
+ if(!in)
+ {
+ AWS_LOGSTREAM_ERROR(AWS_REQUEST_COMPRESSION_LOG_TAG, "Failed to allocate in buffer while compressing")
+ return false;
+ }
+
+ auto out = Aws::MakeUniqueArray<unsigned char>(ZLIB_CHUNK, AWS_REQUEST_COMPRESSION_ALLOCATION_TAG);
+ if(!out)
+ {
+ AWS_LOGSTREAM_ERROR(AWS_REQUEST_COMPRESSION_LOG_TAG, "Failed to allocate out buffer while compressing")
+ return false;
+ }
+
+ //Preparing allocators
+#ifdef USE_AWS_MEMORY_MANAGEMENT
+ strm.zalloc = (void *(*)(void *, unsigned, unsigned)) aws_zalloc;
+ strm.zfree = (void (*)(void *, void *)) aws_zfree;
+#else
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+#endif
+ strm.opaque = Z_NULL;
+
+ const int MAX_WINDOW_GZIP = 31;
+ const int DEFAULT_MEM_LEVEL_USAGE = 8;
+ ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WINDOW_GZIP, DEFAULT_MEM_LEVEL_USAGE, Z_DEFAULT_STRATEGY);
+ if(ret != Z_OK)
+ {
+ return false;
+ }
+
+ //Adding one to the stream size counter to account for the EOF marker.
+ streamSize++;
+ size_t toRead;
+ // Compress
+ do {
+ toRead = std::min(streamSize, ZLIB_CHUNK);
+ // Fill the buffer
+ if (! input->read(reinterpret_cast<char *>(in.get()), toRead))
+ {
+ if (input->eof())
+ {
+ //Last read need flush when exit loop
+ flush = Z_FINISH;
+ }
+ else {
+ AWS_LOGSTREAM_ERROR(
+ AWS_REQUEST_COMPRESSION_LOG_TAG,
+ "Uncompress request failed to read from stream");
+ return false;
+ }
+ }
+ streamSize -= toRead; //left to read
+ strm.avail_in = (flush == Z_FINISH)?toRead-1:toRead; //skip EOF if included
+ strm.next_in = in.get();
+ do
+ {
+ // Run deflate on buffers
+ strm.avail_out = ZLIB_CHUNK;
+ strm.next_out = out.get();
+
+ ret = deflate(&strm, flush);
+
+ // writing the output
+ assert(ZLIB_CHUNK >= strm.avail_out);
+ unsigned output_size = ZLIB_CHUNK - strm.avail_out;
+ if(! output->write(reinterpret_cast<char *>(out.get()), output_size))
+ {
+ AWS_LOGSTREAM_ERROR(AWS_REQUEST_COMPRESSION_LOG_TAG, "Compressed request failed to write to output stream");
+ return false;
+ }
+ } while (strm.avail_out == 0);
+ assert(strm.avail_in == 0); // All data was read
+ } while (flush != Z_FINISH);
+ assert(ret == Z_STREAM_END); // Completed stream
+ AWS_LOGSTREAM_TRACE(AWS_REQUEST_COMPRESSION_LOG_TAG, "Compressed request to: " << strm.total_out << " bytes");
+ deflateEnd(&strm);
+ return output;
+ }
+ else
+ {
+ AWS_LOGSTREAM_ERROR(AWS_REQUEST_COMPRESSION_LOG_TAG, "Compress request requested in runtime without support: " << GetCompressionAlgorithmId(algorithm));
+ return false;
+ }
+#else
+ // If there is no support to compress, always fail calls to this method.
+ AWS_LOGSTREAM_ERROR(AWS_REQUEST_COMPRESSION_LOG_TAG, "Compress request requested in runtime without support: " << GetCompressionAlgorithmId(algorithm));
+ AWS_UNREFERENCED_PARAM(input); // silencing warning;
+ return false;
+#endif
+}
+
+Aws::Utils::Outcome<std::shared_ptr<Aws::IOStream>, bool>
+Aws::Client::RequestCompression::uncompress(std::shared_ptr<Aws::IOStream> input, const CompressionAlgorithm &algorithm) const
+{
+#ifdef ENABLED_ZLIB_REQUEST_COMPRESSION
+ if (algorithm == CompressionAlgorithm::GZIP)
+ {
+ // calculating stream size
+ input->seekg(0, input->end);
+ size_t streamSize = input->tellg();
+ input->seekg(0, input->beg);
+
+ AWS_LOGSTREAM_TRACE(AWS_REQUEST_COMPRESSION_LOG_TAG, "Uncompressing request of " << streamSize << " bytes.");
+
+ // Preparing output
+ std::shared_ptr<Aws::IOStream> output = Aws::MakeShared<Aws::StringStream>( AWS_REQUEST_COMPRESSION_ALLOCATION_TAG);
+ if(!output)
+ {
+ AWS_LOGSTREAM_ERROR(AWS_REQUEST_COMPRESSION_LOG_TAG, "Failed to allocate output while uncompressing")
+ return false;
+ }
+
+ // Prepare ZLIB to uncompress
+ int ret = Z_NULL;
+ z_stream strm = {};
+ auto in = Aws::MakeUniqueArray<unsigned char>(ZLIB_CHUNK, AWS_REQUEST_COMPRESSION_ALLOCATION_TAG);
+ if(!in)
+ {
+ AWS_LOGSTREAM_ERROR(AWS_REQUEST_COMPRESSION_LOG_TAG, "Failed to allocate in buffer while uncompressing")
+ return false;
+ }
+
+ auto out = Aws::MakeUniqueArray<unsigned char>(ZLIB_CHUNK, AWS_REQUEST_COMPRESSION_ALLOCATION_TAG);
+ if(!out)
+ {
+ AWS_LOGSTREAM_ERROR(AWS_REQUEST_COMPRESSION_LOG_TAG, "Failed to allocate out buffer while uncompressing")
+ return false;
+ }
+
+ //preparing allocation
+#ifdef USE_AWS_MEMORY_MANAGEMENT
+ strm.zalloc = (void *(*)(void *, unsigned, unsigned)) aws_zalloc;
+ strm.zfree = (void (*)(void *, void *)) aws_zfree;
+#else
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+#endif
+ strm.opaque = Z_NULL;
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+
+ const int MAX_WINDOW_GZIP = 31;
+ ret = inflateInit2(&strm, MAX_WINDOW_GZIP);
+ if (ret != Z_OK)
+ {
+ return false;
+ }
+
+ //Adding one to the stream size counter to account for the EOF marker.
+ streamSize++;
+ size_t toRead;
+ // Decompress
+ do {
+ toRead = (streamSize < ZLIB_CHUNK)?streamSize:ZLIB_CHUNK;
+ if (toRead < 1) break; // Nothing left to read
+ // Fill the buffer
+ if(! input->read(reinterpret_cast<char *>(in.get()), toRead))
+ {
+ if (input->eof())
+ {
+ //skip passing the EOF to the buffer
+ toRead--;
+ }
+ else
+ {
+ AWS_LOGSTREAM_ERROR(
+ AWS_REQUEST_COMPRESSION_LOG_TAG,
+ "Compress request failed to read from stream");
+ return false;
+ }
+ }
+
+ // Filling input buffer to decompress
+ strm.avail_in = toRead;
+ strm.next_in = in.get();
+ do
+ {
+ // Run inflate on buffers
+ strm.avail_out = ZLIB_CHUNK;
+ strm.next_out = out.get();
+
+ ret = inflate(&strm, Z_NO_FLUSH);
+ // Catch errors
+ switch (ret)
+ {
+ case Z_NEED_DICT:
+ AWS_LOGSTREAM_ERROR(AWS_REQUEST_COMPRESSION_LOG_TAG, "Compressed request failed to inflate with code: Z_NEED_DICT");
+ return false;
+ case Z_DATA_ERROR:
+ AWS_LOGSTREAM_ERROR(AWS_REQUEST_COMPRESSION_LOG_TAG, "Compressed request failed to inflate with code: Z_DATA_ERROR");
+ return false;
+ case Z_MEM_ERROR:
+ (void)inflateEnd(&strm);
+ AWS_LOGSTREAM_ERROR(AWS_REQUEST_COMPRESSION_LOG_TAG, "Compressed request failed to inflate with code: Z_MEM_ERROR");
+ return false;
+ }
+
+ // writing the output
+ unsigned output_size = ZLIB_CHUNK - strm.avail_out;
+ if(! output->write(reinterpret_cast<char *>(out.get()), output_size)) {
+ AWS_LOGSTREAM_ERROR(AWS_REQUEST_COMPRESSION_LOG_TAG, "Uncompressed request failed to write to output stream");
+ return false;
+ }
+ } while (strm.avail_out == 0);
+ } while (ret != Z_STREAM_END);
+ // clean up
+ (void)inflateEnd(&strm);
+ if (ret == Z_STREAM_END)
+ {
+ AWS_LOGSTREAM_TRACE(AWS_REQUEST_COMPRESSION_LOG_TAG, "Decompressed request to: " << strm.total_out << " bytes");
+ return output;
+ }
+ else
+ {
+ AWS_LOGSTREAM_ERROR(AWS_REQUEST_COMPRESSION_LOG_TAG, "Failed to decompress after read input completely");
+ return false;
+ }
+ }
+ else
+ {
+ AWS_LOGSTREAM_ERROR(AWS_REQUEST_COMPRESSION_LOG_TAG, "Uncompress request requested in runtime without support: " << GetCompressionAlgorithmId(algorithm));
+ return false;
+ }
+#else
+ // If there is no support to compress, always fail calls to this method.
+ AWS_LOGSTREAM_ERROR(AWS_REQUEST_COMPRESSION_LOG_TAG, "Uncompress request requested in runtime without support: " << GetCompressionAlgorithmId(algorithm));
+ AWS_UNREFERENCED_PARAM(input); // silencing warning;
+ return false;
+#endif
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RetryStrategy.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RetryStrategy.cpp
index b439b7ca99..77b6f5abbb 100644
--- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RetryStrategy.cpp
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RetryStrategy.cpp
@@ -17,18 +17,21 @@ namespace Aws
{
static const int INITIAL_RETRY_TOKENS = 500;
static const int RETRY_COST = 5;
- static const int NO_RETRY_INCREMENT = 1;
static const int TIMEOUT_RETRY_COST = 10;
StandardRetryStrategy::StandardRetryStrategy(long maxAttempts) :
m_retryQuotaContainer(Aws::MakeShared<DefaultRetryQuotaContainer>("StandardRetryStrategy")),
m_maxAttempts(maxAttempts)
- {}
+ {
+ srand((unsigned int)time(NULL));
+ }
StandardRetryStrategy::StandardRetryStrategy(std::shared_ptr<RetryQuotaContainer> retryQuotaContainer, long maxAttempts) :
m_retryQuotaContainer(retryQuotaContainer),
m_maxAttempts(maxAttempts)
- {}
+ {
+ srand((unsigned int)time(NULL));
+ }
void StandardRetryStrategy::RequestBookkeeping(const HttpResponseOutcome& httpResponseOutcome)
{
@@ -60,7 +63,8 @@ namespace Aws
long StandardRetryStrategy::CalculateDelayBeforeNextRetry(const AWSError<CoreErrors>& error, long attemptedRetries) const
{
AWS_UNREFERENCED_PARAM(error);
- return (std::min)(rand() % 1000 * (1 << attemptedRetries), 20000);
+ // Maximum left shift factor is capped by ceil(log2(max_delay)), to avoid wrap-around and overflow into negative values:
+ return (std::min)(rand() % 1000 * (1 << (std::min)(attemptedRetries, 15L)), 20000);
}
DefaultRetryQuotaContainer::DefaultRetryQuotaContainer() : m_retryQuota(INITIAL_RETRY_TOKENS)
@@ -99,4 +103,4 @@ namespace Aws
ReleaseRetryQuota(capacityAmount);
}
}
-} \ No newline at end of file
+}