diff options
author | dakovalkov <dakovalkov@yandex-team.com> | 2023-12-03 13:33:55 +0300 |
---|---|---|
committer | dakovalkov <dakovalkov@yandex-team.com> | 2023-12-03 14:04:39 +0300 |
commit | 2a718325637e5302334b6d0a6430f63168f8dbb3 (patch) | |
tree | 64be81080b7df9ec1d86d053a0c394ae53fcf1fe /contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core | |
parent | e0d94a470142d95c3007e9c5d80380994940664a (diff) | |
download | ydb-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')
178 files changed, 12738 insertions, 3272 deletions
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.darwin-arm64.txt b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.darwin-arm64.txt index 07544321770..34e01718e79 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.darwin-arm64.txt +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.darwin-arm64.txt @@ -9,32 +9,44 @@ add_library(libs-aws-sdk-cpp-aws-cpp-sdk-core) target_compile_options(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE + -DAWS_AUTH_USE_IMPORT_EXPORT -DAWS_CAL_USE_IMPORT_EXPORT -DAWS_CHECKSUMS_USE_IMPORT_EXPORT -DAWS_COMMON_USE_IMPORT_EXPORT + -DAWS_COMPRESSION_USE_IMPORT_EXPORT + -DAWS_CRT_CPP_USE_IMPORT_EXPORT -DAWS_EVENT_STREAM_USE_IMPORT_EXPORT + -DAWS_HTTP_USE_IMPORT_EXPORT -DAWS_IO_USE_IMPORT_EXPORT + -DAWS_MQTT_USE_IMPORT_EXPORT + -DAWS_MQTT_WITH_WEBSOCKETS + -DAWS_S3_USE_IMPORT_EXPORT + -DAWS_SDKUTILS_USE_IMPORT_EXPORT -DAWS_SDK_VERSION_MAJOR=1 - -DAWS_SDK_VERSION_MINOR=8 - -DAWS_SDK_VERSION_PATCH=186 + -DAWS_SDK_VERSION_MINOR=11 + -DAWS_SDK_VERSION_PATCH=37 + -DAWS_TEST_REGION=US_EAST_1 -DAWS_USE_EPOLL -DCURL_HAS_H2 -DCURL_HAS_TLS_PROXY + -DENABLED_REQUEST_COMPRESSION + -DENABLED_ZLIB_REQUEST_COMPRESSION -DENABLE_CURL_CLIENT -DENABLE_CURL_LOGGING -DENABLE_OPENSSL_ENCRYPTION -DHAS_PATHCONF -DHAS_UMASK - -DS2N_ADX - -DS2N_BIKE_R3_AVX2 - -DS2N_BIKE_R3_AVX512 - -DS2N_BIKE_R3_PCLMUL - -DS2N_BIKE_R3_VPCLMUL + -DS2N_CLONE_SUPPORTED -DS2N_CPUID_AVAILABLE -DS2N_FALL_THROUGH_SUPPORTED - -DS2N_HAVE_EXECINFO + -DS2N_FEATURES_AVAILABLE -DS2N_KYBER512R3_AVX2_BMI2 - -DS2N_SIKE_P434_R3_ASM + -DS2N_LIBCRYPTO_SUPPORTS_EVP_MD5_SHA1_HASH + -DS2N_LIBCRYPTO_SUPPORTS_EVP_MD_CTX_SET_PKEY_CTX + -DS2N_LIBCRYPTO_SUPPORTS_EVP_RC4 + -DS2N_MADVISE_SUPPORTED + -DS2N_PLATFORM_SUPPORTS_KTLS + -DS2N_STACKTRACE -DS2N___RESTRICT__SUPPORTED $<IF:$<CXX_COMPILER_ID:MSVC>,,-Wno-everything> ) @@ -45,8 +57,17 @@ target_link_libraries(libs-aws-sdk-cpp-aws-cpp-sdk-core PUBLIC contrib-libs-cxxsupp contrib-libs-curl contrib-libs-openssl + contrib-libs-zlib + restricted-aws-aws-c-auth + restricted-aws-aws-c-cal restricted-aws-aws-c-common restricted-aws-aws-c-event-stream + restricted-aws-aws-c-http + restricted-aws-aws-c-io + restricted-aws-aws-c-mqtt + restricted-aws-aws-c-sdkutils + restricted-aws-aws-checksums + restricted-aws-aws-crt-cpp ) target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonSerializableWebServiceRequest.cpp @@ -56,26 +77,52 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Globals.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Region.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Version.cpp - ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp - ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSignerProvider.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/SSOCredentialsProvider.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/STSCredentialsProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/DefaultBearerTokenProviderChain.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/SSOBearerTokenProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/BearerTokenAuthSignerProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/DefaultAuthSignerProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthBearerSigner.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthEventStreamV4Signer.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerCommon.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerHelper.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthV4Signer.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSNullSigner.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSClient.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSJsonClient.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSUrlPresigner.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSXmlClient.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AdaptiveRetryStrategy.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AsyncCallerContext.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/ClientConfiguration.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/CoreErrors.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/DefaultRetryStrategy.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/GenericClientConfiguration.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RequestCompression.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RetryStrategy.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/SpecifiedRetryableErrorsRetryStrategy.cpp - ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSConfigFileProfileConfigLoader.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoaderBase.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/ConfigAndCredentialsCacheManager.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/EC2InstanceProfileConfigLoader.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/defaults/ClientConfigurationDefaults.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/AWSEndpoint.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/AWSPartitions.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/BuiltInParameters.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/ClientContextParameters.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/DefaultEndpointProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/EndpointProviderBase.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/internal/AWSEndpointAttribute.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/cjson/cJSON.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/tinyxml2/tinyxml2.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClient.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClientFactory.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpRequest.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpResponse.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpTypes.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/Scheme.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp @@ -92,6 +139,7 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DNS.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DateTimeCommon.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Directory.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Document.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/EnumParseOverflowContainer.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/FileSystemUtils.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/GetTheLights.cpp @@ -100,6 +148,7 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/TempFile.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/UUID.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/base64/Base64.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CRC32.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Cipher.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoMaterial.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoScheme.cpp @@ -123,6 +172,8 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamErrors.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/AWSLogging.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/CRTLogSystem.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/CRTLogging.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/ConsoleLogSystem.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/DefaultLogSystem.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/FormattedLogSystem.cpp diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.darwin-x86_64.txt b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.darwin-x86_64.txt index 07544321770..34e01718e79 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.darwin-x86_64.txt +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.darwin-x86_64.txt @@ -9,32 +9,44 @@ add_library(libs-aws-sdk-cpp-aws-cpp-sdk-core) target_compile_options(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE + -DAWS_AUTH_USE_IMPORT_EXPORT -DAWS_CAL_USE_IMPORT_EXPORT -DAWS_CHECKSUMS_USE_IMPORT_EXPORT -DAWS_COMMON_USE_IMPORT_EXPORT + -DAWS_COMPRESSION_USE_IMPORT_EXPORT + -DAWS_CRT_CPP_USE_IMPORT_EXPORT -DAWS_EVENT_STREAM_USE_IMPORT_EXPORT + -DAWS_HTTP_USE_IMPORT_EXPORT -DAWS_IO_USE_IMPORT_EXPORT + -DAWS_MQTT_USE_IMPORT_EXPORT + -DAWS_MQTT_WITH_WEBSOCKETS + -DAWS_S3_USE_IMPORT_EXPORT + -DAWS_SDKUTILS_USE_IMPORT_EXPORT -DAWS_SDK_VERSION_MAJOR=1 - -DAWS_SDK_VERSION_MINOR=8 - -DAWS_SDK_VERSION_PATCH=186 + -DAWS_SDK_VERSION_MINOR=11 + -DAWS_SDK_VERSION_PATCH=37 + -DAWS_TEST_REGION=US_EAST_1 -DAWS_USE_EPOLL -DCURL_HAS_H2 -DCURL_HAS_TLS_PROXY + -DENABLED_REQUEST_COMPRESSION + -DENABLED_ZLIB_REQUEST_COMPRESSION -DENABLE_CURL_CLIENT -DENABLE_CURL_LOGGING -DENABLE_OPENSSL_ENCRYPTION -DHAS_PATHCONF -DHAS_UMASK - -DS2N_ADX - -DS2N_BIKE_R3_AVX2 - -DS2N_BIKE_R3_AVX512 - -DS2N_BIKE_R3_PCLMUL - -DS2N_BIKE_R3_VPCLMUL + -DS2N_CLONE_SUPPORTED -DS2N_CPUID_AVAILABLE -DS2N_FALL_THROUGH_SUPPORTED - -DS2N_HAVE_EXECINFO + -DS2N_FEATURES_AVAILABLE -DS2N_KYBER512R3_AVX2_BMI2 - -DS2N_SIKE_P434_R3_ASM + -DS2N_LIBCRYPTO_SUPPORTS_EVP_MD5_SHA1_HASH + -DS2N_LIBCRYPTO_SUPPORTS_EVP_MD_CTX_SET_PKEY_CTX + -DS2N_LIBCRYPTO_SUPPORTS_EVP_RC4 + -DS2N_MADVISE_SUPPORTED + -DS2N_PLATFORM_SUPPORTS_KTLS + -DS2N_STACKTRACE -DS2N___RESTRICT__SUPPORTED $<IF:$<CXX_COMPILER_ID:MSVC>,,-Wno-everything> ) @@ -45,8 +57,17 @@ target_link_libraries(libs-aws-sdk-cpp-aws-cpp-sdk-core PUBLIC contrib-libs-cxxsupp contrib-libs-curl contrib-libs-openssl + contrib-libs-zlib + restricted-aws-aws-c-auth + restricted-aws-aws-c-cal restricted-aws-aws-c-common restricted-aws-aws-c-event-stream + restricted-aws-aws-c-http + restricted-aws-aws-c-io + restricted-aws-aws-c-mqtt + restricted-aws-aws-c-sdkutils + restricted-aws-aws-checksums + restricted-aws-aws-crt-cpp ) target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonSerializableWebServiceRequest.cpp @@ -56,26 +77,52 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Globals.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Region.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Version.cpp - ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp - ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSignerProvider.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/SSOCredentialsProvider.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/STSCredentialsProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/DefaultBearerTokenProviderChain.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/SSOBearerTokenProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/BearerTokenAuthSignerProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/DefaultAuthSignerProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthBearerSigner.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthEventStreamV4Signer.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerCommon.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerHelper.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthV4Signer.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSNullSigner.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSClient.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSJsonClient.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSUrlPresigner.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSXmlClient.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AdaptiveRetryStrategy.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AsyncCallerContext.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/ClientConfiguration.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/CoreErrors.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/DefaultRetryStrategy.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/GenericClientConfiguration.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RequestCompression.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RetryStrategy.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/SpecifiedRetryableErrorsRetryStrategy.cpp - ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSConfigFileProfileConfigLoader.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoaderBase.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/ConfigAndCredentialsCacheManager.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/EC2InstanceProfileConfigLoader.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/defaults/ClientConfigurationDefaults.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/AWSEndpoint.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/AWSPartitions.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/BuiltInParameters.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/ClientContextParameters.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/DefaultEndpointProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/EndpointProviderBase.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/internal/AWSEndpointAttribute.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/cjson/cJSON.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/tinyxml2/tinyxml2.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClient.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClientFactory.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpRequest.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpResponse.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpTypes.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/Scheme.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp @@ -92,6 +139,7 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DNS.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DateTimeCommon.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Directory.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Document.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/EnumParseOverflowContainer.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/FileSystemUtils.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/GetTheLights.cpp @@ -100,6 +148,7 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/TempFile.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/UUID.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/base64/Base64.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CRC32.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Cipher.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoMaterial.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoScheme.cpp @@ -123,6 +172,8 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamErrors.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/AWSLogging.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/CRTLogSystem.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/CRTLogging.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/ConsoleLogSystem.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/DefaultLogSystem.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/FormattedLogSystem.cpp diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.linux-aarch64.txt b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.linux-aarch64.txt index 577d096b9a2..43002865c6e 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.linux-aarch64.txt +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.linux-aarch64.txt @@ -9,32 +9,44 @@ add_library(libs-aws-sdk-cpp-aws-cpp-sdk-core) target_compile_options(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE + -DAWS_AUTH_USE_IMPORT_EXPORT -DAWS_CAL_USE_IMPORT_EXPORT -DAWS_CHECKSUMS_USE_IMPORT_EXPORT -DAWS_COMMON_USE_IMPORT_EXPORT + -DAWS_COMPRESSION_USE_IMPORT_EXPORT + -DAWS_CRT_CPP_USE_IMPORT_EXPORT -DAWS_EVENT_STREAM_USE_IMPORT_EXPORT + -DAWS_HTTP_USE_IMPORT_EXPORT -DAWS_IO_USE_IMPORT_EXPORT + -DAWS_MQTT_USE_IMPORT_EXPORT + -DAWS_MQTT_WITH_WEBSOCKETS + -DAWS_S3_USE_IMPORT_EXPORT + -DAWS_SDKUTILS_USE_IMPORT_EXPORT -DAWS_SDK_VERSION_MAJOR=1 - -DAWS_SDK_VERSION_MINOR=8 - -DAWS_SDK_VERSION_PATCH=186 + -DAWS_SDK_VERSION_MINOR=11 + -DAWS_SDK_VERSION_PATCH=37 + -DAWS_TEST_REGION=US_EAST_1 -DAWS_USE_EPOLL -DCURL_HAS_H2 -DCURL_HAS_TLS_PROXY + -DENABLED_REQUEST_COMPRESSION + -DENABLED_ZLIB_REQUEST_COMPRESSION -DENABLE_CURL_CLIENT -DENABLE_CURL_LOGGING -DENABLE_OPENSSL_ENCRYPTION -DHAS_PATHCONF -DHAS_UMASK - -DS2N_ADX - -DS2N_BIKE_R3_AVX2 - -DS2N_BIKE_R3_AVX512 - -DS2N_BIKE_R3_PCLMUL - -DS2N_BIKE_R3_VPCLMUL + -DS2N_CLONE_SUPPORTED -DS2N_CPUID_AVAILABLE -DS2N_FALL_THROUGH_SUPPORTED - -DS2N_HAVE_EXECINFO + -DS2N_FEATURES_AVAILABLE -DS2N_KYBER512R3_AVX2_BMI2 - -DS2N_SIKE_P434_R3_ASM + -DS2N_LIBCRYPTO_SUPPORTS_EVP_MD5_SHA1_HASH + -DS2N_LIBCRYPTO_SUPPORTS_EVP_MD_CTX_SET_PKEY_CTX + -DS2N_LIBCRYPTO_SUPPORTS_EVP_RC4 + -DS2N_MADVISE_SUPPORTED + -DS2N_PLATFORM_SUPPORTS_KTLS + -DS2N_STACKTRACE -DS2N___RESTRICT__SUPPORTED $<IF:$<CXX_COMPILER_ID:MSVC>,,-Wno-everything> ) @@ -46,8 +58,17 @@ target_link_libraries(libs-aws-sdk-cpp-aws-cpp-sdk-core PUBLIC contrib-libs-cxxsupp contrib-libs-curl contrib-libs-openssl + contrib-libs-zlib + restricted-aws-aws-c-auth + restricted-aws-aws-c-cal restricted-aws-aws-c-common restricted-aws-aws-c-event-stream + restricted-aws-aws-c-http + restricted-aws-aws-c-io + restricted-aws-aws-c-mqtt + restricted-aws-aws-c-sdkutils + restricted-aws-aws-checksums + restricted-aws-aws-crt-cpp ) target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonSerializableWebServiceRequest.cpp @@ -57,26 +78,52 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Globals.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Region.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Version.cpp - ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp - ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSignerProvider.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/SSOCredentialsProvider.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/STSCredentialsProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/DefaultBearerTokenProviderChain.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/SSOBearerTokenProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/BearerTokenAuthSignerProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/DefaultAuthSignerProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthBearerSigner.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthEventStreamV4Signer.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerCommon.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerHelper.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthV4Signer.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSNullSigner.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSClient.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSJsonClient.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSUrlPresigner.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSXmlClient.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AdaptiveRetryStrategy.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AsyncCallerContext.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/ClientConfiguration.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/CoreErrors.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/DefaultRetryStrategy.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/GenericClientConfiguration.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RequestCompression.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RetryStrategy.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/SpecifiedRetryableErrorsRetryStrategy.cpp - ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSConfigFileProfileConfigLoader.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoaderBase.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/ConfigAndCredentialsCacheManager.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/EC2InstanceProfileConfigLoader.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/defaults/ClientConfigurationDefaults.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/AWSEndpoint.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/AWSPartitions.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/BuiltInParameters.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/ClientContextParameters.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/DefaultEndpointProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/EndpointProviderBase.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/internal/AWSEndpointAttribute.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/cjson/cJSON.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/tinyxml2/tinyxml2.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClient.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClientFactory.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpRequest.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpResponse.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpTypes.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/Scheme.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp @@ -93,6 +140,7 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DNS.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DateTimeCommon.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Directory.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Document.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/EnumParseOverflowContainer.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/FileSystemUtils.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/GetTheLights.cpp @@ -101,6 +149,7 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/TempFile.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/UUID.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/base64/Base64.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CRC32.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Cipher.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoMaterial.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoScheme.cpp @@ -124,6 +173,8 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamErrors.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/AWSLogging.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/CRTLogSystem.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/CRTLogging.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/ConsoleLogSystem.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/DefaultLogSystem.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/FormattedLogSystem.cpp diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.linux-x86_64.txt b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.linux-x86_64.txt index 577d096b9a2..43002865c6e 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.linux-x86_64.txt +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.linux-x86_64.txt @@ -9,32 +9,44 @@ add_library(libs-aws-sdk-cpp-aws-cpp-sdk-core) target_compile_options(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE + -DAWS_AUTH_USE_IMPORT_EXPORT -DAWS_CAL_USE_IMPORT_EXPORT -DAWS_CHECKSUMS_USE_IMPORT_EXPORT -DAWS_COMMON_USE_IMPORT_EXPORT + -DAWS_COMPRESSION_USE_IMPORT_EXPORT + -DAWS_CRT_CPP_USE_IMPORT_EXPORT -DAWS_EVENT_STREAM_USE_IMPORT_EXPORT + -DAWS_HTTP_USE_IMPORT_EXPORT -DAWS_IO_USE_IMPORT_EXPORT + -DAWS_MQTT_USE_IMPORT_EXPORT + -DAWS_MQTT_WITH_WEBSOCKETS + -DAWS_S3_USE_IMPORT_EXPORT + -DAWS_SDKUTILS_USE_IMPORT_EXPORT -DAWS_SDK_VERSION_MAJOR=1 - -DAWS_SDK_VERSION_MINOR=8 - -DAWS_SDK_VERSION_PATCH=186 + -DAWS_SDK_VERSION_MINOR=11 + -DAWS_SDK_VERSION_PATCH=37 + -DAWS_TEST_REGION=US_EAST_1 -DAWS_USE_EPOLL -DCURL_HAS_H2 -DCURL_HAS_TLS_PROXY + -DENABLED_REQUEST_COMPRESSION + -DENABLED_ZLIB_REQUEST_COMPRESSION -DENABLE_CURL_CLIENT -DENABLE_CURL_LOGGING -DENABLE_OPENSSL_ENCRYPTION -DHAS_PATHCONF -DHAS_UMASK - -DS2N_ADX - -DS2N_BIKE_R3_AVX2 - -DS2N_BIKE_R3_AVX512 - -DS2N_BIKE_R3_PCLMUL - -DS2N_BIKE_R3_VPCLMUL + -DS2N_CLONE_SUPPORTED -DS2N_CPUID_AVAILABLE -DS2N_FALL_THROUGH_SUPPORTED - -DS2N_HAVE_EXECINFO + -DS2N_FEATURES_AVAILABLE -DS2N_KYBER512R3_AVX2_BMI2 - -DS2N_SIKE_P434_R3_ASM + -DS2N_LIBCRYPTO_SUPPORTS_EVP_MD5_SHA1_HASH + -DS2N_LIBCRYPTO_SUPPORTS_EVP_MD_CTX_SET_PKEY_CTX + -DS2N_LIBCRYPTO_SUPPORTS_EVP_RC4 + -DS2N_MADVISE_SUPPORTED + -DS2N_PLATFORM_SUPPORTS_KTLS + -DS2N_STACKTRACE -DS2N___RESTRICT__SUPPORTED $<IF:$<CXX_COMPILER_ID:MSVC>,,-Wno-everything> ) @@ -46,8 +58,17 @@ target_link_libraries(libs-aws-sdk-cpp-aws-cpp-sdk-core PUBLIC contrib-libs-cxxsupp contrib-libs-curl contrib-libs-openssl + contrib-libs-zlib + restricted-aws-aws-c-auth + restricted-aws-aws-c-cal restricted-aws-aws-c-common restricted-aws-aws-c-event-stream + restricted-aws-aws-c-http + restricted-aws-aws-c-io + restricted-aws-aws-c-mqtt + restricted-aws-aws-c-sdkutils + restricted-aws-aws-checksums + restricted-aws-aws-crt-cpp ) target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonSerializableWebServiceRequest.cpp @@ -57,26 +78,52 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Globals.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Region.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Version.cpp - ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp - ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSignerProvider.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/SSOCredentialsProvider.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/STSCredentialsProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/DefaultBearerTokenProviderChain.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/SSOBearerTokenProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/BearerTokenAuthSignerProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/DefaultAuthSignerProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthBearerSigner.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthEventStreamV4Signer.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerCommon.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerHelper.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthV4Signer.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSNullSigner.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSClient.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSJsonClient.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSUrlPresigner.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSXmlClient.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AdaptiveRetryStrategy.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AsyncCallerContext.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/ClientConfiguration.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/CoreErrors.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/DefaultRetryStrategy.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/GenericClientConfiguration.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RequestCompression.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RetryStrategy.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/SpecifiedRetryableErrorsRetryStrategy.cpp - ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSConfigFileProfileConfigLoader.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoaderBase.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/ConfigAndCredentialsCacheManager.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/EC2InstanceProfileConfigLoader.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/defaults/ClientConfigurationDefaults.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/AWSEndpoint.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/AWSPartitions.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/BuiltInParameters.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/ClientContextParameters.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/DefaultEndpointProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/EndpointProviderBase.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/internal/AWSEndpointAttribute.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/cjson/cJSON.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/tinyxml2/tinyxml2.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClient.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClientFactory.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpRequest.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpResponse.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpTypes.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/Scheme.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp @@ -93,6 +140,7 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DNS.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DateTimeCommon.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Directory.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Document.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/EnumParseOverflowContainer.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/FileSystemUtils.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/GetTheLights.cpp @@ -101,6 +149,7 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/TempFile.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/UUID.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/base64/Base64.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CRC32.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Cipher.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoMaterial.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoScheme.cpp @@ -124,6 +173,8 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamErrors.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/AWSLogging.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/CRTLogSystem.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/CRTLogging.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/ConsoleLogSystem.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/DefaultLogSystem.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/FormattedLogSystem.cpp diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.windows-x86_64.txt b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.windows-x86_64.txt index 604debb4b76..ad17203f81f 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.windows-x86_64.txt +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/CMakeLists.windows-x86_64.txt @@ -9,32 +9,44 @@ add_library(libs-aws-sdk-cpp-aws-cpp-sdk-core) target_compile_options(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE + -DAWS_AUTH_USE_IMPORT_EXPORT -DAWS_CAL_USE_IMPORT_EXPORT -DAWS_CHECKSUMS_USE_IMPORT_EXPORT -DAWS_COMMON_USE_IMPORT_EXPORT + -DAWS_COMPRESSION_USE_IMPORT_EXPORT + -DAWS_CRT_CPP_USE_IMPORT_EXPORT -DAWS_EVENT_STREAM_USE_IMPORT_EXPORT + -DAWS_HTTP_USE_IMPORT_EXPORT -DAWS_IO_USE_IMPORT_EXPORT + -DAWS_MQTT_USE_IMPORT_EXPORT + -DAWS_MQTT_WITH_WEBSOCKETS + -DAWS_S3_USE_IMPORT_EXPORT + -DAWS_SDKUTILS_USE_IMPORT_EXPORT -DAWS_SDK_VERSION_MAJOR=1 - -DAWS_SDK_VERSION_MINOR=8 - -DAWS_SDK_VERSION_PATCH=186 + -DAWS_SDK_VERSION_MINOR=11 + -DAWS_SDK_VERSION_PATCH=37 + -DAWS_TEST_REGION=US_EAST_1 -DAWS_USE_EPOLL -DCURL_HAS_H2 -DCURL_HAS_TLS_PROXY + -DENABLED_REQUEST_COMPRESSION + -DENABLED_ZLIB_REQUEST_COMPRESSION -DENABLE_CURL_CLIENT -DENABLE_CURL_LOGGING -DENABLE_OPENSSL_ENCRYPTION -DHAS_PATHCONF -DHAS_UMASK - -DS2N_ADX - -DS2N_BIKE_R3_AVX2 - -DS2N_BIKE_R3_AVX512 - -DS2N_BIKE_R3_PCLMUL - -DS2N_BIKE_R3_VPCLMUL + -DS2N_CLONE_SUPPORTED -DS2N_CPUID_AVAILABLE -DS2N_FALL_THROUGH_SUPPORTED - -DS2N_HAVE_EXECINFO + -DS2N_FEATURES_AVAILABLE -DS2N_KYBER512R3_AVX2_BMI2 - -DS2N_SIKE_P434_R3_ASM + -DS2N_LIBCRYPTO_SUPPORTS_EVP_MD5_SHA1_HASH + -DS2N_LIBCRYPTO_SUPPORTS_EVP_MD_CTX_SET_PKEY_CTX + -DS2N_LIBCRYPTO_SUPPORTS_EVP_RC4 + -DS2N_MADVISE_SUPPORTED + -DS2N_PLATFORM_SUPPORTS_KTLS + -DS2N_STACKTRACE -DS2N___RESTRICT__SUPPORTED $<IF:$<CXX_COMPILER_ID:MSVC>,,-Wno-everything> ) @@ -45,8 +57,17 @@ target_link_libraries(libs-aws-sdk-cpp-aws-cpp-sdk-core PUBLIC contrib-libs-cxxsupp contrib-libs-curl contrib-libs-openssl + contrib-libs-zlib + restricted-aws-aws-c-auth + restricted-aws-aws-c-cal restricted-aws-aws-c-common restricted-aws-aws-c-event-stream + restricted-aws-aws-c-http + restricted-aws-aws-c-io + restricted-aws-aws-c-mqtt + restricted-aws-aws-c-sdkutils + restricted-aws-aws-checksums + restricted-aws-aws-crt-cpp ) target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonSerializableWebServiceRequest.cpp @@ -56,26 +77,52 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Globals.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Region.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Version.cpp - ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp - ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSignerProvider.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/SSOCredentialsProvider.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/STSCredentialsProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/DefaultBearerTokenProviderChain.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/SSOBearerTokenProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/BearerTokenAuthSignerProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/DefaultAuthSignerProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthBearerSigner.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthEventStreamV4Signer.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerCommon.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerHelper.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthV4Signer.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSNullSigner.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSClient.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSJsonClient.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSUrlPresigner.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSXmlClient.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AdaptiveRetryStrategy.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AsyncCallerContext.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/ClientConfiguration.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/CoreErrors.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/DefaultRetryStrategy.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/GenericClientConfiguration.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RequestCompression.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/RetryStrategy.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/SpecifiedRetryableErrorsRetryStrategy.cpp - ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSConfigFileProfileConfigLoader.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoaderBase.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/ConfigAndCredentialsCacheManager.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/EC2InstanceProfileConfigLoader.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/defaults/ClientConfigurationDefaults.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/AWSEndpoint.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/AWSPartitions.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/BuiltInParameters.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/ClientContextParameters.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/DefaultEndpointProvider.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/EndpointProviderBase.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/internal/AWSEndpointAttribute.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/cjson/cJSON.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/tinyxml2/tinyxml2.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClient.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClientFactory.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpRequest.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpResponse.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpTypes.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/Scheme.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp @@ -92,6 +139,7 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DNS.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DateTimeCommon.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Directory.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Document.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/EnumParseOverflowContainer.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/FileSystemUtils.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/GetTheLights.cpp @@ -100,6 +148,7 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/TempFile.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/UUID.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/base64/Base64.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CRC32.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Cipher.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoMaterial.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoScheme.cpp @@ -123,6 +172,8 @@ target_sources(libs-aws-sdk-cpp-aws-cpp-sdk-core PRIVATE ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamErrors.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/AWSLogging.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/CRTLogSystem.cpp + ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/CRTLogging.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/ConsoleLogSystem.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/DefaultLogSystem.cpp ${CMAKE_SOURCE_DIR}/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/FormattedLogSystem.cpp diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonWebServiceRequest.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonWebServiceRequest.h index 1fc7c0e7e00..35783070220 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonWebServiceRequest.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonWebServiceRequest.h @@ -7,13 +7,16 @@ #include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/UnreferencedParam.h> -#include <aws/core/http/HttpTypes.h> +#include <aws/core/client/RequestCompression.h> +#include <aws/core/auth/AWSAuthSigner.h> +#include <aws/core/client/CoreErrors.h> +#include <aws/core/endpoint/EndpointParameter.h> #include <aws/core/http/HttpRequest.h> +#include <aws/core/http/HttpTypes.h> +#include <aws/core/utils/UnreferencedParam.h> #include <aws/core/utils/memory/stl/AWSStreamFwd.h> +#include <aws/core/utils/memory/stl/AWSString.h> #include <aws/core/utils/stream/ResponseStream.h> -#include <aws/core/auth/AWSAuthSigner.h> namespace Aws { @@ -51,12 +54,21 @@ namespace Aws */ virtual Aws::Http::HeaderValueCollection GetHeaders() const = 0; /** + * Get the additional user-set custom headers for the request + */ + virtual const Aws::Http::HeaderValueCollection& GetAdditionalCustomHeaders() const; + /** + * Set an additional custom header value under a key. This value will overwrite any previously set or regular header. + */ + virtual void SetAdditionalCustomHeaderValue(const Aws::String& headerName, const Aws::String& headerValue); + + /** * Do nothing virtual, override this to add query strings to the request */ virtual void AddQueryStringParameters(Aws::Http::URI& uri) const { AWS_UNREFERENCED_PARAM(uri); } /** - * Put the request to a url for later presigning. This will push the body to the url and + * Put the request to a url for later presigning. This will push the body to the url and * then adds the existing query string parameters as normal. */ virtual void PutToPresignedUrl(Aws::Http::URI& uri) const { DumpBodyToUrl(uri); AddQueryStringParameters(uri); } @@ -76,6 +88,15 @@ namespace Aws virtual bool SignBody() const { return true; } /** + * Defaults to false, if a derived class returns true it indicates that the body has an embedded error. + */ + virtual bool HasEmbeddedError(Aws::IOStream& body, const Aws::Http::HeaderValueCollection& header) const { + (void) body; + (void) header; + return false; + } + + /** * Defaults to false, if this is set to true, it supports chunked transfer encoding. */ virtual bool IsChunked() const { return false; } @@ -150,15 +171,28 @@ namespace Aws */ inline virtual bool ShouldComputeContentMd5() const { return false; } + inline virtual bool ShouldValidateResponseChecksum() const { return false; } + + inline virtual Aws::Vector<Aws::String> GetResponseChecksumAlgorithmNames() const { return {}; } + + inline virtual Aws::String GetChecksumAlgorithmName() const { return {}; } + virtual const char* GetServiceRequestName() const = 0; + using EndpointParameters = Aws::Vector<Aws::Endpoint::EndpointParameter>; + virtual EndpointParameters GetEndpointContextParams() const; + + virtual Aws::Client::CompressionAlgorithm + GetSelectedCompressionAlgorithm(Aws::Client::RequestCompressionConfig) const { return Aws::Client::CompressionAlgorithm::NONE; } + protected: /** - * Default does nothing. Override this to convert what would otherwise be the payload of the + * Default does nothing. Override this to convert what would otherwise be the payload of the * request to a query string format. */ virtual void DumpBodyToUrl(Aws::Http::URI& uri) const { AWS_UNREFERENCED_PARAM(uri); } + Aws::Http::HeaderValueCollection m_additionalCustomHeaders; private: Aws::IOStreamFactory m_responseStreamFactory; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonWebServiceResult.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonWebServiceResult.h index cde25d80f6f..37538accb71 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonWebServiceResult.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonWebServiceResult.h @@ -57,7 +57,7 @@ namespace Aws /** * Get the payload from the response and take ownership of it. */ - inline PAYLOAD_TYPE TakeOwnershipOfPayload() { return std::move(m_payload); } + inline PAYLOAD_TYPE&& TakeOwnershipOfPayload() { return std::move(m_payload); } /** * Get the headers from the response */ diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Aws.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Aws.h index 7c2d7af53f4..03f965a3e6c 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Aws.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Aws.h @@ -6,11 +6,14 @@ #include <aws/core/utils/logging/LogLevel.h> #include <aws/core/utils/logging/LogSystemInterface.h> +#include <aws/core/utils/logging/CRTLogSystem.h> #include <aws/core/utils/memory/MemorySystemInterface.h> #include <aws/core/utils/crypto/Factories.h> #include <aws/core/http/HttpClientFactory.h> #include <aws/core/monitoring/MonitoringManager.h> #include <aws/core/Core_EXPORTS.h> +#include <aws/crt/io/Bootstrap.h> +#include <aws/crt/io/TlsOptions.h> namespace Aws { @@ -35,10 +38,16 @@ namespace Aws const char* defaultLogPrefix; /** - * Defaults to empty, if logLevel has been set and this field is empty, then the default log interface will be used. + * Defaults to empty, if logLevel has been set and this field is empty, then the default log system will be used. * otherwise, we will call this closure to create a logger */ std::function<std::shared_ptr<Aws::Utils::Logging::LogSystemInterface>()> logger_create_fn; + + /** + * Defaults to empty, if logLevel has been set and this field is empty, then the default CRT log system will be used. + * The default CRT log system will redirect all logs from common runtime libraries (CRT) to C++ SDK with the same log level and formatting. + */ + std::function<std::shared_ptr<Aws::Utils::Logging::CRTLogSystemInterface>()> crt_logger_create_fn; }; /** @@ -58,11 +67,20 @@ namespace Aws }; /** + * SDK wide options for I/O: client bootstrap and TLS connection options + */ + struct IoOptions + { + std::function<std::shared_ptr<Aws::Crt::Io::ClientBootstrap>()> clientBootstrap_create_fn; + std::function<std::shared_ptr<Aws::Crt::Io::TlsConnectionOptions>()> tlsConnectionOptions_create_fn; + }; + + /** * SDK wide options for http */ struct HttpOptions { - HttpOptions() : initAndCleanupCurl(true), installSigPipeHandler(false) + HttpOptions() : initAndCleanupCurl(true), installSigPipeHandler(false), compliantRfc3986Encoding(false) { } /** @@ -82,6 +100,10 @@ namespace Aws * NOTE: CURLOPT_NOSIGNAL is already being set. */ bool installSigPipeHandler; + /** + * Disable legacy URL encoding that leaves `$&,:@=` unescaped for legacy purposes. + */ + bool compliantRfc3986Encoding; }; /** @@ -194,6 +216,10 @@ namespace Aws struct SDKOptions { /** + * SDK wide options for I/O: client bootstrap and TLS connection options + */ + IoOptions ioOptions; + /** * SDK wide options for logging */ LoggingOptions loggingOptions; @@ -260,7 +286,10 @@ namespace Aws /** * Shutdown SDK wide state for the SDK. This method must be called when you are finished using the SDK. - * Do not call any other SDK methods after calling ShutdownAPI. + * Notes: + * 1) Please call this from the same thread from which InitAPI() has been called (use a dedicated thread + * if necessary). This avoids problems in initializing the dependent Common RunTime C libraries. + * 2) Do not call any other SDK methods after calling ShutdownAPI. */ AWS_CORE_API void ShutdownAPI(const SDKOptions& options); } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Core_EXPORTS.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Core_EXPORTS.h index 12e9dfc9beb..1d3e312a607 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Core_EXPORTS.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Core_EXPORTS.h @@ -21,8 +21,14 @@ #else // USE_IMPORT_EXPORT #define AWS_CORE_API #endif // USE_IMPORT_EXPORT + #define AWS_CORE_LOCAL #else // defined (USE_WINDOWS_DLL_SEMANTICS) || defined (_WIN32) #define AWS_CORE_API + #if __GNUC__ >= 4 + #define AWS_CORE_LOCAL __attribute__((visibility("hidden"))) + #else + #define AWS_CORE_LOCAL + #endif #endif // defined (USE_WINDOWS_DLL_SEMANTICS) || defined (_WIN32) #ifdef _MSC_VER diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Globals.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Globals.h index cebe4891b77..08dfafce09d 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Globals.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Globals.h @@ -9,6 +9,54 @@ namespace Aws { + namespace Crt + { + class ApiHandle; + + namespace Io + { + class ClientBootstrap; + class TlsConnectionOptions; + + } + } + + /** + * Like we need to call InitAPI() to initialize aws-sdk-cpp, we need ApiHandle to initialize aws-crt-cpp, which is a wrapper of a collection of common runtime libraries. + * We will wrap the memory management system and pass it to common runtime libraries via ApiHandle. + */ + AWS_CORE_API Aws::Crt::ApiHandle* GetApiHandle(); + + /** + * Set the default ClientBootStrap for AWS common runtime libraries in the global scope. + */ + AWS_CORE_API void SetDefaultClientBootstrap(const std::shared_ptr<Aws::Crt::Io::ClientBootstrap>& clientBootstrap); + + /** + * Get the default ClientBootStrap for AWS common runtime libraries in the global scope. + */ + AWS_CORE_API Aws::Crt::Io::ClientBootstrap* GetDefaultClientBootstrap(); + + /** + * Set the default TlsConnectionOptions for AWS common runtime libraries in the global scope. + */ + AWS_CORE_API void SetDefaultTlsConnectionOptions(const std::shared_ptr<Aws::Crt::Io::TlsConnectionOptions>& tlsConnectionOptions); + + /** + * Get the default TlsConnectionOptions for AWS common runtime libraries in the global scope. + */ + AWS_CORE_API Aws::Crt::Io::TlsConnectionOptions* GetDefaultTlsConnectionOptions(); + + /** + * Initialize ApiHandle in aws-crt-cpp. + */ + void InitializeCrt(); + + /** + * Clean up ApiHandle in aws-crt-cpp. + */ + void CleanupCrt(); + namespace Utils { class EnumParseOverflowContainer; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Region.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Region.h index a728c829ed3..9bfeba1ad36 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Region.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Region.h @@ -20,33 +20,42 @@ namespace Aws // You can specify this region to corresponding environment variable, config file item and in your code. // For services without global region, the request will be directed to us-east-1 static const char AWS_GLOBAL[] = "aws-global"; - static const char US_EAST_1[] = "us-east-1"; - static const char US_EAST_2[] = "us-east-2"; - static const char US_WEST_1[] = "us-west-1"; - static const char US_WEST_2[] = "us-west-2"; - static const char AF_SOUTH_1[] = "af-south-1"; - static const char EU_WEST_1[] = "eu-west-1"; - static const char EU_WEST_2[] = "eu-west-2"; - static const char EU_WEST_3[] = "eu-west-3"; - static const char EU_CENTRAL_1[] = "eu-central-1"; - static const char EU_NORTH_1[] = "eu-north-1"; - static const char AP_EAST_1[] = "ap-east-1"; - static const char AP_SOUTH_1[] = "ap-south-1"; - static const char AP_SOUTHEAST_1[] = "ap-southeast-1"; - static const char AP_SOUTHEAST_2[] = "ap-southeast-2"; - static const char AP_NORTHEAST_1[] = "ap-northeast-1"; - static const char AP_NORTHEAST_2[] = "ap-northeast-2"; - static const char AP_NORTHEAST_3[] = "ap-northeast-3"; - static const char SA_EAST_1[] = "sa-east-1"; - static const char CA_CENTRAL_1[] = "ca-central-1"; - static const char CN_NORTH_1[] = "cn-north-1"; - static const char CN_NORTHWEST_1[] = "cn-northwest-1"; - static const char ME_SOUTH_1[] = "me-south-1"; - static const char US_GOV_WEST_1[] = "us-gov-west-1"; - static const char US_GOV_EAST_1[] = "us-gov-east-1"; + static const char US_EAST_1[] = "us-east-1"; // US East (N. Virginia) + static const char US_EAST_2[] = "us-east-2"; // US East (Ohio) + static const char US_WEST_1[] = "us-west-1"; // US West (N. California) + static const char US_WEST_2[] = "us-west-2"; // US West (Oregon) + static const char EU_WEST_1[] = "eu-west-1"; // EU (Ireland) + static const char EU_WEST_2[] = "eu-west-2"; // EU (London) + static const char EU_WEST_3[] = "eu-west-3"; // EU (Paris) + static const char EU_CENTRAL_1[] = "eu-central-1"; // "EU (Frankfurt) + static const char EU_NORTH_1[] = "eu-north-1"; // EU (Stockholm) + static const char EU_SOUTH_1[] = "eu-south-1"; // EU (Milan) + static const char AP_EAST_1[] = "ap-east-1"; // Asia Pacific (Hong Kong) + static const char AP_SOUTH_1[] = "ap-south-1"; // Asia Pacific (Mumbai) + static const char AP_SOUTHEAST_1[] = "ap-southeast-1"; // Asia Pacific (Singapore) + static const char AP_SOUTHEAST_2[] = "ap-southeast-2"; // Asia Pacific (Sydney) + static const char AP_SOUTHEAST_3[] = "ap-southeast-3"; // Asia Pacific (Jakarta) + static const char AP_NORTHEAST_1[] = "ap-northeast-1"; // Asia Pacific (Tokyo) + static const char AP_NORTHEAST_2[] = "ap-northeast-2"; // Asia Pacific (Seoul) + static const char AP_NORTHEAST_3[] = "ap-northeast-3"; // Asia Pacific (Osaka) + static const char SA_EAST_1[] = "sa-east-1"; // South America (Sao Paulo + static const char CN_NORTH_1[] = "cn-north-1"; // China (Beijing) + static const char CN_NORTHWEST_1[] = "cn-northwest-1"; // China (Ningxia) + static const char CA_CENTRAL_1[] = "ca-central-1"; // Canada (Central) + static const char ME_SOUTH_1[] = "me-south-1"; // Middle East (Bahrain) + static const char ME_CENTRAL_1[] = "me-central-1"; // Middle East (UEA) + static const char AF_SOUTH_1[] = "af-south-1"; // Africa (Cape Town) + static const char US_GOV_WEST_1[] = "us-gov-west-1"; // AWS GovCloud (US-West) + static const char US_GOV_EAST_1[] = "us-gov-east-1"; // AWS GovCloud (US-East) + static const char US_ISO_EAST_1[] = "us-iso-east-1"; // US ISO East + static const char US_ISOB_EAST_1[] = "us-isob-east-1"; // US ISOB East (Ohio) + static const char US_ISO_WEST_1[] = "us-iso-west-1"; // US ISO West // If a pseudo region, for example, aws-global or us-east-1-fips is provided, it should be converted to the region name used for signing. Aws::String AWS_CORE_API ComputeSignerRegion(const Aws::String& region); + + // A FIPs region starts with "fips-" or ends with "-fips". + bool AWS_CORE_API IsFipsRegion(const Aws::String& region); } } // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/VersionConfig.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/VersionConfig.h index fd965734a6c..0dedf23c9a1 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/VersionConfig.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/VersionConfig.h @@ -2,5 +2,9 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ +#pragma once -#define AWS_SDK_VERSION_STRING "1.8.186" +#define AWS_SDK_VERSION_STRING "1.11.37" +#define AWS_SDK_VERSION_MAJOR 1 +#define AWS_SDK_VERSION_MINOR 11 +#define AWS_SDK_VERSION_PATCH 37 diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSAuthSigner.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSAuthSigner.h index 8061ee1e251..0c4a26dbd32 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSAuthSigner.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSAuthSigner.h @@ -5,421 +5,11 @@ #pragma once -#include <aws/core/Core_EXPORTS.h> +#include <aws/core/auth/signer/AWSAuthSignerBase.h> +#include <aws/core/auth/signer/AWSAuthSignerCommon.h> -#include <aws/core/Region.h> -#include <aws/core/utils/memory/AWSMemory.h> -#include <aws/core/utils/memory/stl/AWSSet.h> -#include <aws/core/utils/DateTime.h> -#include <aws/core/utils/Array.h> -#include <aws/core/utils/threading/ReaderWriterLock.h> -#include <aws/core/utils/crypto/Sha256.h> -#include <aws/core/utils/crypto/Sha256HMAC.h> - -#include <memory> -#include <atomic> -#include <chrono> - -namespace Aws -{ - namespace Http - { - class HttpClientFactory; - class HttpRequest; - } // namespace Http - - namespace Utils - { - namespace Event - { - class Message; - } - } // namespace Utils - - namespace Auth - { - class AWSCredentials; - class AWSCredentialsProvider; - AWS_CORE_API extern const char SIGV4_SIGNER[]; - AWS_CORE_API extern const char EVENTSTREAM_SIGV4_SIGNER[]; - AWS_CORE_API extern const char SIGNATURE[]; - AWS_CORE_API extern const char NULL_SIGNER[]; - } // namespace Auth - - namespace Client - { - struct ClientConfiguration; - - /** - * Auth Signer interface. Takes a generic AWS request and applies crypto tamper resistent signatures on the request. - */ - class AWS_CORE_API AWSAuthSigner - { - public: - AWSAuthSigner() : m_clockSkew() { m_clockSkew.store(std::chrono::milliseconds(0L)); } - virtual ~AWSAuthSigner() = default; - - /** - * Signs the request itself (usually by adding a signature header) based on info in the request and uri. - */ - virtual bool SignRequest(Aws::Http::HttpRequest& request) const = 0; - - /** - * Signs the request itself (usually by adding a signature header) based on info in the request and uri. - * If signBody is false and https is being used then the body of the payload will not be signed. - * The default virtual function, just calls SignRequest. - */ - virtual bool SignRequest(Aws::Http::HttpRequest& request, bool signBody) const - { - AWS_UNREFERENCED_PARAM(signBody); - return SignRequest(request); - } - - /** - * Signs the request itself (usually by adding a signature header) based on info in the request and uri. - * If signBody is false and https is being used then the body of the payload will not be signed. - * The default virtual function, just calls SignRequest. - * Using m_region by default if parameter region is nullptr. - */ - virtual bool SignRequest(Aws::Http::HttpRequest& request, const char* region, bool signBody) const - { - AWS_UNREFERENCED_PARAM(signBody); - AWS_UNREFERENCED_PARAM(region); - return SignRequest(request); - } - - /** - * Signs the request itself (usually by adding a signature header) based on info in the request and uri. - * If signBody is false and https is being used then the body of the payload will not be signed. - * The default virtual function, just calls SignRequest. - * Using m_region by default if parameter region is nullptr. - * Using m_serviceName by default if parameter serviceName is nullptr. - */ - virtual bool SignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, bool signBody) const - { - AWS_UNREFERENCED_PARAM(signBody); - AWS_UNREFERENCED_PARAM(region); - AWS_UNREFERENCED_PARAM(serviceName); - return SignRequest(request); - } - - /** - * Signs a single event message in an event stream. - * The input message buffer is copied and signed. The message's input buffer will be deallocated and a new - * buffer will be assigned. The new buffer encodes the original message with its headers as the payload of - * the new message. The signature of the original message will be added as a header to the new message. - * - * A Hex encoded signature of the previous event (or of the HTTP request headers in case of the first event) - * is provided as the 'priorSignature' parameter. 'priorSignature' will contain the value of the new - * signature after this call returns successfully. - * - * The function returns true if the message is successfully signed. - */ - virtual bool SignEventMessage(Aws::Utils::Event::Message&, Aws::String& /* priorSignature */) const { return false; } - - /** - * Takes a request and signs the URI based on the HttpMethod, URI and other info from the request. - * The URI can then be used in a normal HTTP call until expiration. - */ - virtual bool PresignRequest(Aws::Http::HttpRequest& request, long long expirationInSeconds) const = 0; - - /** - * Generates a signed Uri using the injected signer. for the supplied uri and http method and region. expirationInSeconds defaults - * to 0 which is the default 7 days. - * Using m_region by default if parameter region is nullptr. - */ - virtual bool PresignRequest(Aws::Http::HttpRequest& request, const char* region, long long expirationInSeconds = 0) const = 0; - - /** - * Generates a signed Uri using the injected signer. for the supplied uri and http method, region, and service name. expirationInSeconds defaults - * to 0 which is the default 7 days. - * Using m_region by default if parameter region is nullptr. - * Using m_serviceName by default if parameter serviceName is nullptr. - */ - virtual bool PresignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, long long expirationInSeconds = 0) const = 0; - - /** - * Return the signer's name - */ - virtual const char* GetName() const = 0; - - /** - * This handles detection of clock skew between clients and the server and adjusts the clock so that the next request will not - * fail on the timestamp check. - */ - virtual void SetClockSkew(const std::chrono::milliseconds& clockSkew) { m_clockSkew = clockSkew; } - - /** - * Gets the timestamp being used by the signer. This may include a clock skew if a clock skew has been detected. - */ - virtual Aws::Utils::DateTime GetSigningTimestamp() const { return Aws::Utils::DateTime::Now() + GetClockSkewOffset(); } - - protected: - virtual std::chrono::milliseconds GetClockSkewOffset() const { return m_clockSkew.load(); } - - std::atomic<std::chrono::milliseconds> m_clockSkew; - }; - - /** - * AWS Auth v4 Signer implementation of the AWSAuthSigner interface. More information on AWS Auth v4 Can be found here: - * http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html - */ - class AWS_CORE_API AWSAuthV4Signer : public AWSAuthSigner - { - - public: - /** - * Even though different payload signing polices, HTTP will force payload signing to be on. - */ - enum class PayloadSigningPolicy - { - /** - * Sign the request based on the value returned by AmazonWebServiceRequest::SignBody() - */ - RequestDependent, - /** - * Always sign the body of the request. - */ - Always, - /** - * Never sign the body of the request - */ - Never - }; - /** - * credentialsProvider, source of AWS Credentials to sign requests with - * serviceName, canonical service name to sign with - * region, region string to use in signature - * signPayloads, if Always, the payload will have a sha256 computed on the body of the request. If this is set - * to Never, the sha256 will not be computed on the body. This is only useful for Amazon S3 over Https. If - * Https is not used then this flag will be ignored. If set to RequestDependent, compute or not is based on - * the value from AmazonWebServiceRequest::SignBody() - */ - AWSAuthV4Signer(const std::shared_ptr<Auth::AWSCredentialsProvider>& credentialsProvider, - const char* serviceName, const Aws::String& region, PayloadSigningPolicy signingPolicy = PayloadSigningPolicy::RequestDependent, - bool urlEscapePath = true); - - virtual ~AWSAuthV4Signer(); - - /** - * AWSAuthV4signer's implementation of virtual function from base class - * Return Auth Signer's name, here the value is specified in Aws::Auth::DEFAULT_AUTHV4_SIGNER. - */ - const char* GetName() const override { return Aws::Auth::SIGV4_SIGNER; } - - /** - * Signs the request itself based on info in the request and uri. - * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. - */ - bool SignRequest(Aws::Http::HttpRequest& request) const override - { - return SignRequest(request, m_region.c_str(), m_serviceName.c_str(), true/*signBody*/); - } - - /** - * Signs the request itself based on info in the request and uri. - * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. If signBody is false - * and https is being used then the body of the payload will not be signed. - */ - bool SignRequest(Aws::Http::HttpRequest& request, bool signBody) const override - { - return SignRequest(request, m_region.c_str(), m_serviceName.c_str(), signBody); - } - - /** - * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. If signBody is false - * and https is being used then the body of the payload will not be signed. - * Using m_region by default if parameter region is nullptr. - */ - bool SignRequest(Aws::Http::HttpRequest& request, const char* region, bool signBody) const override - { - return SignRequest(request, region, m_serviceName.c_str(), signBody); - } - - /** - * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. If signBody is false - * and https is being used then the body of the payload will not be signed. - * Using m_region by default if parameter region is nullptr. - */ - bool SignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, bool signBody) const override; - - /** - * Takes a request and signs the URI based on the HttpMethod, URI and other info from the request. - * the region the signer was initialized with will be used for the signature. - * The URI can then be used in a normal HTTP call until expiration. - * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. - * expirationInSeconds defaults to 0 which provides a URI good for 7 days. - */ - bool PresignRequest(Aws::Http::HttpRequest& request, long long expirationInSeconds = 0) const override; - - /** - * Takes a request and signs the URI based on the HttpMethod, URI and other info from the request. - * The URI can then be used in a normal HTTP call until expiration. - * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. - * expirationInSeconds defaults to 0 which provides a URI good for 7 days. - * Using m_region by default if parameter region is nullptr. - */ - bool PresignRequest(Aws::Http::HttpRequest& request, const char* region, long long expirationInSeconds = 0) const override; - - /** - * Takes a request and signs the URI based on the HttpMethod, URI and other info from the request. - * The URI can then be used in a normal HTTP call until expiration. - * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. - * expirationInSeconds defaults to 0 which provides a URI good for 7 days. - * Using m_region by default if parameter region is nullptr. - * Using m_serviceName by default if parameter serviceName is nullptr. - */ - bool PresignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, long long expirationInSeconds = 0) const override; - - Aws::String GetServiceName() const { return m_serviceName; } - Aws::String GetRegion() const { return m_region; } - Aws::String GenerateSignature(const Aws::Auth::AWSCredentials& credentials, - const Aws::String& stringToSign, const Aws::String& simpleDate) const; - bool ShouldSignHeader(const Aws::String& header) const; - - protected: - bool m_includeSha256HashHeader; - - private: - - Aws::String GenerateSignature(const Aws::Auth::AWSCredentials& credentials, - const Aws::String& stringToSign, const Aws::String& simpleDate, const Aws::String& region, - const Aws::String& serviceName) const; - - Aws::String GenerateSignature(const Aws::String& stringToSign, const Aws::Utils::ByteBuffer& key) const; - bool ServiceRequireUnsignedPayload(const Aws::String& serviceName) const; - Aws::String ComputePayloadHash(Aws::Http::HttpRequest&) const; - Aws::String GenerateStringToSign(const Aws::String& dateValue, const Aws::String& simpleDate, - const Aws::String& canonicalRequestHash, const Aws::String& region, - const Aws::String& serviceName) const; - Aws::Utils::ByteBuffer ComputeHash(const Aws::String& secretKey, const Aws::String& simpleDate) const; - Aws::Utils::ByteBuffer ComputeHash(const Aws::String& secretKey, - const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const; - - - std::shared_ptr<Auth::AWSCredentialsProvider> m_credentialsProvider; - const Aws::String m_serviceName; - const Aws::String m_region; - Aws::UniquePtr<Aws::Utils::Crypto::Sha256> m_hash; - Aws::UniquePtr<Aws::Utils::Crypto::Sha256HMAC> m_HMAC; - - Aws::Set<Aws::String> m_unsignedHeaders; - - //these next four fields are ONLY for caching purposes and do not change - //the logical state of the signer. They are marked mutable so the - //interface can remain const. - mutable Aws::Utils::ByteBuffer m_partialSignature; - mutable Aws::String m_currentDateStr; - mutable Aws::String m_currentSecretKey; - mutable Utils::Threading::ReaderWriterLock m_partialSignatureLock; - PayloadSigningPolicy m_payloadSigningPolicy; - bool m_urlEscapePath; - }; - - class AWS_CORE_API AWSAuthEventStreamV4Signer : public AWSAuthSigner - { - public: - AWSAuthEventStreamV4Signer(const std::shared_ptr<Auth::AWSCredentialsProvider>& credentialsProvider, - const char* serviceName, const Aws::String& region); - - const char* GetName() const override { return Aws::Auth::EVENTSTREAM_SIGV4_SIGNER; } - - bool SignEventMessage(Aws::Utils::Event::Message&, Aws::String& priorSignature) const override; - - bool SignRequest(Aws::Http::HttpRequest& request) const override - { - return SignRequest(request, m_region.c_str(), m_serviceName.c_str(), true); - } - - bool SignRequest(Aws::Http::HttpRequest& request, bool signBody) const override - { - return SignRequest(request, m_region.c_str(), m_serviceName.c_str(), signBody); - } - - bool SignRequest(Aws::Http::HttpRequest& request, const char* region, bool signBody) const override - { - return SignRequest(request, region, m_serviceName.c_str(), signBody); - } - - bool SignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, bool signBody) const override; - - /** - * Do nothing - */ - bool PresignRequest(Aws::Http::HttpRequest&, long long) const override { return false; } - - /** - * Do nothing - */ - bool PresignRequest(Aws::Http::HttpRequest&, const char*, long long) const override { return false; } - - /** - * Do nothing - */ - bool PresignRequest(Aws::Http::HttpRequest&, const char*, const char*, long long) const override { return false; } - - bool ShouldSignHeader(const Aws::String& header) const; - private: - Utils::ByteBuffer GenerateSignature(const Aws::Auth::AWSCredentials& credentials, - const Aws::String& stringToSign, const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const; - Utils::ByteBuffer GenerateSignature(const Aws::String& stringToSign, const Aws::Utils::ByteBuffer& key) const; - Aws::String GenerateStringToSign(const Aws::String& dateValue, const Aws::String& simpleDate, - const Aws::String& canonicalRequestHash, const Aws::String& region, - const Aws::String& serviceName) const; - Aws::Utils::ByteBuffer ComputeHash(const Aws::String& secretKey, const Aws::String& simpleDate) const; - Aws::Utils::ByteBuffer ComputeHash(const Aws::String& secretKey, - const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const; - const Aws::String m_serviceName; - const Aws::String m_region; - mutable Aws::Utils::Crypto::Sha256 m_hash; - mutable Aws::Utils::Crypto::Sha256HMAC m_HMAC; - mutable Utils::Threading::ReaderWriterLock m_derivedKeyLock; - mutable Aws::Utils::ByteBuffer m_derivedKey; - mutable Aws::String m_currentDateStr; - mutable Aws::String m_currentSecretKey; - Aws::Vector<Aws::String> m_unsignedHeaders; - std::shared_ptr<Auth::AWSCredentialsProvider> m_credentialsProvider; - }; - - - /** - * A no-op implementation of the AWSAuthSigner interface - */ - class AWS_CORE_API AWSNullSigner : public AWSAuthSigner - { - public: - /** - * AWSNullSigner's implementation of virtual function from base class - * Here the returned value is specified in Aws::Auth::NULL_SIGNER. - */ - const char* GetName() const override { return Aws::Auth::NULL_SIGNER; } - - /** - * Do nothing - */ - bool SignRequest(Aws::Http::HttpRequest&) const override { return true; } - - /** - * Do nothing - */ - bool SignEventMessage(Aws::Utils::Event::Message&, Aws::String& /* priorSignature */) const override { return true; } - - /** - * Do nothing - */ - bool PresignRequest(Aws::Http::HttpRequest&, long long) const override { return false; } - - /** - * Do nothing - */ - bool PresignRequest(Aws::Http::HttpRequest&, const char*, long long) const override { return false; } - - /** - * Do nothing - */ - bool PresignRequest(Aws::Http::HttpRequest&, const char*, const char*, long long) const override { return false; } - }; - - } // namespace Client -} // namespace Aws +#include <aws/core/auth/signer/AWSAuthV4Signer.h> +#include <aws/core/auth/signer/AWSAuthEventStreamV4Signer.h> +#include <aws/core/auth/signer/AWSNullSigner.h> +// This is a header that represents old legacy all-in-one header to maintain backward compatibility diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSAuthSignerProvider.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSAuthSignerProvider.h index 305c58cd9d9..b27d0792845 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSAuthSignerProvider.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSAuthSignerProvider.h @@ -6,48 +6,7 @@ #pragma once -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/memory/stl/AWSVector.h> -#include <memory> +#include <aws/core/auth/signer-provider/AWSAuthSignerProviderBase.h> +#include <aws/core/auth/signer-provider/DefaultAuthSignerProvider.h> - -namespace Aws -{ - namespace Client - { - class AWSAuthSigner; - } - namespace Auth - { - class AWSCredentialsProvider; - - class AWS_CORE_API AWSAuthSignerProvider - { - public: - virtual std::shared_ptr<Aws::Client::AWSAuthSigner> GetSigner(const Aws::String& signerName) const = 0; - virtual void AddSigner(std::shared_ptr<Aws::Client::AWSAuthSigner>& signer) = 0; - virtual ~AWSAuthSignerProvider() = default; - }; - - class AWS_CORE_API DefaultAuthSignerProvider : public AWSAuthSignerProvider - { - public: - /** - * Creates a Signature-V4 signer provider that supports the different implementations of Signature-V4 - * used for standard and event-stream requests. - * - * @param credentialsProvider A provider to retrieve the access/secret key used to derive the signing - * @param serviceName The canonical name of the AWS service to be used in the signature - * @param region The AWS region in which the requests will be made. - */ - DefaultAuthSignerProvider(const std::shared_ptr<AWSCredentialsProvider>& credentialsProvider, - const Aws::String& serviceName, const Aws::String& region); - explicit DefaultAuthSignerProvider(const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer); - void AddSigner(std::shared_ptr<Aws::Client::AWSAuthSigner>& signer) override; - std::shared_ptr<Aws::Client::AWSAuthSigner> GetSigner(const Aws::String& signerName) const override; - private: - Aws::Vector<std::shared_ptr<Aws::Client::AWSAuthSigner>> m_signers; - }; - } -} +// This is a header that represents old legacy all-in-one header to maintain backward compatibility diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSBearerToken.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSBearerToken.h new file mode 100644 index 00000000000..9565dd3802f --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSBearerToken.h @@ -0,0 +1,113 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/DateTime.h> + +namespace Aws +{ + namespace Auth + { + /** + * Simple data object around aws credentials + */ + class AWS_CORE_API AWSBearerToken + { + public: + /** + * Initializes an empty token. + * Empty token is not expired by default. + * Token expires only if an expiration date is explicitly set. + */ + AWSBearerToken() : m_expiration((std::chrono::time_point<std::chrono::system_clock>::max)()) + { + } + + /** + * Initializes object with token. + * Expiration date is set to "never expire". + */ + AWSBearerToken(const Aws::String& token) : + m_token(token), + m_expiration((std::chrono::time_point<std::chrono::system_clock>::max)()) + { + } + + /** + * Initializes object with token and expiration date. + */ + AWSBearerToken(const Aws::String& token, Aws::Utils::DateTime expiration) : + m_token(token), + m_expiration(expiration) + { + } + + /** + * If token has not been initialized or been initialized to empty value. + * Expiration date does not affect the result of this function. + */ + inline bool IsEmpty() const { return m_token.empty(); } + + inline bool IsExpired() const { return m_expiration <= Aws::Utils::DateTime::Now(); } + + inline bool IsExpiredOrEmpty() const { return IsEmpty() || IsExpired(); } + + /** + * Gets the underlying token + */ + inline const Aws::String& GetToken() const + { + return m_token; + } + + /** + * Gets the expiration date of the token + */ + inline Aws::Utils::DateTime GetExpiration() const + { + return m_expiration; + } + + /** + * Sets the underlying token. Copies from the parameter token + */ + inline void SetToken(const Aws::String& token) + { + m_token = token; + } + + /** + * Sets the underlying token. Moves from the parameter token + */ + inline void SetToken(Aws::String&& token) + { + m_token = std::move(token); + } + + /** + * Sets the expiration date of the credential + */ + inline void SetExpiration(const Aws::Utils::DateTime& expiration) + { + m_expiration = expiration; + } + + /** + * Sets the expiration date of the credential + */ + inline void SetExpiration(Aws::Utils::DateTime&& expiration) + { + m_expiration = std::move(expiration); + } + + private: + Aws::String m_token; + Aws::Utils::DateTime m_expiration; + }; + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentials.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentials.h index 1c14b955fc2..0152d3e5a74 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentials.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentials.h @@ -68,7 +68,7 @@ namespace Aws } /** - * If credentials haven't been initialized or been initialized to emtpy values. + * If credentials haven't been initialized or been initialized to empty values. * Expiration date does not affect the result of this function. */ inline bool IsEmpty() const { return m_accessKeyId.empty() && m_secretKey.empty(); } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentialsProvider.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentialsProvider.h index a3a46964e8e..e8fec174ab5 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentialsProvider.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentialsProvider.h @@ -217,6 +217,7 @@ namespace Aws void Reload() override; private: + bool ExpiresSoon() const; void RefreshIfExpired(); std::shared_ptr<Aws::Config::AWSProfileConfigLoader> m_ec2MetadataConfigLoader; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentialsProviderChain.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentialsProviderChain.h index dae8cf5a426..ffcd57dde42 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentialsProviderChain.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentialsProviderChain.h @@ -32,7 +32,7 @@ namespace Aws /** * Gets all providers stored in this chain. */ - const Aws::Vector<std::shared_ptr<AWSCredentialsProvider>>& GetProviders() { return m_providerChain; } + const Aws::Vector<std::shared_ptr<AWSCredentialsProvider>>& GetProviders() const { return m_providerChain; } protected: /** @@ -62,6 +62,8 @@ namespace Aws * and InstanceProfileCredentialsProvider in that order. */ DefaultAWSCredentialsProviderChain(); + + DefaultAWSCredentialsProviderChain(const DefaultAWSCredentialsProviderChain& chain); }; } // namespace Auth diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/SSOCredentialsProvider.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/SSOCredentialsProvider.h index 288beccb3b5..3b476177b9a 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/SSOCredentialsProvider.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/SSOCredentialsProvider.h @@ -8,6 +8,7 @@ #include <aws/core/Core_EXPORTS.h> #include <aws/core/auth/AWSCredentialsProvider.h> +#include <aws/core/auth/bearer-token-provider/SSOBearerTokenProvider.h> #include <memory> namespace Aws { @@ -39,6 +40,8 @@ namespace Aws { Aws::String m_ssoRegion; // The expiration time of the accessToken. Aws::Utils::DateTime m_expiresAt; + // The SSO Token Provider + Aws::Auth::SSOBearerTokenProvider m_bearerTokenProvider; void Reload() override; void RefreshIfExpired(); diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/STSCredentialsProvider.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/STSCredentialsProvider.h index 92d997c7ca5..720006592c9 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/STSCredentialsProvider.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/STSCredentialsProvider.h @@ -46,6 +46,7 @@ namespace Aws Aws::String m_sessionName; Aws::String m_token; bool m_initialized; + bool ExpiresSoon() const; }; } // namespace Auth } // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/bearer-token-provider/AWSBearerTokenProviderBase.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/bearer-token-provider/AWSBearerTokenProviderBase.h new file mode 100644 index 00000000000..d7608a351c5 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/bearer-token-provider/AWSBearerTokenProviderBase.h @@ -0,0 +1,30 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + + +#pragma once + +#include <aws/core/auth/AWSBearerToken.h> + +namespace Aws +{ + namespace Auth + { + /** + * Abstract class for retrieving Bearer Token. Create a derived class from this to allow + * various methods of storing and retrieving auth bearer tokens. + */ + class AWS_CORE_API AWSBearerTokenProviderBase + { + public: + virtual ~AWSBearerTokenProviderBase() = default; + + /** + * The core of the bearer token provider interface. Override this method to control how credentials are retrieved. + */ + virtual AWSBearerToken GetAWSBearerToken() = 0; + }; + } // namespace Auth +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/bearer-token-provider/AWSBearerTokenProviderChainBase.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/bearer-token-provider/AWSBearerTokenProviderChainBase.h new file mode 100644 index 00000000000..e5f3b828bc9 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/bearer-token-provider/AWSBearerTokenProviderChainBase.h @@ -0,0 +1,31 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + + +#pragma once + +#include <aws/core/auth/bearer-token-provider/AWSBearerTokenProviderBase.h> +#include <aws/core/utils/memory/stl/AWSVector.h> +#include <memory> + +namespace Aws +{ + namespace Auth + { + /** + * Abstract class for providing chains of bearer token providers + */ + class AWS_CORE_API AWSBearerTokenProviderChainBase : public AWSBearerTokenProviderBase + { + public: + virtual ~AWSBearerTokenProviderChainBase() = default; + + /** + * Gets all providers stored in this chain. + */ + virtual const Aws::Vector<std::shared_ptr<AWSBearerTokenProviderBase>>& GetProviders() = 0; + }; + } // namespace Auth +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/bearer-token-provider/DefaultBearerTokenProviderChain.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/bearer-token-provider/DefaultBearerTokenProviderChain.h new file mode 100644 index 00000000000..8e8a4508a32 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/bearer-token-provider/DefaultBearerTokenProviderChain.h @@ -0,0 +1,49 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + + +#pragma once + +#include <aws/core/auth/bearer-token-provider/AWSBearerTokenProviderChainBase.h> +#include <aws/core/utils/memory/stl/AWSVector.h> +#include <memory> + +namespace Aws +{ + namespace Auth + { + /** + * Default built-in AWSBearerTokenProviderChainBase implementation that includes Aws::Auth::SSOBearerTokenProvider in the chain. + */ + class AWS_CORE_API DefaultBearerTokenProviderChain : public AWSBearerTokenProviderChainBase + { + public: + DefaultBearerTokenProviderChain(); + virtual ~DefaultBearerTokenProviderChain() = default; + + /** + * Return bearer token, implementation of a base class interface + */ + virtual AWSBearerToken GetAWSBearerToken() override; + + /** + * Gets all providers stored in this chain. + */ + const Aws::Vector<std::shared_ptr<AWSBearerTokenProviderBase>>& GetProviders() override + { + return m_providerChain; + } + + protected: + /** + * Adds a provider to the back of the chain. + */ + void AddProvider(const std::shared_ptr<AWSBearerTokenProviderBase>& provider) { m_providerChain.push_back(provider); } + + Aws::Vector<std::shared_ptr<AWSBearerTokenProviderBase> > m_providerChain; + }; + + } // namespace Auth +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/bearer-token-provider/SSOBearerTokenProvider.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/bearer-token-provider/SSOBearerTokenProvider.h new file mode 100644 index 00000000000..b0656caa8e4 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/bearer-token-provider/SSOBearerTokenProvider.h @@ -0,0 +1,63 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + + +#pragma once + +#include <aws/core/auth/bearer-token-provider/AWSBearerTokenProviderBase.h> + +#include <aws/core/internal/AWSHttpResourceClient.h> +#include <aws/core/utils/threading/ReaderWriterLock.h> + +namespace Aws +{ + namespace Auth + { + /** + * To support usage of SSO bearerToken. + * The SSO token provider assumes that an SSO access token has already been resolved and cached to disk. + */ + class AWS_CORE_API SSOBearerTokenProvider : public AWSBearerTokenProviderBase + { + public: + SSOBearerTokenProvider(); + explicit SSOBearerTokenProvider(const Aws::String& awsProfile); + /** + * Retrieves the bearerToken if found, otherwise returns empty credential set. + */ + AWSBearerToken GetAWSBearerToken() override; + + protected: + struct CachedSsoToken + { + public: + Aws::String accessToken; + Aws::Utils::DateTime expiresAt; + Aws::String refreshToken; + Aws::String clientId; + Aws::String clientSecret; + Aws::Utils::DateTime registrationExpiresAt; + Aws::String region; + Aws::String startUrl; + }; + + static const size_t REFRESH_ATTEMPT_INTERVAL_S; + static const size_t REFRESH_WINDOW_BEFORE_EXPIRATION_S; + // Profile description variables + Aws::UniquePtr<Aws::Internal::SSOCredentialsClient> m_client; + Aws::String m_profileToUse; + + mutable Aws::Auth::AWSBearerToken m_token; + mutable Aws::Utils::DateTime m_lastUpdateAttempt; + + mutable Aws::Utils::Threading::ReaderWriterLock m_reloadLock; + + void Reload(); + void RefreshFromSso(); + CachedSsoToken LoadAccessTokenFile() const; + bool WriteAccessTokenFile(const CachedSsoToken& token) const; + }; + } // namespace Auth +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer-provider/AWSAuthSignerProviderBase.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer-provider/AWSAuthSignerProviderBase.h new file mode 100644 index 00000000000..0577cef77e1 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer-provider/AWSAuthSignerProviderBase.h @@ -0,0 +1,33 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSVector.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <memory> + +namespace Aws +{ + namespace Client + { + class AWSAuthSigner; + } + namespace Auth + { + class AWSCredentialsProvider; + + class AWS_CORE_API AWSAuthSignerProvider + { + public: + virtual std::shared_ptr<Aws::Client::AWSAuthSigner> GetSigner(const Aws::String& signerName) const = 0; + virtual void AddSigner(std::shared_ptr<Aws::Client::AWSAuthSigner>& signer) = 0; + virtual ~AWSAuthSignerProvider() = default; + }; + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer-provider/BearerTokenAuthSignerProvider.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer-provider/BearerTokenAuthSignerProvider.h new file mode 100644 index 00000000000..09b83a8e272 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer-provider/BearerTokenAuthSignerProvider.h @@ -0,0 +1,38 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/auth/signer-provider/AWSAuthSignerProviderBase.h> +#include <aws/core/utils/memory/stl/AWSSet.h> +#include <aws/core/auth/signer/AWSAuthBearerSigner.h> + + +namespace Aws +{ + namespace Auth + { + class AWSCredentialsProvider; + + class AWS_CORE_API BearerTokenAuthSignerProvider : public AWSAuthSignerProvider + { + public: + /** + * Creates a Signature-V4 signer provider that supports the different implementations of Signature-V4 + * used for standard and event-stream requests. + * + * @param credentialsProvider A provider to retrieve the access/secret key used to derive the signing + * @param serviceName The canonical name of the AWS service to be used in the signature + * @param region The AWS region in which the requests will be made. + */ + BearerTokenAuthSignerProvider() = delete; + BearerTokenAuthSignerProvider(const std::shared_ptr<Aws::Auth::AWSBearerTokenProviderBase> bearerTokenProvider); + void AddSigner(std::shared_ptr<Aws::Client::AWSAuthSigner>& signer) override; + std::shared_ptr<Aws::Client::AWSAuthSigner> GetSigner(const Aws::String& signerName) const override; + private: + Aws::Vector<std::shared_ptr<Aws::Client::AWSAuthSigner>> m_signers; + }; + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer-provider/DefaultAuthSignerProvider.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer-provider/DefaultAuthSignerProvider.h new file mode 100644 index 00000000000..4c31aaaa327 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer-provider/DefaultAuthSignerProvider.h @@ -0,0 +1,42 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + + +#pragma once + +#include <aws/core/auth/signer-provider/AWSAuthSignerProviderBase.h> + +#include <aws/core/auth/signer/AWSAuthV4Signer.h> + + +namespace Aws +{ + namespace Auth + { + class AWSCredentialsProvider; + + class AWS_CORE_API DefaultAuthSignerProvider : public AWSAuthSignerProvider + { + public: + /** + * Creates a Signature-V4 signer provider that supports the different implementations of Signature-V4 + * used for standard and event-stream requests. + * + * @param credentialsProvider A provider to retrieve the access/secret key used to derive the signing + * @param serviceName The canonical name of the AWS service to be used in the signature + * @param region The AWS region in which the requests will be made. + */ + DefaultAuthSignerProvider(const std::shared_ptr<AWSCredentialsProvider>& credentialsProvider, + const Aws::String& serviceName, const Aws::String& region, + Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy signingPolicy = Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy::RequestDependent, + bool urlEscapePath = true); + explicit DefaultAuthSignerProvider(const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer); + void AddSigner(std::shared_ptr<Aws::Client::AWSAuthSigner>& signer) override; + std::shared_ptr<Aws::Client::AWSAuthSigner> GetSigner(const Aws::String& signerName) const override; + private: + Aws::Vector<std::shared_ptr<Aws::Client::AWSAuthSigner>> m_signers; + }; + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSAuthBearerSigner.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSAuthBearerSigner.h new file mode 100644 index 00000000000..655aeb1a002 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSAuthBearerSigner.h @@ -0,0 +1,106 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + + +#pragma once + +#include "aws/core/auth/signer/AWSAuthSignerBase.h" + +namespace Aws +{ + namespace Http + { + class HttpRequest; + } // namespace Http + + namespace Utils + { + namespace Event + { + class Message; + } + } // namespace Utils + + namespace Auth + { + class AWSBearerTokenProviderBase; + AWS_CORE_API extern const char BEARER_SIGNER[]; + } // namespace Auth + + namespace Client + { + class AWS_CORE_API AWSAuthBearerSigner : public AWSAuthSigner + { + + public: + /** + * An implementation of a signer interface that uses bearer token auth signature. + */ + AWSAuthBearerSigner(const std::shared_ptr<Aws::Auth::AWSBearerTokenProviderBase> bearerTokenProvider) + : m_bearerTokenProvider(bearerTokenProvider) + {} + + virtual ~AWSAuthBearerSigner() {}; + + /** + * Return the signer's name + */ + const char* GetName() const override + { + return Aws::Auth::BEARER_SIGNER; + } + + /** + * Sign request with a bearer auth token + * @return true if success, false if fail to sign + */ + bool SignRequest(Aws::Http::HttpRequest& ) const override; + + /** + * Dummy function to satisfy the interface requirements of a base Signer interface + * additional arguments are not used. + * @return true if success, false if fail to sign + */ + bool SignRequest(Aws::Http::HttpRequest& ioRequest, const char* /*region*/, const char* /*serviceName*/, bool /*signBody*/) const override + { + return SignRequest(ioRequest); + } + + /** + * Dummy function to satisfy the interface requirements of a base Signer interface + * @return true if success, false if fail to sign + */ + bool PresignRequest(Aws::Http::HttpRequest& ioRequest, long long /*expirationInSeconds = 0*/) const override + { + return SignRequest(ioRequest); + } + + /** + * Dummy function to satisfy the interface requirements of a base Signer interface + * additional arguments are not used. + * @return true if success, false if fail to sign + */ + bool PresignRequest(Aws::Http::HttpRequest& ioRequest, const char* /*region*/, long long expirationInSeconds = 0) const override + { + return PresignRequest(ioRequest, expirationInSeconds); + } + + /** + * Dummy function to satisfy the interface requirements of a base Signer interface + * additional arguments are not used. + * @return true if success, false if fail to sign + */ + bool PresignRequest(Aws::Http::HttpRequest& ioRequest, const char* /*region*/, const char* /*serviceName*/, long long expirationInSeconds = 0) const override + { + return PresignRequest(ioRequest, expirationInSeconds); + } + + protected: + std::shared_ptr<Aws::Auth::AWSBearerTokenProviderBase> m_bearerTokenProvider; + }; + + } // namespace Client +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSAuthEventStreamV4Signer.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSAuthEventStreamV4Signer.h new file mode 100644 index 00000000000..f9c4d4fedf2 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSAuthEventStreamV4Signer.h @@ -0,0 +1,114 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include "aws/core/auth/signer/AWSAuthSignerBase.h" + +#include <aws/core/utils/Array.h> +#include <aws/core/utils/memory/stl/AWSSet.h> +#include <aws/core/utils/threading/ReaderWriterLock.h> +#include <aws/core/utils/crypto/Sha256.h> +#include <aws/core/utils/crypto/Sha256HMAC.h> + +#include <aws/crt/auth/Sigv4Signing.h> + +#include <memory> + +namespace Aws +{ + namespace Http + { + class HttpRequest; + } // namespace Http + + namespace Utils + { + namespace Event + { + class Message; + } + } // namespace Utils + + namespace Auth + { + class AWSCredentials; + class AWSCredentialsProvider; + + AWS_CORE_API extern const char EVENTSTREAM_SIGV4_SIGNER[]; + } // namespace Auth + + namespace Client + { + /** + * AWS Auth EventStream v4 Signer implementation of the AWSAuthSigner interface. + */ + class AWS_CORE_API AWSAuthEventStreamV4Signer : public AWSAuthSigner + { + public: + AWSAuthEventStreamV4Signer(const std::shared_ptr<Auth::AWSCredentialsProvider>& credentialsProvider, + const char* serviceName, const Aws::String& region); + + const char* GetName() const override { return Aws::Auth::EVENTSTREAM_SIGV4_SIGNER; } + + bool SignEventMessage(Aws::Utils::Event::Message&, Aws::String& priorSignature) const override; + + bool SignRequest(Aws::Http::HttpRequest& request) const override + { + return SignRequest(request, m_region.c_str(), m_serviceName.c_str(), true); + } + + bool SignRequest(Aws::Http::HttpRequest& request, bool signBody) const override + { + return SignRequest(request, m_region.c_str(), m_serviceName.c_str(), signBody); + } + + bool SignRequest(Aws::Http::HttpRequest& request, const char* region, bool signBody) const override + { + return SignRequest(request, region, m_serviceName.c_str(), signBody); + } + + bool SignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, bool signBody) const override; + + /** + * Do nothing + */ + bool PresignRequest(Aws::Http::HttpRequest&, long long) const override { return false; } + + /** + * Do nothing + */ + bool PresignRequest(Aws::Http::HttpRequest&, const char*, long long) const override { return false; } + + /** + * Do nothing + */ + bool PresignRequest(Aws::Http::HttpRequest&, const char*, const char*, long long) const override { return false; } + + bool ShouldSignHeader(const Aws::String& header) const; + private: + Utils::ByteBuffer GenerateSignature(const Aws::Auth::AWSCredentials& credentials, + const Aws::String& stringToSign, const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const; + Utils::ByteBuffer GenerateSignature(const Aws::String& stringToSign, const Aws::Utils::ByteBuffer& key) const; + Aws::String GenerateStringToSign(const Aws::String& dateValue, const Aws::String& simpleDate, + const Aws::String& canonicalRequestHash, const Aws::String& region, + const Aws::String& serviceName) const; + Aws::Utils::ByteBuffer ComputeHash(const Aws::String& secretKey, const Aws::String& simpleDate) const; + Aws::Utils::ByteBuffer ComputeHash(const Aws::String& secretKey, + const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const; + const Aws::String m_serviceName; + const Aws::String m_region; + mutable Aws::Utils::Crypto::Sha256 m_hash; + mutable Aws::Utils::Crypto::Sha256HMAC m_HMAC; + mutable Utils::Threading::ReaderWriterLock m_derivedKeyLock; + mutable Aws::Utils::ByteBuffer m_derivedKey; + mutable Aws::String m_currentDateStr; + mutable Aws::String m_currentSecretKey; + Aws::Vector<Aws::String> m_unsignedHeaders; + std::shared_ptr<Auth::AWSCredentialsProvider> m_credentialsProvider; + }; + } // namespace Client +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSAuthSignerBase.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSAuthSignerBase.h new file mode 100644 index 00000000000..54be880a377 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSAuthSignerBase.h @@ -0,0 +1,142 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include "aws/core/Core_EXPORTS.h" +#include "aws/core/utils/DateTime.h" + +#include <memory> +#include <atomic> +#include <chrono> + +namespace Aws +{ + namespace Http + { + class HttpRequest; + } // namespace Http + + namespace Utils + { + namespace Event + { + class Message; + } + } // namespace Utils + + namespace Client + { + /** + * Auth Signer interface. Takes a generic AWS request and applies crypto tamper resistent signatures on the request. + */ + class AWS_CORE_API AWSAuthSigner + { + public: + AWSAuthSigner() : m_clockSkew() { m_clockSkew.store(std::chrono::milliseconds(0L)); } + virtual ~AWSAuthSigner() = default; + + /** + * Signs the request itself (usually by adding a signature header) based on info in the request and uri. + */ + virtual bool SignRequest(Aws::Http::HttpRequest& request) const = 0; + + /** + * Signs the request itself (usually by adding a signature header) based on info in the request and uri. + * If signBody is false and https is being used then the body of the payload will not be signed. + * The default virtual function, just calls SignRequest. + */ + virtual bool SignRequest(Aws::Http::HttpRequest& request, bool signBody) const + { + AWS_UNREFERENCED_PARAM(signBody); + return SignRequest(request); + } + + /** + * Signs the request itself (usually by adding a signature header) based on info in the request and uri. + * If signBody is false and https is being used then the body of the payload will not be signed. + * The default virtual function, just calls SignRequest. + * Using m_region by default if parameter region is nullptr. + */ + virtual bool SignRequest(Aws::Http::HttpRequest& request, const char* region, bool signBody) const + { + AWS_UNREFERENCED_PARAM(signBody); + AWS_UNREFERENCED_PARAM(region); + return SignRequest(request); + } + + /** + * Signs the request itself (usually by adding a signature header) based on info in the request and uri. + * If signBody is false and https is being used then the body of the payload will not be signed. + * The default virtual function, just calls SignRequest. + * Using m_region by default if parameter region is nullptr. + * Using m_serviceName by default if parameter serviceName is nullptr. + */ + virtual bool SignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, bool signBody) const + { + AWS_UNREFERENCED_PARAM(signBody); + AWS_UNREFERENCED_PARAM(region); + AWS_UNREFERENCED_PARAM(serviceName); + return SignRequest(request); + } + + /** + * Signs a single event message in an event stream. + * The input message buffer is copied and signed. The message's input buffer will be deallocated and a new + * buffer will be assigned. The new buffer encodes the original message with its headers as the payload of + * the new message. The signature of the original message will be added as a header to the new message. + * + * A Hex encoded signature of the previous event (or of the HTTP request headers in case of the first event) + * is provided as the 'priorSignature' parameter. 'priorSignature' will contain the value of the new + * signature after this call returns successfully. + * + * The function returns true if the message is successfully signed. + */ + virtual bool SignEventMessage(Aws::Utils::Event::Message&, Aws::String& /* priorSignature */) const { return false; } + + /** + * Takes a request and signs the URI based on the HttpMethod, URI and other info from the request. + * The URI can then be used in a normal HTTP call until expiration. + */ + virtual bool PresignRequest(Aws::Http::HttpRequest& request, long long expirationInSeconds) const = 0; + + /** + * Generates a signed Uri using the injected signer. for the supplied uri and http method and region. expirationInSeconds defaults + * to 0 which is the default 7 days. + * Using m_region by default if parameter region is nullptr. + */ + virtual bool PresignRequest(Aws::Http::HttpRequest& request, const char* region, long long expirationInSeconds = 0) const = 0; + + /** + * Generates a signed Uri using the injected signer. for the supplied uri and http method, region, and service name. expirationInSeconds defaults + * to 0 which is the default 7 days. + * Using m_region by default if parameter region is nullptr. + * Using m_serviceName by default if parameter serviceName is nullptr. + */ + virtual bool PresignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, long long expirationInSeconds = 0) const = 0; + + /** + * Return the signer's name + */ + virtual const char* GetName() const = 0; + + /** + * This handles detection of clock skew between clients and the server and adjusts the clock so that the next request will not + * fail on the timestamp check. + */ + virtual void SetClockSkew(const std::chrono::milliseconds& clockSkew) { m_clockSkew = clockSkew; } + + /** + * Gets the timestamp being used by the signer. This may include a clock skew if a clock skew has been detected. + */ + virtual Aws::Utils::DateTime GetSigningTimestamp() const { return Aws::Utils::DateTime::Now() + GetClockSkewOffset(); } + + protected: + virtual std::chrono::milliseconds GetClockSkewOffset() const { return m_clockSkew.load(); } + + std::atomic<std::chrono::milliseconds> m_clockSkew; + }; + } // namespace Client +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSAuthSignerCommon.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSAuthSignerCommon.h new file mode 100644 index 00000000000..7ed72b87b71 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSAuthSignerCommon.h @@ -0,0 +1,23 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/http/HttpTypes.h> + +namespace Aws +{ + namespace Http + { + class HttpRequest; + } // namespace Http + + namespace Auth + { + AWS_CORE_API extern const char SIGNATURE[]; + } // namespace Client +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSAuthSignerHelper.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSAuthSignerHelper.h new file mode 100644 index 00000000000..955445b6b63 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSAuthSignerHelper.h @@ -0,0 +1,45 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/http/HttpTypes.h> + +namespace Aws +{ + namespace Http + { + class HttpRequest; + } // namespace Http + + namespace Auth + { + class AWSAuthHelper + { + public: + /** + * Helper functions used across different signers + */ + static Aws::String CanonicalizeRequestSigningString(Aws::Http::HttpRequest &request, bool urlEscapePath); + static Aws::Http::HeaderValueCollection CanonicalizeHeaders(Http::HeaderValueCollection &&headers); + + /** + * Static const variables used across different signers + */ + static const char* EQ; + static const char* AWS_HMAC_SHA256; + static const char* AWS4_REQUEST; + static const char* SIGNED_HEADERS; + static const char* CREDENTIAL; + static const char* NEWLINE; + static const char* X_AMZN_TRACE_ID; + static const char* X_AMZ_CONTENT_SHA256; + static const char* SIGNING_KEY; + static const char* SIMPLE_DATE_FORMAT_STR; + }; + } // namespace Client +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSAuthV4Signer.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSAuthV4Signer.h new file mode 100644 index 00000000000..469391a1cae --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSAuthV4Signer.h @@ -0,0 +1,214 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + + +#pragma once + +#include "aws/core/auth/signer/AWSAuthSignerBase.h" + +#include <aws/core/utils/Array.h> +#include <aws/core/utils/memory/stl/AWSSet.h> +#include <aws/core/utils/threading/ReaderWriterLock.h> +#include <aws/core/utils/crypto/Sha256.h> +#include <aws/core/utils/crypto/Sha256HMAC.h> + +#include <aws/crt/auth/Sigv4Signing.h> + +#include <memory> + +namespace Aws +{ + namespace Http + { + class HttpRequest; + } // namespace Http + + namespace Auth + { + class AWSCredentials; + class AWSCredentialsProvider; + + enum class AWSSigningAlgorithm + { + SIGV4 = static_cast<int>(Aws::Crt::Auth::SigningAlgorithm::SigV4), + ASYMMETRIC_SIGV4 = static_cast<int>(Aws::Crt::Auth::SigningAlgorithm::SigV4A), + }; + + AWS_CORE_API extern const char SIGV4_SIGNER[]; + AWS_CORE_API extern const char ASYMMETRIC_SIGV4_SIGNER[]; + } // namespace Auth + + namespace Client + { + /** + * AWS Auth v4 Signer implementation of the AWSAuthSigner interface. More information on AWS Auth v4 Can be found here: + * http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html + */ + class AWS_CORE_API AWSAuthV4Signer : public AWSAuthSigner + { + + public: + /** + * Even though different payload signing polices, HTTP will force payload signing to be on. + */ + enum class PayloadSigningPolicy + { + /** + * Sign the request based on the value returned by AmazonWebServiceRequest::SignBody() + */ + RequestDependent, + /** + * Always sign the body of the request. + */ + Always, + /** + * Never sign the body of the request + */ + Never + }; + /** + * credentialsProvider, source of AWS Credentials to sign requests with + * serviceName, canonical service name to sign with + * region, region string to use in signature + * signPayloads, if Always, the payload will have a sha256 computed on the body of the request. If this is set + * to Never, the sha256 will not be computed on the body. This is only useful for Amazon S3 over Https. If + * Https is not used then this flag will be ignored. If set to RequestDependent, compute or not is based on + * the value from AmazonWebServiceRequest::SignBody() + */ + AWSAuthV4Signer(const std::shared_ptr<Auth::AWSCredentialsProvider>& credentialsProvider, + const char* serviceName, const Aws::String& region, PayloadSigningPolicy signingPolicy = PayloadSigningPolicy::RequestDependent, + bool urlEscapePath = true, Aws::Auth::AWSSigningAlgorithm signingAlgorithm = Aws::Auth::AWSSigningAlgorithm::SIGV4); + + virtual ~AWSAuthV4Signer(); + + /** + * AWSAuthV4signer's implementation of virtual function from base class + * Return Auth Signer's name, here the value is specified in Aws::Auth::DEFAULT_AUTHV4_SIGNER. + */ + const char* GetName() const override + { + if (m_signingAlgorithm == Aws::Auth::AWSSigningAlgorithm::ASYMMETRIC_SIGV4) + { + return Aws::Auth::ASYMMETRIC_SIGV4_SIGNER; + } + else + { + return Aws::Auth::SIGV4_SIGNER; + } + } + + /** + * Signs the request itself based on info in the request and uri. + * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. + */ + bool SignRequest(Aws::Http::HttpRequest& request) const override + { + return SignRequest(request, m_region.c_str(), m_serviceName.c_str(), true/*signBody*/); + } + + /** + * Signs the request itself based on info in the request and uri. + * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. If signBody is false + * and https is being used then the body of the payload will not be signed. + */ + bool SignRequest(Aws::Http::HttpRequest& request, bool signBody) const override + { + return SignRequest(request, m_region.c_str(), m_serviceName.c_str(), signBody); + } + + /** + * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. If signBody is false + * and https is being used then the body of the payload will not be signed. + * Using m_region by default if parameter region is nullptr. + */ + bool SignRequest(Aws::Http::HttpRequest& request, const char* region, bool signBody) const override + { + return SignRequest(request, region, m_serviceName.c_str(), signBody); + } + + /** + * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. If signBody is false + * and https is being used then the body of the payload will not be signed. + * Using m_region by default if parameter region is nullptr. + */ + bool SignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, bool signBody) const override; + + /** + * Takes a request and signs the URI based on the HttpMethod, URI and other info from the request. + * the region the signer was initialized with will be used for the signature. + * The URI can then be used in a normal HTTP call until expiration. + * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. + * expirationInSeconds defaults to 0 which provides a URI good for 7 days. + */ + bool PresignRequest(Aws::Http::HttpRequest& request, long long expirationInSeconds = 0) const override; + + /** + * Takes a request and signs the URI based on the HttpMethod, URI and other info from the request. + * The URI can then be used in a normal HTTP call until expiration. + * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. + * expirationInSeconds defaults to 0 which provides a URI good for 7 days. + * Using m_region by default if parameter region is nullptr. + */ + bool PresignRequest(Aws::Http::HttpRequest& request, const char* region, long long expirationInSeconds = 0) const override; + + /** + * Takes a request and signs the URI based on the HttpMethod, URI and other info from the request. + * The URI can then be used in a normal HTTP call until expiration. + * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. + * expirationInSeconds defaults to 0 which provides a URI good for 7 days. + * Using m_region by default if parameter region is nullptr. + * Using m_serviceName by default if parameter serviceName is nullptr. + */ + bool PresignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, long long expirationInSeconds = 0) const override; + + Aws::String GetServiceName() const { return m_serviceName; } + Aws::String GetRegion() const { return m_region; } + Aws::String GenerateSignature(const Aws::Auth::AWSCredentials& credentials, + const Aws::String& stringToSign, const Aws::String& simpleDate) const; + bool ShouldSignHeader(const Aws::String& header) const; + + protected: + bool m_includeSha256HashHeader; + + private: + + Aws::String GenerateSignature(const Aws::Auth::AWSCredentials& credentials, + const Aws::String& stringToSign, const Aws::String& simpleDate, const Aws::String& region, + const Aws::String& serviceName) const; + + Aws::String GenerateSignature(const Aws::String& stringToSign, const Aws::Utils::ByteBuffer& key) const; + bool ServiceRequireUnsignedPayload(const Aws::String& serviceName) const; + Aws::String ComputePayloadHash(Aws::Http::HttpRequest&) const; + Aws::String GenerateStringToSign(const Aws::String& dateValue, const Aws::String& simpleDate, + const Aws::String& canonicalRequestHash, const Aws::String& region, + const Aws::String& serviceName) const; + Aws::Utils::ByteBuffer ComputeHash(const Aws::String& secretKey, const Aws::String& simpleDate) const; + Aws::Utils::ByteBuffer ComputeHash(const Aws::String& secretKey, + const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const; + bool SignRequestWithSigV4a(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, + bool signBody, long long expirationTimeInSeconds, Aws::Crt::Auth::SignatureType signatureType) const; + + Aws::Auth::AWSSigningAlgorithm m_signingAlgorithm; + std::shared_ptr<Auth::AWSCredentialsProvider> m_credentialsProvider; + const Aws::String m_serviceName; + const Aws::String m_region; + Aws::UniquePtr<Aws::Utils::Crypto::Sha256> m_hash; + Aws::UniquePtr<Aws::Utils::Crypto::Sha256HMAC> m_HMAC; + + Aws::Set<Aws::String> m_unsignedHeaders; + + //these next four fields are ONLY for caching purposes and do not change + //the logical state of the signer. They are marked mutable so the + //interface can remain const. + mutable Aws::Utils::ByteBuffer m_partialSignature; + mutable Aws::String m_currentDateStr; + mutable Aws::String m_currentSecretKey; + mutable Utils::Threading::ReaderWriterLock m_partialSignatureLock; + PayloadSigningPolicy m_payloadSigningPolicy; + bool m_urlEscapePath; + }; + } // namespace Client +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSNullSigner.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSNullSigner.h new file mode 100644 index 00000000000..7c40f44fb42 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/signer/AWSNullSigner.h @@ -0,0 +1,72 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include "aws/core/auth/signer/AWSAuthSignerBase.h" + +namespace Aws +{ + namespace Http + { + class HttpRequest; + } // namespace Http + + namespace Utils + { + namespace Event + { + class Message; + } + } // namespace Utils + + namespace Auth + { + AWS_CORE_API extern const char NULL_SIGNER[]; + } // namespace Auth + + namespace Client + { + /** + * A no-op implementation of the AWSAuthSigner interface + */ + class AWS_CORE_API AWSNullSigner : public AWSAuthSigner + { + public: + /** + * AWSNullSigner's implementation of virtual function from base class + * Here the returned value is specified in Aws::Auth::NULL_SIGNER. + */ + const char* GetName() const override { return Aws::Auth::NULL_SIGNER; } + + /** + * Do nothing + */ + bool SignRequest(Aws::Http::HttpRequest&) const override { return true; } + + /** + * Do nothing + */ + bool SignEventMessage(Aws::Utils::Event::Message&, Aws::String& /* priorSignature */) const override { return true; } + + /** + * Do nothing + */ + bool PresignRequest(Aws::Http::HttpRequest&, long long) const override { return false; } + + /** + * Do nothing + */ + bool PresignRequest(Aws::Http::HttpRequest&, const char*, long long) const override { return false; } + + /** + * Do nothing + */ + bool PresignRequest(Aws::Http::HttpRequest&, const char*, const char*, long long) const override { return false; } + }; + + } // namespace Client +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSAsyncOperationTemplate.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSAsyncOperationTemplate.h new file mode 100644 index 00000000000..15ee45f8859 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSAsyncOperationTemplate.h @@ -0,0 +1,191 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/AWSMemory.h> +#include <aws/core/utils/memory/stl/AWSAllocator.h> +#include <aws/core/utils/threading/Executor.h> +#include <functional> +#include <future> + +namespace Aws +{ +namespace Client +{ + /** + * A template function that is used to create an Async Operation function body for AWS Operations + */ + template<typename ClientT, + typename RequestT, + typename HandlerT, + typename HandlerContextT, + typename OperationFuncT, + typename ExecutorT> + inline void AWS_CORE_LOCAL MakeAsyncOperation(OperationFuncT&& operationFunc, + const ClientT* clientThis, + const RequestT& request, + const HandlerT& handler, + const HandlerContextT& context, + ExecutorT* pExecutor) + { + std::function<void()> asyncTask = + [operationFunc, clientThis, request, handler, context]() // note capture by value + { + handler(clientThis, + request, + (clientThis->*operationFunc)(request), + context); + }; + + pExecutor->Submit(std::move(asyncTask)); + } + + /** + * A template function that is used to create an Async Operation function body for AWS Streaming Operations + * The only difference compared to a regular non-streaming Operation is that + * the request is passed by non-const reference, therefore virtual copy constructor is not needed. + * However, caller code must ensure the life time of the request object is maintained during the Async execution. + */ + template<typename ClientT, + typename RequestT, + typename HandlerT, + typename HandlerContextT, + typename OperationFuncT, + typename ExecutorT> + inline void AWS_CORE_LOCAL MakeAsyncStreamingOperation(OperationFuncT&& operationFunc, + const ClientT* clientThis, + RequestT& request, // note non-const ref + const HandlerT& handler, + const HandlerContextT& context, + ExecutorT* pExecutor) + { + std::function<void()> asyncTask = + [operationFunc, clientThis, &request, handler, context]() // note capture by ref + { + handler(clientThis, + request, + (clientThis->*operationFunc)(request), + context); + }; + + pExecutor->Submit(std::move(asyncTask)); + } + + /** + * A template function to create an Async Operation function body for AWS Operation without a request on input. + */ + template<typename ClientT, + typename HandlerT, + typename HandlerContextT, + typename OperationFuncT, + typename ExecutorT> + inline void AWS_CORE_LOCAL MakeAsyncOperation(OperationFuncT&& operationFunc, + const ClientT* clientThis, + const HandlerT& handler, + const HandlerContextT& context, + ExecutorT* pExecutor) + { + std::function<void()> asyncTask = + [operationFunc, clientThis, handler, context]() + { + handler(clientThis, + (clientThis->*operationFunc)(), + context); + }; + + pExecutor->Submit(std::move(asyncTask)); + } + + /** + * A template function that is used to create a Callable Operation function body for AWS Operations + */ + template<typename ClientT, + typename RequestT, + typename OperationFuncT, + typename ExecutorT> + inline auto AWS_CORE_LOCAL MakeCallableOperation(const char* ALLOCATION_TAG, + OperationFuncT&& operationFunc, + const ClientT* clientThis, + const RequestT& request, + ExecutorT* pExecutor) -> std::future<decltype((clientThis->*operationFunc)(request))> + { + using OperationOutcomeT = decltype((clientThis->*operationFunc)(request)); + + auto task = Aws::MakeShared< std::packaged_task< OperationOutcomeT() > >( + ALLOCATION_TAG, + [clientThis, operationFunc, request]() // note capture by value + { + auto futureOutcome = (clientThis->*operationFunc)(request); + return futureOutcome; + } ); + + std::function<void()> packagedFunction = + [task]() { (*task)(); }; + pExecutor->Submit(std::move(packagedFunction)); + return task->get_future(); + } + + /** + * A template function that is used to create a Callable Operation function body for AWS Streaming Operations + * The only difference compared to a regular non-streaming Operation is that + * the request is passed by non-const reference, therefore virtual copy constructor is not needed. + * However, caller code must ensure the life time of the request object is maintained during the Async execution. + */ + template<typename ClientT, + typename RequestT, + typename OperationFuncT, + typename ExecutorT> + inline auto AWS_CORE_LOCAL MakeCallableStreamingOperation(const char* ALLOCATION_TAG, + OperationFuncT&& operationFunc, + const ClientT* clientThis, + RequestT& request, // note non-const ref + ExecutorT* pExecutor) -> std::future<decltype((clientThis->*operationFunc)(request))> + { + using OperationOutcomeT = decltype((clientThis->*operationFunc)(request)); + + auto task = Aws::MakeShared< std::packaged_task< OperationOutcomeT() > >( + ALLOCATION_TAG, + [clientThis, operationFunc, &request]() // note capture by ref + { + return (clientThis->*operationFunc)(request); + } ); + + std::function<void()> packagedFunction = + [task]() { (*task)(); }; + pExecutor->Submit(std::move(packagedFunction)); + return task->get_future(); + } + + /** + * A template function that is used to create a Callable Operation function body for AWS Operation without a request on input. + */ + template<typename ClientT, + typename OperationFuncT, + typename ExecutorT> + inline auto AWS_CORE_LOCAL MakeCallableOperation(const char* ALLOCATION_TAG, + OperationFuncT&& operationFunc, + const ClientT* clientThis, + ExecutorT* pExecutor) -> std::future<decltype((clientThis->*operationFunc)())> + { + using OperationOutcomeT = decltype((clientThis->*operationFunc)()); + + auto task = Aws::MakeShared< std::packaged_task< OperationOutcomeT() > >( + ALLOCATION_TAG, + [clientThis, operationFunc]() + { + return (clientThis->*operationFunc)(); + } ); + + std::function<void()> packagedFunction = + [task]() { (*task)(); }; + pExecutor->Submit(std::move(packagedFunction)); + return task->get_future(); + } +} // namespace Client +} // namespace Aws + + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSClient.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSClient.h index 186206a66ef..4e67e8a4df2 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSClient.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSClient.h @@ -4,19 +4,21 @@ */ #pragma once +#if !defined(AWS_CLIENT_H) +#define AWS_CLIENT_H #include <aws/core/Core_EXPORTS.h> #include <aws/core/client/CoreErrors.h> +#include <aws/core/client/AWSUrlPresigner.h> #include <aws/core/http/HttpTypes.h> #include <aws/core/utils/memory/stl/AWSString.h> #include <aws/core/AmazonWebServiceResult.h> #include <aws/core/utils/crypto/Hash.h> #include <aws/core/auth/AWSAuthSignerProvider.h> +#include <aws/core/endpoint/AWSEndpoint.h> #include <memory> #include <atomic> -struct aws_array_list; - namespace Aws { namespace Utils @@ -24,16 +26,6 @@ namespace Aws template<typename R, typename E> class Outcome; - namespace Xml - { - class XmlDocument; - } // namespace Xml - - namespace Json - { - class JsonValue; - } // namespace Json - namespace RateLimits { class RateLimiterInterface; @@ -71,7 +63,6 @@ namespace Aws template<typename ERROR_TYPE> class AWSError; class AWSErrorMarshaller; - class AWSRestfulJsonErrorMarshaller; class AWSAuthSigner; struct ClientConfiguration; class RetryStrategy; @@ -80,7 +71,7 @@ namespace Aws typedef Utils::Outcome<AmazonWebServiceResult<Utils::Stream::ResponseStream>, AWSError<CoreErrors>> StreamOutcome; /** - * Abstract AWS Client. Contains most of the functionality necessary to build an http request, get it signed, and send it accross the wire. + * Abstract AWS Client. Contains most of the functionality necessary to build an http request, get it signed, and send it across the wire. */ class AWS_CORE_API AWSClient { @@ -91,8 +82,8 @@ namespace Aws * errorMarshaller tells the client how to convert error payloads into AWSError objects. */ AWSClient(const Aws::Client::ClientConfiguration& configuration, - const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer, - const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); + const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer, + const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); /** * Configuration will be used for http client settings, retry strategy, throttles, and signing information. @@ -100,8 +91,8 @@ namespace Aws * SigV4 signer. errorMarshaller tells the client how to convert error payloads into AWSError objects. */ AWSClient(const Aws::Client::ClientConfiguration& configuration, - const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider, - const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); + const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider, + const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); virtual ~AWSClient() { }; @@ -109,46 +100,69 @@ namespace Aws * Generates a signed Uri using the injected signer. for the supplied uri and http method. expirationInSeconds defaults * to 0 which is the default 7 days. The implication of this function is using auth signer v4 to sign it. */ - Aws::String GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, long long expirationInSeconds = 0); + Aws::String GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, long long expirationInSeconds = 0); /** * Generates a signed Uri using the injected signer. for the supplied uri, http method and customized headers. expirationInSeconds defaults * to 0 which is the default 7 days. The implication of this function is using auth signer v4 to sign it. */ - Aws::String GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds = 0); + Aws::String GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds = 0); /** * Generates a signed Uri using the injected signer. for the supplied uri and http method and region. expirationInSeconds defaults * to 0 which is the default 7 days. */ - Aws::String GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, long long expirationInSeconds = 0) const; + Aws::String GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, long long expirationInSeconds = 0) const; /** * Generates a signed Uri using the injected signer. for the supplied uri, http method and customized headers. expirationInSeconds defaults * to 0 which is the default 7 days. */ - Aws::String GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds = 0); + Aws::String GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds = 0); /** * Generates a signed Uri using the injected signer. for the supplied uri and http method, region, and service name. expirationInSeconds defaults * to 0 which is the default 7 days. */ - Aws::String GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, long long expirationInSeconds = 0) const; + Aws::String GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, long long expirationInSeconds = 0) const; /** * Generates a signed Uri using the injected signer. for the supplied uri, http method and customized headers. expirationInSeconds defaults * to 0 which is the default 7 days. */ - Aws::String GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds = 0); + Aws::String GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds = 0); - Aws::String GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, Aws::Http::HttpMethod method, - const Aws::Http::QueryStringParameterCollection& extraParams = Aws::Http::QueryStringParameterCollection(), long long expirationInSeconds = 0) const; + /** + * Generates a signed Uri using the injected signer. for the supplied uri and http method, region, service name and signer name. expirationInSeconds defaults + * to 0 which is the default 7 days. + */ + Aws::String GeneratePresignedUrl(const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, const char* signerName, long long expirationInSeconds = 0) const; - Aws::String GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, - const Aws::Http::QueryStringParameterCollection& extraParams = Aws::Http::QueryStringParameterCollection(), long long expirationInSeconds = 0) const; + /** + * Generates a signed Uri using the injected signer. for the supplied uri, http method, region, service name, signer name and customized headers. expirationInSeconds defaults + * to 0 which is the default 7 days. + */ + Aws::String 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 = 0); - Aws::String GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, - const Aws::Http::QueryStringParameterCollection& extraParams = Aws::Http::QueryStringParameterCollection(), long long expirationInSeconds = 0) const; + Aws::String 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); + + Aws::String GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, const Aws::Http::URI& uri, Aws::Http::HttpMethod method, + const Aws::Http::QueryStringParameterCollection& extraParams = Aws::Http::QueryStringParameterCollection(), long long expirationInSeconds = 0) const; + + Aws::String 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 = Aws::Http::QueryStringParameterCollection(), long long expirationInSeconds = 0) const; + + Aws::String 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 = Aws::Http::QueryStringParameterCollection(), long long expirationInSeconds = 0) const; + + Aws::String GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, + const Aws::Http::QueryStringParameterCollection& extraParams = Aws::Http::QueryStringParameterCollection(), long long expirationInSeconds = 0) const; /** * Stop all requests immediately. @@ -175,11 +189,11 @@ namespace Aws * or encounters and error that is not retryable. */ HttpResponseOutcome AttemptExhaustively(const Aws::Http::URI& uri, - const Aws::AmazonWebServiceRequest& request, - Http::HttpMethod httpMethod, - const char* signerName, - const char* signerRegionOverride = nullptr, - const char* signerServiceNameOverride = nullptr) const; + const Aws::AmazonWebServiceRequest& request, + Http::HttpMethod httpMethod, + const char* signerName, + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const; /** * Calls AttemptOneRequest until it either, succeeds, runs out of retries from the retry strategy, @@ -189,45 +203,45 @@ namespace Aws * name. */ HttpResponseOutcome AttemptExhaustively(const Aws::Http::URI& uri, - Http::HttpMethod httpMethod, - const char* signerName, - const char* requestName = "", - const char* signerRegionOverride = nullptr, - const char* signerServiceNameOverride = nullptr) const; + Http::HttpMethod httpMethod, + const char* signerName, + const char* requestName = "", + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const; /** - * Build an Http Request from the AmazonWebServiceRequest object. Signs the request, sends it accross the wire + * Build an Http Request from the AmazonWebServiceRequest object. Signs the request, sends it across the wire * then reports the http response. */ HttpResponseOutcome AttemptOneRequest(const std::shared_ptr<Http::HttpRequest>& httpRequest, - const Aws::AmazonWebServiceRequest& request, - const char* signerName, - const char* signerRegionOverride = nullptr, - const char* signerServiceNameOverride = nullptr) const; + const Aws::AmazonWebServiceRequest& request, + const char* signerName, + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const; /** - * Signs an Http Request, sends it accross the wire + * Signs an Http Request, sends it across the wire * then reports the http response. This method is for payloadless requests e.g. GET, DELETE, HEAD * * requestName is used for metrics and defaults to empty string, to avoid empty names in metrics provide a valid * name. */ HttpResponseOutcome AttemptOneRequest(const std::shared_ptr<Http::HttpRequest>& httpRequest, - const char* signerName, - const char* requestName = "", - const char* signerRegionOverride = nullptr, - const char* signerServiceNameOverride = nullptr) const; + const char* signerName, + const char* requestName = "", + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const; /** * This is used for structureless response payloads (file streams, binary data etc...). It calls AttemptExhaustively, but upon * return transfers ownership of the underlying stream for the http response to the caller. */ StreamOutcome MakeRequestWithUnparsedResponse(const Aws::Http::URI& uri, - const Aws::AmazonWebServiceRequest& request, - Http::HttpMethod method = Http::HttpMethod::HTTP_POST, - const char* signerName = Aws::Auth::SIGV4_SIGNER, - const char* signerRegionOverride = nullptr, - const char* signerServiceNameOverride = nullptr) const; + const Aws::AmazonWebServiceRequest& request, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const; /** * This is used for structureless response payloads (file streams, binary data etc...). It calls AttemptExhaustively, but upon @@ -237,11 +251,18 @@ namespace Aws * name. */ StreamOutcome MakeRequestWithUnparsedResponse(const Aws::Http::URI& uri, - Http::HttpMethod method = Http::HttpMethod::HTTP_POST, - const char* signerName = Aws::Auth::SIGV4_SIGNER, - const char* requestName = "", - const char* signerRegionOverride = nullptr, - const char* signerServiceNameOverride = nullptr) const; + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* requestName = "", + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const; + + StreamOutcome MakeRequestWithUnparsedResponse(const Aws::AmazonWebServiceRequest& request, + const Aws::Endpoint::AWSEndpoint& endpoint, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const; /** * Abstract. Subclassing clients should override this to tell the client how to marshall error payloads @@ -252,7 +273,7 @@ namespace Aws * Transforms the AmazonWebServicesResult object into an HttpRequest. */ virtual void BuildHttpRequest(const Aws::AmazonWebServiceRequest& request, - const std::shared_ptr<Aws::Http::HttpRequest>& httpRequest) const; + const std::shared_ptr<Aws::Http::HttpRequest>& httpRequest) const; /** * Gets the underlying ErrorMarshaller for subclasses to use. @@ -266,6 +287,8 @@ namespace Aws * Gets the corresponding signer from the signers map by name. */ Aws::Client::AWSAuthSigner* GetSignerByName(const char* name) const; + + friend Aws::Client::AWSAuthSigner* AWSUrlPresigner::GetSignerByName(const char* name) const; protected: /** @@ -276,14 +299,24 @@ namespace Aws * event-streams. */ std::shared_ptr<Aws::Http::HttpRequest> BuildAndSignHttpRequest(const Aws::Http::URI& uri, - const Aws::AmazonWebServiceRequest& request, - Http::HttpMethod method, const char* signerName) const; + const Aws::AmazonWebServiceRequest& request, + Http::HttpMethod method, const char* signerName) const; /** * Performs the HTTP request via the HTTP client while enforcing rate limiters */ std::shared_ptr<Aws::Http::HttpResponse> MakeHttpRequest(std::shared_ptr<Aws::Http::HttpRequest>& request) const; Aws::String m_region; + + /** + * Adds "X-Amzn-Trace-Id" header with the value of _X_AMZN_TRACE_ID if both + * environment variables AWS_LAMBDA_FUNCTION_NAME and _X_AMZN_TRACE_ID are set. + * Does not add/modify header "X-Amzn-Trace-Id" if it is already set. + */ + static void AppendRecursionDetectionHeader(std::shared_ptr<Aws::Http::HttpRequest> ioRequest); + + static CoreErrors GuessBodylessErrorType(Aws::Http::HttpResponseCode responseCode); + static bool DoesResponseGenerateError(const std::shared_ptr<Aws::Http::HttpResponse>& response); private: /** * Try to adjust signer's clock @@ -291,12 +324,11 @@ namespace Aws */ bool AdjustClockSkew(HttpResponseOutcome& outcome, const char* signerName) const; void AddHeadersToRequest(const std::shared_ptr<Aws::Http::HttpRequest>& httpRequest, const Http::HeaderValueCollection& headerValues) const; + void AddChecksumToRequest(const std::shared_ptr<Aws::Http::HttpRequest>& HttpRequest, const Aws::AmazonWebServiceRequest& request) const; void AddContentBodyToRequest(const std::shared_ptr<Aws::Http::HttpRequest>& httpRequest, const std::shared_ptr<Aws::IOStream>& body, bool needsContentMd5 = false, bool isChunked = false) const; void AddCommonHeaders(Aws::Http::HttpRequest& httpRequest) const; - void InitializeGlobalStatics(); - std::shared_ptr<Aws::Http::HttpRequest> ConvertToRequestForPresigning(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, - Aws::Http::HttpMethod method, const Aws::Http::QueryStringParameterCollection& extraParams) const; + std::shared_ptr<Aws::IOStream> GetBodyStream(const Aws::AmazonWebServiceRequest& request) const; std::shared_ptr<Aws::Http::HttpClient> m_httpClient; std::shared_ptr<Aws::Auth::AWSAuthSignerProvider> m_signerProvider; @@ -310,154 +342,19 @@ namespace Aws long m_requestTimeoutMs; bool m_enableClockSkewAdjustment; Aws::String m_serviceName; + Aws::Client::RequestCompressionConfig m_requestCompressionConfig; + void AppendHeaderValueToRequest( + const std::shared_ptr<Http::HttpRequest> &request, String header, + String value) const; }; - typedef Utils::Outcome<AmazonWebServiceResult<Utils::Json::JsonValue>, AWSError<CoreErrors>> JsonOutcome; AWS_CORE_API Aws::String GetAuthorizationHeader(const Aws::Http::HttpRequest& httpRequest); - - /** - * AWSClient that handles marshalling json response bodies. You would inherit from this class - * to create a client that uses Json as its payload format. - */ - class AWS_CORE_API AWSJsonClient : public AWSClient - { - public: - typedef AWSClient BASECLASS; - - /** - * Simply calls AWSClient constructor. - */ - AWSJsonClient(const Aws::Client::ClientConfiguration& configuration, - const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer, - const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); - - /** - * Simply calls AWSClient constructor. - */ - AWSJsonClient(const Aws::Client::ClientConfiguration& configuration, - const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider, - const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); - - virtual ~AWSJsonClient() = default; - - protected: - /** - * Converts/Parses an http response into a meaningful AWSError object using the json message structure. - */ - virtual AWSError<CoreErrors> BuildAWSError(const std::shared_ptr<Aws::Http::HttpResponse>& response) const override; - - /** - * Returns a Json document or an error from the request. Does some marshalling json and raw streams, - * then just calls AttemptExhaustively. - * - * method defaults to POST - */ - JsonOutcome MakeRequest(const Aws::Http::URI& uri, - const Aws::AmazonWebServiceRequest& request, - Http::HttpMethod method = Http::HttpMethod::HTTP_POST, - const char* signerName = Aws::Auth::SIGV4_SIGNER, - const char* signerRegionOverride = nullptr, - const char* signerServiceNameOverride = nullptr) const; - - /** - * Returns a Json document or an error from the request. Does some marshalling json and raw streams, - * then just calls AttemptExhaustively. - * - * requestName is used for metrics and defaults to empty string, to avoid empty names in metrics provide a valid - * name. - * - * method defaults to POST - */ - JsonOutcome MakeRequest(const Aws::Http::URI& uri, - Http::HttpMethod method = Http::HttpMethod::HTTP_POST, - const char* signerName = Aws::Auth::SIGV4_SIGNER, - const char* requestName = "", - const char* signerRegionOverride = nullptr, - const char* signerServiceNameOverride = nullptr) const; - - JsonOutcome MakeEventStreamRequest(std::shared_ptr<Aws::Http::HttpRequest>& request) const; - }; - - typedef Utils::Outcome<AmazonWebServiceResult<Utils::Xml::XmlDocument>, AWSError<CoreErrors>> XmlOutcome; - - /** - * AWSClient that handles marshalling xml response bodies. You would inherit from this class - * to create a client that uses Xml as its payload format. - */ - class AWS_CORE_API AWSXMLClient : public AWSClient - { - public: - - typedef AWSClient BASECLASS; - - AWSXMLClient(const Aws::Client::ClientConfiguration& configuration, - const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer, - const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); - - AWSXMLClient(const Aws::Client::ClientConfiguration& configuration, - const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider, - const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); - - virtual ~AWSXMLClient() = default; - - protected: - /** - * Converts/Parses an http response into a meaningful AWSError object. Using the XML message structure. - */ - virtual AWSError<CoreErrors> BuildAWSError(const std::shared_ptr<Aws::Http::HttpResponse>& response) const override; - - /** - * Returns an xml document or an error from the request. Does some marshalling xml and raw streams, - * then just calls AttemptExhaustively. - * - * method defaults to POST - */ - XmlOutcome MakeRequest(const Aws::Http::URI& uri, - const Aws::AmazonWebServiceRequest& request, - Http::HttpMethod method = Http::HttpMethod::HTTP_POST, - const char* signerName = Aws::Auth::SIGV4_SIGNER, - const char* signerRegionOverride = nullptr, - const char* signerServiceNameOverride = nullptr) const; - - - /** - * Returns an xml document or an error from the request. Does some marshalling xml and raw streams, - * then just calls AttemptExhaustively. - * - * requestName is used for metrics and defaults to empty string, to avoid empty names in metrics provide a valid - * name. - * - * method defaults to POST - */ - XmlOutcome MakeRequest(const Aws::Http::URI& uri, - Http::HttpMethod method = Http::HttpMethod::HTTP_POST, - const char* signerName = Aws::Auth::SIGV4_SIGNER, - const char* requestName = "", - const char* signerRegionOverride = nullptr, - const char* signerServiceNameOverride = nullptr) const; - - /** - * This is used for event stream response. - */ - XmlOutcome MakeRequestWithEventStream(const Aws::Http::URI& uri, - const Aws::AmazonWebServiceRequest& request, - Http::HttpMethod method = Http::HttpMethod::HTTP_POST, - const char* singerName = Aws::Auth::SIGV4_SIGNER, - const char* signerRegionOverride = nullptr, - const char* signerServiceNameOverride = nullptr) const; - - /** - * This is used for event stream response. - * requestName is used for metrics and defaults to empty string, to avoid empty names in metrics provide a valid - * name. - */ - XmlOutcome MakeRequestWithEventStream(const Aws::Http::URI& uri, - Http::HttpMethod method = Http::HttpMethod::HTTP_POST, - const char* signerName = Aws::Auth::SIGV4_SIGNER, - const char* requestName = "", - const char* signerRegionOverride = nullptr, - const char* signerServiceNameOverride = nullptr) const; - }; - } // namespace Client } // namespace Aws + +#if !defined(AWS_JSON_CLIENT_H) && !defined(AWS_XML_CLIENT_H) +/* Legacy backward compatibility macros to not break the build for ones including just AWSClient.h */ +#include <aws/core/client/AWSJsonClient.h> +#include <aws/core/client/AWSXmlClient.h> +#endif // !defined(AWS_JSON_CLIENT_H) && !defined(AWS_XML_CLIENT_H) +#endif // !defined(AWS_CLIENT_H)
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSClientAsyncCRTP.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSClientAsyncCRTP.h new file mode 100644 index 00000000000..a31b1c17832 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSClientAsyncCRTP.h @@ -0,0 +1,125 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/client/AWSAsyncOperationTemplate.h> + +namespace Aws +{ +namespace Client +{ + class AsyncCallerContext; + + /** + * A helper to determine if AWS Operation is EventStream-enabled or not (based on const-ness of the request) + */ + template<typename T> + struct AWS_CORE_LOCAL IsEventStreamOperation : IsEventStreamOperation<decltype(&T::operator())> {}; + + template<typename ReturnT, typename ClassT, typename RequestT> + struct AWS_CORE_LOCAL IsEventStreamOperation<ReturnT(ClassT::*)(RequestT) const> + { + static const bool value = !std::is_const<typename std::remove_reference<RequestT>::type>::value; + }; + + template<typename ReturnT, typename ClassT> + struct AWS_CORE_LOCAL IsEventStreamOperation<ReturnT(ClassT::*)() const> + { + static const bool value = false; + }; + + + /** + * A CRTP-base class template that is used to add template methods to call AWS Operations in parallel using ThreadExecutor + * An Aws<Service>Client is going to inherit from this class and will get methods below available. + */ + template <typename AwsServiceClientT> + class ClientWithAsyncTemplateMethods + { + public: + /** + * A template to submit a AwsServiceClient regular operation method for async execution. + * This template method copies and queues the request into a thread executor and triggers associated callback when operation has finished. + */ + template<typename RequestT, typename HandlerT, typename OperationFuncT, typename std::enable_if<!IsEventStreamOperation<OperationFuncT>::value, int>::type = 0> + void SubmitAsync(OperationFuncT operationFunc, + const RequestT& request, + const HandlerT& handler, + const std::shared_ptr<const Aws::Client::AsyncCallerContext>& context = nullptr) const + { + const AwsServiceClientT* clientThis = static_cast<const AwsServiceClientT*>(this); + Aws::Client::MakeAsyncOperation(operationFunc, clientThis, request, handler, context, clientThis->m_executor.get()); + } + + /** + * A template to submit a AwsServiceClient event stream enabled operation method for async execution. + * This template method queues the original request object into a thread executor and triggers associated callback when operation has finished. + * It is caller's responsibility to ensure the lifetime of the original request object for a duration of the async execution. + */ + template<typename RequestT, typename HandlerT, typename OperationFuncT, typename std::enable_if<IsEventStreamOperation<OperationFuncT>::value, int>::type = 0> + void SubmitAsync(OperationFuncT operationFunc, + RequestT& request, // note non-const ref + const HandlerT& handler, + const std::shared_ptr<const Aws::Client::AsyncCallerContext>& context = nullptr) const + { + const AwsServiceClientT* clientThis = static_cast<const AwsServiceClientT*>(this); + Aws::Client::MakeAsyncStreamingOperation(operationFunc, clientThis, request, handler, context, clientThis->m_executor.get()); + } + + /** + * A template to submit a AwsServiceClient regular operation method without arguments for async execution. + * This template method submits a task into a thread executor and triggers associated callback when operation has finished. + */ + template<typename HandlerT, typename OperationFuncT> + void SubmitAsync(OperationFuncT operationFunc, + const HandlerT& handler, + const std::shared_ptr<const Aws::Client::AsyncCallerContext>& context = nullptr) const + { + const AwsServiceClientT* clientThis = static_cast<const AwsServiceClientT*>(this); + Aws::Client::MakeAsyncOperation(operationFunc, clientThis, handler, context, clientThis->m_executor.get()); + } + + /** + * A template to submit a AwsServiceClient regular operation method for async execution that returns a future<OperationOutcome> object. + * This template method copies and queues the request into a thread executor and returns a future<OperationOutcome> object when operation has finished. + */ + template<typename RequestT, typename OperationFuncT, typename std::enable_if<!IsEventStreamOperation<OperationFuncT>::value, int>::type = 0> + auto SubmitCallable(OperationFuncT operationFunc, + const RequestT& request) const + -> std::future<decltype((static_cast<const AwsServiceClientT*>(nullptr)->*operationFunc)(request))> + { + const AwsServiceClientT* clientThis = static_cast<const AwsServiceClientT*>(this); + return Aws::Client::MakeCallableOperation(AwsServiceClientT::ALLOCATION_TAG, operationFunc, clientThis, request, clientThis->m_executor.get()); + } + + /** + * A template to submit a AwsServiceClient event stream enabled operation method for async execution that returns a future<OperationOutcome> object. + * This template method queues the original request into a thread executor and returns a future<OperationOutcome> object when operation has finished. + * It is caller's responsibility to ensure the lifetime of the original request object for a duration of the async execution. + */ + template<typename RequestT, typename OperationFuncT, typename std::enable_if<IsEventStreamOperation<OperationFuncT>::value, int>::type = 0> + auto SubmitCallable(OperationFuncT operationFunc, /*note non-const ref*/ RequestT& request) const + -> std::future<decltype((static_cast<const AwsServiceClientT*>(nullptr)->*operationFunc)(request))> + { + const AwsServiceClientT* clientThis = static_cast<const AwsServiceClientT*>(this); + return Aws::Client::MakeCallableStreamingOperation(AwsServiceClientT::ALLOCATION_TAG, operationFunc, clientThis, request, clientThis->m_executor.get()); + } + + /** + * A template to submit a AwsServiceClient regular operation without request argument for + * an async execution that returns a future<OperationOutcome> object. + * This template method copies and queues the request into a thread executor and returns a future<OperationOutcome> object when operation has finished. + */ + template<typename OperationFuncT> + auto SubmitCallable(OperationFuncT operationFunc) const + -> std::future<decltype((static_cast<const AwsServiceClientT*>(nullptr)->*operationFunc)())> + { + const AwsServiceClientT* clientThis = static_cast<const AwsServiceClientT*>(this); + return Aws::Client::MakeCallableOperation(AwsServiceClientT::ALLOCATION_TAG, operationFunc, clientThis, clientThis->m_executor.get()); + } + }; +} // namespace Client +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSError.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSError.h index 39f033c3fce..e9df0be8a25 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSError.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSError.h @@ -12,6 +12,13 @@ #include <aws/core/utils/json/JsonSerializer.h> #include <aws/core/utils/StringUtils.h> +// TODO: temporary fix for naming conflicts on Windows. +#ifdef _WIN32 +#ifdef GetMessage +#undef GetMessage +#endif +#endif + namespace Aws { namespace Client @@ -41,12 +48,17 @@ namespace Aws /** * Initializes AWSError object as empty with the error not being retryable. */ - AWSError() : m_responseCode(Aws::Http::HttpResponseCode::REQUEST_NOT_MADE), m_isRetryable(false) {} + AWSError() + : m_errorType(), + m_responseCode(Aws::Http::HttpResponseCode::REQUEST_NOT_MADE), + m_isRetryable(false), + m_errorPayloadType(ErrorPayloadType::NOT_SET) + {} /** * Initializes AWSError object with errorType, exceptionName, message, and retryable flag. */ - AWSError(ERROR_TYPE errorType, Aws::String exceptionName, const Aws::String message, bool isRetryable) : - m_errorType(errorType), m_exceptionName(exceptionName), m_message(message), + AWSError(ERROR_TYPE errorType, Aws::String exceptionName, Aws::String message, bool isRetryable) + : m_errorType(errorType), m_exceptionName(std::move(exceptionName)), m_message(std::move(message)), m_responseCode(Aws::Http::HttpResponseCode::REQUEST_NOT_MADE), m_isRetryable(isRetryable), m_errorPayloadType(ErrorPayloadType::NOT_SET) {} /** @@ -85,7 +97,7 @@ namespace Aws /** * Move assignment operator */ - AWSError& operator=(AWSError<ERROR_TYPE>&& other) = default; + AWSError& operator=(AWSError<ERROR_TYPE>&&) = default; /** * Gets underlying errorType. @@ -191,10 +203,10 @@ namespace Aws Aws::String m_remoteHostIpAddress; Aws::String m_requestId; Aws::Http::HeaderValueCollection m_responseHeaders; - Aws::Http::HttpResponseCode m_responseCode; - bool m_isRetryable; + Aws::Http::HttpResponseCode m_responseCode = Aws::Http::HttpResponseCode::REQUEST_NOT_MADE; + bool m_isRetryable = false; - ErrorPayloadType m_errorPayloadType; + ErrorPayloadType m_errorPayloadType = ErrorPayloadType::NOT_SET; Aws::Utils::Xml::XmlDocument m_xmlPayload; Aws::Utils::Json::JsonValue m_jsonPayload; }; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSJsonClient.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSJsonClient.h new file mode 100644 index 00000000000..877db0aec5b --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSJsonClient.h @@ -0,0 +1,110 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once +#if !defined(AWS_JSON_CLIENT_H) +#define AWS_JSON_CLIENT_H + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/client/AWSClient.h> + +namespace Aws +{ + namespace Utils + { + namespace Json + { + class JsonValue; + } // namespace Json + } // namespace Utils + + namespace Client + { + typedef Utils::Outcome<AmazonWebServiceResult<Utils::Json::JsonValue>, AWSError<CoreErrors>> JsonOutcome; + /** + * AWSClient that handles marshalling json response bodies. You would inherit from this class + * to create a client that uses Json as its payload format. + */ + class AWS_CORE_API AWSJsonClient : public AWSClient + { + public: + typedef AWSClient BASECLASS; + + /** + * Simply calls AWSClient constructor. + */ + AWSJsonClient(const Aws::Client::ClientConfiguration& configuration, + const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer, + const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); + + /** + * Simply calls AWSClient constructor. + */ + AWSJsonClient(const Aws::Client::ClientConfiguration& configuration, + const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider, + const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); + + virtual ~AWSJsonClient() = default; + + protected: + /** + * Converts/Parses an http response into a meaningful AWSError object using the json message structure. + */ + virtual AWSError<CoreErrors> BuildAWSError(const std::shared_ptr<Aws::Http::HttpResponse>& response) const override; + + /** + * Returns a Json document or an error from the request. Does some marshalling json and raw streams, + * then just calls AttemptExhaustively. + * + * method defaults to POST + */ + JsonOutcome MakeRequest(const Aws::AmazonWebServiceRequest& request, + const Aws::Endpoint::AWSEndpoint& endpoint, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const; + + JsonOutcome MakeRequest(const Aws::Endpoint::AWSEndpoint& endpoint, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const; + + /** + * Returns a Json document or an error from the request. Does some marshalling json and raw streams, + * then just calls AttemptExhaustively. + * + * method defaults to POST + */ + JsonOutcome MakeRequest(const Aws::Http::URI& uri, + const Aws::AmazonWebServiceRequest& request, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const; + + /** + * Returns a Json document or an error from the request. Does some marshalling json and raw streams, + * then just calls AttemptExhaustively. + * + * requestName is used for metrics and defaults to empty string, to avoid empty names in metrics provide a valid + * name. + * + * method defaults to POST + */ + JsonOutcome MakeRequest(const Aws::Http::URI& uri, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* requestName = "", + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const; + + JsonOutcome MakeEventStreamRequest(std::shared_ptr<Aws::Http::HttpRequest>& request) const; + }; + } // namespace Client +} // namespace Aws + +#endif // !defined(AWS_JSON_CLIENT_H)
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSUrlPresigner.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSUrlPresigner.h new file mode 100644 index 00000000000..01601c1eb1d --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSUrlPresigner.h @@ -0,0 +1,176 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/AmazonWebServiceRequest.h> +#include <aws/core/endpoint/AWSEndpoint.h> + +#include <aws/core/utils/memory/stl/AWSString.h> + +namespace Aws +{ + namespace Client + { + class AWSClient; + + /** + * Helper class to generate pre-signed AWS URLs. + */ + class AWS_CORE_API AWSUrlPresigner + { + public: + AWSUrlPresigner(const AWSClient& client); + + virtual ~AWSUrlPresigner() {}; + + /** + * Generates a signed Uri using the injected signer, for the supplied uri and http method. expirationInSeconds defaults + * to 0 which is the default 7 days. The implication of this function is using auth signer v4 to sign it. + */ + Aws::String GeneratePresignedUrl(const Aws::Http::URI &uri, + Aws::Http::HttpMethod method, + long long expirationInSeconds = 0) const; + + /** + * Generates a signed Uri using the injected signer, for the supplied uri, http method, and customized headers. expirationInSeconds defaults + * to 0 which is the default 7 days. The implication of this function is using auth signer v4 to sign it. + */ + Aws::String GeneratePresignedUrl(const Aws::Http::URI &uri, + Aws::Http::HttpMethod method, + const Aws::Http::HeaderValueCollection &customizedHeaders, + long long expirationInSeconds = 0) const; + + /** + * Generates a signed Uri using the injected signer, for the supplied uri, http method, and region. expirationInSeconds defaults + * to 0 which is the default 7 days. + */ + Aws::String GeneratePresignedUrl(const Aws::Http::URI &uri, + Aws::Http::HttpMethod method, + const char *regionOverride, + long long expirationInSeconds = 0) const; + + /** + * Generates a signed Uri using the injected signer, for the supplied uri, http method, and customized headers. expirationInSeconds defaults + * to 0 which is the default 7 days. + */ + Aws::String GeneratePresignedUrl(const Aws::Http::URI &uri, + Aws::Http::HttpMethod method, + const char *regionOverride, + const Aws::Http::HeaderValueCollection &customizedHeaders, + long long expirationInSeconds = 0) const; + + /** + * Generates a signed Uri using the injected signer, for the supplied uri, http method, region, and service name. expirationInSeconds defaults + * to 0 which is the default 7 days. + */ + Aws::String GeneratePresignedUrl(const Aws::Http::URI &uri, + Aws::Http::HttpMethod method, + const char *regionOverride, + const char *serviceNameOverride, + long long expirationInSeconds = 0) const; + + /** + * Generates a signed Uri using the injected signer, for the supplied uri, http method, and customized headers. expirationInSeconds defaults + * to 0 which is the default 7 days. + */ + Aws::String GeneratePresignedUrl(const Aws::Http::URI &uri, + Aws::Http::HttpMethod method, + const char *regionOverride, + const char *serviceNameOverride, + const Aws::Http::HeaderValueCollection &customizedHeaders, + long long expirationInSeconds = 0) const; + + /** + * Generates a signed Uri using the injected signer, for the supplied uri, http method, region, service name, and signer name. expirationInSeconds defaults + * to 0 which is the default 7 days. + */ + Aws::String GeneratePresignedUrl(const Aws::Http::URI &uri, + Aws::Http::HttpMethod method, + const char *regionOverride, + const char *serviceNameOverride, + const char *signerName, + long long expirationInSeconds = 0) const; + + /** + * Generates a signed Uri using the injected signer, for the supplied uri, http method, region, service name, signer name, and customized headers. expirationInSeconds defaults + * to 0 which is the default 7 days. + * + * This is a real method for uri pre-signing, the rest are just overloads. + */ + Aws::String GeneratePresignedUrl(const Aws::Http::URI &uri, + Aws::Http::HttpMethod method, + const char *regionOverride, + const char *serviceNameOverride, + const char *signerName, + const Aws::Http::HeaderValueCollection &customizedHeaders, + long long expirationInSeconds = 0) const; + + /** + * Generates a signed Uri for a supplied AWSEndpoint. + */ + Aws::String 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; + + /** + * Generates a signed Uri for a supplied request and uri. + */ + Aws::String GeneratePresignedUrl(const Aws::AmazonWebServiceRequest &request, + const Aws::Http::URI &uri, + Aws::Http::HttpMethod method, + const Aws::Http::QueryStringParameterCollection &extraParams = Aws::Http::QueryStringParameterCollection(), + long long expirationInSeconds = 0) const; + + /** + * Generates a signed Uri using the injected signer. for the supplied request object, uri, http method, region, service name, signer name, and customized headers. + * expirationInSeconds defaults to 0 which is the default 7 days. + * + * This is a real method for request+uri pre-signing, the rest are just overloads. + */ + Aws::String 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 = Aws::Http::QueryStringParameterCollection(), + long long expirationInSeconds = 0) const; + + /** + * Generates a signed Uri for a supplied request and uri. + */ + Aws::String 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 = Aws::Http::QueryStringParameterCollection(), + long long expirationInSeconds = 0) const; + + /** + * Generates a signed Uri for a supplied request and uri. + */ + Aws::String GeneratePresignedUrl(const Aws::AmazonWebServiceRequest &request, + const Aws::Http::URI &uri, + Aws::Http::HttpMethod method, + const char *regionOverride, + const Aws::Http::QueryStringParameterCollection &extraParams = Aws::Http::QueryStringParameterCollection(), + long long expirationInSeconds = 0) const; + + protected: + const AWSClient& m_awsClient; + + friend class AWSClient; // allow AWSClient to see method below to make friends with it + Aws::Client::AWSAuthSigner* GetSignerByName(const char* name) const; + }; // class AWSUrlPresigner + + } // namespace Client +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSXmlClient.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSXmlClient.h new file mode 100644 index 00000000000..1d3426e6e89 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSXmlClient.h @@ -0,0 +1,135 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once +#if !defined(AWS_XML_CLIENT_H) +#define AWS_XML_CLIENT_H + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/client/AWSClient.h> + +namespace Aws +{ + namespace Utils + { + namespace Xml + { + class XmlDocument; + } // namespace Xml + } // namespace Utils + + namespace Client + { + typedef Utils::Outcome<AmazonWebServiceResult<Utils::Xml::XmlDocument>, AWSError<CoreErrors>> XmlOutcome; + + /** + * AWSClient that handles marshalling xml response bodies. You would inherit from this class + * to create a client that uses Xml as its payload format. + */ + class AWS_CORE_API AWSXMLClient : public AWSClient + { + public: + typedef AWSClient BASECLASS; + + AWSXMLClient(const Aws::Client::ClientConfiguration& configuration, + const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer, + const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); + + AWSXMLClient(const Aws::Client::ClientConfiguration& configuration, + const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider, + const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); + + virtual ~AWSXMLClient() = default; + + protected: + /** + * Converts/Parses an http response into a meaningful AWSError object. Using the XML message structure. + */ + virtual AWSError<CoreErrors> BuildAWSError(const std::shared_ptr<Aws::Http::HttpResponse>& response) const override; + + /** + * Returns an xml document or an error from the request. Does some marshalling xml and raw streams, + * then just calls AttemptExhaustively. + * + * method defaults to POST + */ + XmlOutcome MakeRequest(const Aws::AmazonWebServiceRequest& request, + const Aws::Endpoint::AWSEndpoint& endpoint, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const; + + XmlOutcome MakeRequest(const Aws::Endpoint::AWSEndpoint& endpoint, + const char* requestName = "", + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const; + + /** + * Returns an xml document or an error from the request. Does some marshalling xml and raw streams, + * then just calls AttemptExhaustively. + * + * method defaults to POST + */ + XmlOutcome MakeRequest(const Aws::Http::URI& uri, + const Aws::AmazonWebServiceRequest& request, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const; + + + /** + * Returns an xml document or an error from the request. Does some marshalling xml and raw streams, + * then just calls AttemptExhaustively. + * + * requestName is used for metrics and defaults to empty string, to avoid empty names in metrics provide a valid + * name. + * + * method defaults to POST + */ + XmlOutcome MakeRequest(const Aws::Http::URI& uri, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* requestName = "", + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const; + + /** + * This is used for event stream response. + */ + XmlOutcome MakeRequestWithEventStream(const Aws::Http::URI& uri, + const Aws::AmazonWebServiceRequest& request, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + const char* singerName = Aws::Auth::SIGV4_SIGNER, + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const; + + XmlOutcome MakeRequestWithEventStream(const Aws::AmazonWebServiceRequest& request, + const Aws::Endpoint::AWSEndpoint& endpoint, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const; + + /** + * This is used for event stream response. + * requestName is used for metrics and defaults to empty string, to avoid empty names in metrics provide a valid + * name. + */ + XmlOutcome MakeRequestWithEventStream(const Aws::Http::URI& uri, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, + const char* requestName = "", + const char* signerRegionOverride = nullptr, + const char* signerServiceNameOverride = nullptr) const; + }; + + } // namespace Client +} // namespace Aws + +#endif // !defined(AWS_XML_CLIENT_H)
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AdaptiveRetryStrategy.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AdaptiveRetryStrategy.h new file mode 100644 index 00000000000..b0a51126cd7 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AdaptiveRetryStrategy.h @@ -0,0 +1,154 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/client/RetryStrategy.h> +#include <aws/core/utils/DateTime.h> + +namespace Aws +{ +namespace Client +{ + +/** + * A helper class of the AdaptiveRetryStrategy + * representing a (send) token bucket with a dynamically changing fill rate and capacity. + */ +class AWS_CORE_API RetryTokenBucket +{ +public: + /** + * C-tor + */ + RetryTokenBucket() = default; + + /** + * Acquire tokens from the bucket. If the bucket contains enough capacity + * to satisfy the request, this method will return immediately, otherwise + * the method will block the calling thread until enough tokens are refilled + * unless fast fail is provided as an argument. + */ + bool Acquire(size_t amount = 1, bool fastFail = false); + + /** + * Update limiter's client sending rate during the request bookkeeping process + * based on a service response. + */ + void UpdateClientSendingRate(bool throttlingResponse, const Aws::Utils::DateTime& now = Aws::Utils::DateTime::Now()); + +protected: + /** + * Internal C-tor for unit testing + */ + 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); + + /** + * Internal method to update the token bucket's fill rate when we receive a response from the service. + * The update amount will depend on whether or not a throttling response is received from a service. + * The request rate is measured using an exponentially smoothed average, + * with the rate being updated in half second buckets. + */ + void UpdateMeasuredRate(const Aws::Utils::DateTime& now = Aws::Utils::DateTime::Now()); + + /** + * Internal method to enable rate limiting. + */ + void Enable(); + + /** + * Internal method to refill and update refill rate with a new refill rate. + */ + void UpdateRate(double newRps, const Aws::Utils::DateTime& now = Aws::Utils::DateTime::Now()); + + /** + * Internal method to refill send tokens based on a current fill rate. + */ + void Refill(const Aws::Utils::DateTime& now = Aws::Utils::DateTime::Now()); + + /** + * Internal method to compute time window for a last max fill rate. + */ + double CalculateTimeWindow() const; + + /** + * Internal method with a modified CUBIC algorithm to compute new max sending rate for a successful response. + */ + double CUBICSuccess(const Aws::Utils::DateTime& timestamp, const double timeWindow) const; + + /** + * Internal method with a modified CUBIC algorithm to compute new max sending rate for a throttled response. + */ + double CUBICThrottle(const double rateToUse) const; + + // The rate at which token are replenished. + double m_fillRate = 0.0; + // The maximum capacity allowed in the token bucket. + double m_maxCapacity = 0.0; + // The current capacity of the token bucket. + double m_currentCapacity = 0.0; + // The last time the token bucket was refilled. + Aws::Utils::DateTime m_lastTimestamp; + // The smoothed rate which tokens are being retrieved. + double m_measuredTxRate = 0.0; + // The last half second time bucket used. + double m_lastTxRateBucket = 0.0; + // The number of requests seen within the current time bucket. + size_t m_requestCount = 0; + // Boolean indicating if the token bucket is enabled. + bool m_enabled = false; + // The maximum rate when the client was last throttled. + double m_lastMaxRate = 0.0; + // The last time when the client was throttled. + Aws::Utils::DateTime m_lastThrottleTime; + + // TokenBucket's mutex to synchronize read/write operations + std::recursive_mutex m_mutex; +}; + +/** + * A retry strategy that builds on the standard strategy and introduces congestion control through + * client side rate limiting. + */ +class AWS_CORE_API AdaptiveRetryStrategy : public StandardRetryStrategy +{ +public: + /** + * C-tors + */ + AdaptiveRetryStrategy(long maxAttempts = 3); + AdaptiveRetryStrategy(std::shared_ptr<RetryQuotaContainer> retryQuotaContainer, long maxAttempts = 3); + + /** + * Retrieve and consume a send token. + * Returns true if send token is available. + * + * If there is not sufficient capacity, HasSendToken() will either sleep a certain amount of time until the rate + * limiter can retrieve a token from its token bucket or return false indicating there is insufficient capacity. + */ + virtual bool HasSendToken() override; + + /** + * Update status, like the information of retry quota when receiving a response. + */ + virtual void RequestBookkeeping(const HttpResponseOutcome& httpResponseOutcome) override; + virtual void RequestBookkeeping(const HttpResponseOutcome& httpResponseOutcome, const AWSError<CoreErrors>& lastError) override; + +protected: + RetryTokenBucket m_retryTokenBucket; + bool m_fastFail = false; + +private: + /** + * An internal helper function to check if a given service response is classified as a throttled one. + */ + static bool IsThrottlingResponse(const HttpResponseOutcome& httpResponseOutcome); +}; + +} // namespace Client +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AsyncCallerContext.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AsyncCallerContext.h index 6831791ffca..03ebca5151a 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AsyncCallerContext.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AsyncCallerContext.h @@ -33,11 +33,11 @@ namespace Aws * Initializes object with UUID */ AsyncCallerContext(const char* uuid) : m_uuid(uuid) {} - + virtual ~AsyncCallerContext() {} /** - * Gets underlying UUID + * Gets underlying UUID */ inline const Aws::String& GetUUID() const { return m_uuid; } @@ -56,4 +56,3 @@ namespace Aws }; } } - diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/ClientConfiguration.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/ClientConfiguration.h index 69c2166a6e1..b8e32b5fe4e 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/ClientConfiguration.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/ClientConfiguration.h @@ -11,6 +11,7 @@ #include <aws/core/utils/memory/stl/AWSString.h> #include <aws/core/http/HttpTypes.h> #include <aws/core/utils/Array.h> +#include <aws/crt/Optional.h> #include <memory> namespace Aws @@ -45,6 +46,20 @@ namespace Aws }; /** + * This setting is an enumeration, not a boolean, to allow for future expansion. + */ + enum class UseRequestCompression + { + DISABLE, + ENABLE, + }; + + struct RequestCompressionConfig { + UseRequestCompression useRequestCompression=UseRequestCompression::ENABLE; + size_t requestMinCompressionSizeBytes = 10240; + }; + + /** * This mutable structure is used to configure any of the AWS clients. * Default values can only be overwritten prior to passing to the client constructors. */ @@ -55,8 +70,18 @@ namespace Aws /** * Create a configuration based on settings in the aws configuration file for the given profile name. * The configuration file location can be set via the environment variable AWS_CONFIG_FILE + * @param profileName the aws profile name. + * @param shouldDisableIMDS whether or not to disable IMDS calls. */ - ClientConfiguration(const char* profileName); + ClientConfiguration(const char* profileName, bool shouldDisableIMDS = false); + + /** + * Create a configuration with a predefined smart defaults + * @param useSmartDefaults, required to differentiate c-tors + * @param defaultMode, default mode to use + * @param shouldDisableIMDS whether or not to disable IMDS calls. + */ + explicit ClientConfiguration(bool useSmartDefaults, const char* defaultMode = "legacy", bool shouldDisableIMDS = false); /** * User Agent string user for http calls. This is filled in for you in the constructor. Don't override this unless you have a really good reason. @@ -73,47 +98,53 @@ namespace Aws /** * Use dual stack endpoint in the endpoint calculation. It is your responsibility to verify that the service supports ipv6 in the region you select. */ - bool useDualStack; + bool useDualStack = false; + + /** + * Use FIPS endpoint in the endpoint calculation. Please check first that the service supports FIPS in a selected region. + */ + bool useFIPS = false; + /** * Max concurrent tcp connections for a single http client to use. Default 25. */ - unsigned maxConnections; + unsigned maxConnections = 25; /** * This is currently only applicable for Curl to set the http request level timeout, including possible dns lookup time, connection establish time, ssl handshake time and actual data transmission time. * the corresponding Curl option is CURLOPT_TIMEOUT_MS * defaults to 0, no http request level timeout. */ - long httpRequestTimeoutMs; + long httpRequestTimeoutMs = 0; /** - * Socket read timeouts for HTTP clients on Windows. Default 3000 ms. This should be more than adequate for most services. However, if you are transfering large amounts of data + * Socket read timeouts for HTTP clients on Windows. Default 3000 ms. This should be more than adequate for most services. However, if you are transferring large amounts of data * or are worried about higher latencies, you should set to something that makes more sense for your use case. * For Curl, it's the low speed time, which contains the time in number milliseconds that transfer speed should be below "lowSpeedLimit" for the library to consider it too slow and abort. * Note that for Curl this config is converted to seconds by rounding down to the nearest whole second except when the value is greater than 0 and less than 1000. In this case it is set to one second. When it's 0, low speed limit check will be disabled. * Note that for Windows when this config is 0, the behavior is not specified by Windows. */ - long requestTimeoutMs; + long requestTimeoutMs = 0; /** - * Socket connect timeout. Default 1000 ms. Unless you are very far away from your the data center you are talking to. 1000ms is more than sufficient. + * Socket connect timeout. Default 1000 ms. Unless you are very far away from your the data center you are talking to, 1000ms is more than sufficient. */ - long connectTimeoutMs; + long connectTimeoutMs = 1000; /** * Enable TCP keep-alive. Default true; * No-op for WinHTTP, WinINet and IXMLHTTPRequest2 client. */ - bool enableTcpKeepAlive; + bool enableTcpKeepAlive = true; /** * Interval to send a keep-alive packet over the connection. Default 30 seconds. Minimum 15 seconds. * WinHTTP & libcurl support this option. Note that for Curl, this value will be rounded to an integer with second granularity. * No-op for WinINet and IXMLHTTPRequest2 client. */ - unsigned long tcpKeepAliveIntervalMs; + unsigned long tcpKeepAliveIntervalMs = 30000; /** * Average transfer speed in bytes per second that the transfer should be below during the request timeout interval for it to be considered too slow and abort. * Default 1 byte/second. Only for CURL client currently. */ - unsigned long lowSpeedLimit; + unsigned long lowSpeedLimit = 1; /** - * Strategy to use in case of failed requests. Default is DefaultRetryStrategy (e.g. exponential backoff) + * Strategy to use in case of failed requests. Default is DefaultRetryStrategy (i.e. exponential backoff) */ std::shared_ptr<RetryStrategy> retryStrategy; /** @@ -131,7 +162,7 @@ namespace Aws /** * If you have users going through a proxy, set the port here. */ - unsigned proxyPort; + unsigned proxyPort = 0; /** * If you have users going through a proxy, set the username here. */ @@ -175,9 +206,9 @@ namespace Aws std::shared_ptr<Aws::Utils::Threading::Executor> executor; /** * If you need to test and want to get around TLS validation errors, do that here. - * you probably shouldn't use this flag in a production scenario. + * You probably shouldn't use this flag in a production scenario. */ - bool verifySSL; + bool verifySSL = true; /** * If your Certificate Authority path is different from the default, you can tell * clients that aren't using the default trust store where to find your CA trust store. @@ -226,35 +257,73 @@ namespace Aws * But be careful when Http request has large payload such S3 PutObject. You don't want to spend long time sending a large payload just getting a error response for server. * The default value will be false. */ - bool disableExpectHeader; + bool disableExpectHeader = false; /** * If set to true clock skew will be adjusted after each http attempt, default to true. */ - bool enableClockSkewAdjustment; + bool enableClockSkewAdjustment = true; /** * Enable host prefix injection. * For services whose endpoint is injectable. e.g. servicediscovery, you can modify the http host's prefix so as to add "data-" prefix for DiscoverInstances request. * Default to true, enabled. You can disable it for testing purpose. + * + * Deprecated in API v. 1.10. Please set in service-specific client configuration. */ - bool enableHostPrefixInjection; + bool enableHostPrefixInjection = true; /** * Enable endpoint discovery * For some services to dynamically set up their endpoints for different requests. - * Defaults to false, it's an opt-in feature. - * If disabled, regional or overriden endpoint will be used instead. + * By default, service clients will decide if endpoint discovery is enabled or not. + * If disabled, regional or overridden endpoint will be used instead. * If a request requires endpoint discovery but you disabled it. The request will never succeed. + * A boolean value is either true of false, use Optional here to have an instance does not contain a value, + * such that SDK will decide the default behavior as stated before, if no value specified. + * + * Deprecated in API v. 1.10. Please set in service-specific client configuration. */ - bool enableEndpointDiscovery; + Aws::Crt::Optional<bool> enableEndpointDiscovery; /** - * profileName in config file that will be used by this object to reslove more configurations. + * profileName in config file that will be used by this object to resolve more configurations. */ Aws::String profileName; + /** + * Request compression configuration + * To use this feature, the service needs to provide the support, and the compression + * algorithms needs to be available at SDK build time. + */ + Aws::Client::RequestCompressionConfig requestCompressionConfig; + + /** + * Disable all internal IMDS Calls + */ + bool disableIMDS = false; + + /** + * A helper function to read config value from env variable or aws profile config + */ + static Aws::String LoadConfigFromEnvOrProfile(const Aws::String& envKey, + const Aws::String& profile, + const Aws::String& profileProperty, + const Aws::Vector<Aws::String>& allowedValues, + const Aws::String& defaultValue); }; + /** + * A helper function to initialize a retry strategy. + * Default is DefaultRetryStrategy (i.e. exponential backoff) + */ + std::shared_ptr<RetryStrategy> InitRetryStrategy(Aws::String retryMode = ""); + + /** + * A helper function to compute a user agent + * @return Aws::String with a user-agent + */ + AWS_CORE_API Aws::String ComputeUserAgentString(); + } // namespace Client } // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/CoreErrors.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/CoreErrors.h index 52ebe51c82f..08803b50163 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/CoreErrors.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/CoreErrors.h @@ -4,7 +4,8 @@ */ #pragma once -#include "aws/core/Core_EXPORTS.h" +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> namespace Aws { @@ -51,9 +52,16 @@ namespace Aws UNKNOWN = 100, // Unknown to the SDK CLIENT_SIGNING_FAILURE = 101, // Client failed to sign the request USER_CANCELLED = 102, // User cancelled the request - SERVICE_EXTENSION_START_RANGE = 128 + ENDPOINT_RESOLUTION_FAILURE = 103, + SERVICE_EXTENSION_START_RANGE = 128, + OK = -1 // No error set }; + /** + * Overload ostream operator<< for CoreErrors enum class for a prettier output such as "128" + */ + AWS_CORE_API Aws::OStream& operator<< (Aws::OStream& oStream, CoreErrors code); + namespace CoreErrorsMapper { /** diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/GenericClientConfiguration.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/GenericClientConfiguration.h new file mode 100644 index 00000000000..81dda32db98 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/GenericClientConfiguration.h @@ -0,0 +1,86 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/client/ClientConfiguration.h> + +namespace Aws +{ + namespace Client + { + /** + * This mutable structure is used to configure a regular AWS client. + */ + template<bool HasEndpointDiscovery = false> + struct AWS_CORE_API GenericClientConfiguration : public ClientConfiguration + { + static const bool EndpointDiscoverySupported = HasEndpointDiscovery; + + GenericClientConfiguration() + : ClientConfiguration() + {} + + /** + * Create a configuration based on settings in the aws configuration file for the given profile name. + * The configuration file location can be set via the environment variable AWS_CONFIG_FILE + * @param profileName the aws profile name. + * @param shouldDisableIMDS whether or not to disable IMDS calls. + */ + GenericClientConfiguration(const char* inputProfileName, bool shouldDisableIMDS = false) + : ClientConfiguration(inputProfileName, shouldDisableIMDS) + {} + + /** + * Create a configuration with a predefined smart defaults + * @param useSmartDefaults, required to differentiate c-tors + * @param defaultMode, default mode to use + * @param shouldDisableIMDS whether or not to disable IMDS calls. + */ + explicit GenericClientConfiguration(bool useSmartDefaults, const char* defaultMode = "legacy", bool shouldDisableIMDS = false) + : ClientConfiguration(useSmartDefaults, defaultMode, shouldDisableIMDS) + {} + + GenericClientConfiguration(const ClientConfiguration& config) + : ClientConfiguration(config) + {} + }; + + /** + * This mutable structure is used to configure a regular AWS client that supports endpoint discovery. + */ + template <> struct AWS_CORE_API GenericClientConfiguration<true> : public ClientConfiguration + { + static const bool EndpointDiscoverySupported = true; + + GenericClientConfiguration(); + GenericClientConfiguration(const char* profileName, bool shouldDisableIMDS = false); + explicit GenericClientConfiguration(bool useSmartDefaults, const char* defaultMode = "legacy", bool shouldDisableIMDS = false); + GenericClientConfiguration(const ClientConfiguration& config); + GenericClientConfiguration(const GenericClientConfiguration&); + GenericClientConfiguration& operator=(const GenericClientConfiguration&); + + + /** + * Enable host prefix injection. + * For services whose endpoint is injectable. e.g. servicediscovery, you can modify the http host's prefix so as to add "data-" prefix for DiscoverInstances request. + * Default to true, enabled. You can disable it for testing purpose. + */ + bool& enableHostPrefixInjection; + + /** + * Enable endpoint discovery + * For some services to dynamically set up their endpoints for different requests. + * By default, service clients will decide if endpoint discovery is enabled or not. + * If disabled, regional or overridden endpoint will be used instead. + * If a request requires endpoint discovery but you disabled it. The request will never succeed. + * A boolean value is either true of false, use Optional here to have an instance does not contain a value, + * such that SDK will decide the default behavior as stated before, if no value specified. + */ + Aws::Crt::Optional<bool>& enableEndpointDiscovery; + }; + } // namespace Client +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/RequestCompression.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/RequestCompression.h new file mode 100644 index 00000000000..31c0bc98cc6 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/RequestCompression.h @@ -0,0 +1,66 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/client/ClientConfiguration.h> +#include <aws/core/utils/Outcome.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/memory/stl/AWSVector.h> + +using iostream_outcome = + Aws::Utils::Outcome<std::shared_ptr<Aws::IOStream>, bool>; + +namespace Aws { +namespace Client { +enum class CompressionAlgorithm { NONE, GZIP }; + +/** + * Converts a compression Algorithms enum to String to be used as content-type + * header value when compressing a request. + * @param algorithm + * @return string with HTTP content type algorithm id + */ +Aws::String AWS_CORE_API +GetCompressionAlgorithmId(const CompressionAlgorithm &algorithm); + +/** + * Request compression API + */ +class AWS_CORE_API RequestCompression final { +public: + /** + * Select the best matching algorithm based in proposed ones, config, length + * of content and the available algorithms. + * @param proposedAlgorithms + * @param config + * @param payloadLength + * @return selected compression algorithm + */ + CompressionAlgorithm + selectAlgorithm(const Aws::Vector<CompressionAlgorithm> &proposedAlgorithms, + const Aws::Client::RequestCompressionConfig &config, + const size_t payloadLength); + /** + * Compress a IOStream input using the requested algorithm. + * @param input + * @param algorithm + * @return IOStream compressed + */ + iostream_outcome compress(std::shared_ptr<Aws::IOStream> input, + const CompressionAlgorithm &algorithm) const; + /** + * Uncompress a IOStream input using the requested algorithm. + * @param input + * @param algorithm + * @return + */ + iostream_outcome uncompress(std::shared_ptr<Aws::IOStream> input, + const CompressionAlgorithm &algorithm) const; +}; +} // namespace Client +} // namespace Aws
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/RetryStrategy.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/RetryStrategy.h index 930eaa581d6..a0b5ea8131b 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/RetryStrategy.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/RetryStrategy.h @@ -24,6 +24,8 @@ namespace Aws namespace Client { + static const int NO_RETRY_INCREMENT = 1; + enum class CoreErrors; template<typename ERROR_TYPE> class AWSError; @@ -54,11 +56,20 @@ namespace Aws virtual long GetMaxAttempts() const { return 0; } /** - * Retrives send tokens from the bucket. + * Retrieves send tokens from the bucket. Throws an exception if not available. */ virtual void GetSendToken() {} /** + * Retrieves send tokens from the bucket. Returns true is send token is retrieved. + */ + virtual bool HasSendToken() + { + GetSendToken(); // first call old method for backward compatibility + return true; + } + + /** * Update status, like the information of retry quota when receiving a response. */ virtual void RequestBookkeeping(const HttpResponseOutcome& /* httpResponseOutcome */) {} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/AWSConfigFileProfileConfigLoader.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/AWSConfigFileProfileConfigLoader.h new file mode 100644 index 00000000000..cc778241b69 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/AWSConfigFileProfileConfigLoader.h @@ -0,0 +1,51 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/config/AWSProfileConfigLoaderBase.h> + +#include <aws/core/utils/memory/stl/AWSString.h> + +namespace Aws +{ + namespace Config + { + /** + * Reads configuration from a config file (e.g. $HOME/.aws/config or $HOME/.aws/credentials + */ + class AWS_CORE_API AWSConfigFileProfileConfigLoader : public AWSProfileConfigLoader + { + public: + /** + * fileName - file to load config from + * useProfilePrefix - whether or not the profiles are prefixed with "profile", credentials file is not + * while the config file is. Defaults to off. + */ + AWSConfigFileProfileConfigLoader(const Aws::String& fileName, bool useProfilePrefix = false); + + virtual ~AWSConfigFileProfileConfigLoader() = default; + + /** + * File path being used for the config loader. + */ + const Aws::String& GetFileName() const { return m_fileName; } + + /** + * Give loader the ability to change the file path to load config from. + * This can avoid creating new loader object if the file changed. + */ + void SetFileName(const Aws::String& fileName) { m_fileName = fileName; } + + protected: + virtual bool LoadInternal() override; + virtual bool PersistInternal(const Aws::Map<Aws::String, Aws::Config::Profile>&) override; + + private: + Aws::String m_fileName; + bool m_useProfilePrefix; + }; + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/AWSProfileConfig.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/AWSProfileConfig.h new file mode 100644 index 00000000000..4f08231d9cc --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/AWSProfileConfig.h @@ -0,0 +1,120 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/memory/stl/AWSMap.h> +#include <aws/core/auth/AWSCredentials.h> + +namespace Aws +{ + namespace Config + { + /** + * Simple data container for a Profile. + */ + class Profile + { + public: + /* + * Data container for a sso-session config entry. + * This is independent of the general profile configuration and used by a bearer auth token provider. + */ + class SsoSession + { + public: + inline const Aws::String& GetName() const { return m_name; } + inline void SetName(const Aws::String& value) { m_name = value; } + inline const Aws::String& GetSsoRegion() const { return m_ssoRegion; } + inline void SetSsoRegion(const Aws::String& value) { m_ssoRegion = value; } + inline const Aws::String& GetSsoStartUrl() const { return m_ssoStartUrl; } + inline void SetSsoStartUrl(const Aws::String& value) { m_ssoStartUrl = value; } + + inline void SetAllKeyValPairs(const Aws::Map<Aws::String, Aws::String>& map) { m_allKeyValPairs = map; } + inline const Aws::String GetValue(const Aws::String& key) const + { + auto iter = m_allKeyValPairs.find(key); + if (iter == m_allKeyValPairs.end()) return {}; + return iter->second; + } + + bool operator==(SsoSession const& other) const + { + return this->m_name == other.m_name && + this->m_ssoRegion == other.m_ssoRegion && + this->m_ssoStartUrl == other.m_ssoStartUrl && + this->m_allKeyValPairs == other.m_allKeyValPairs; + } + bool operator!=(SsoSession const& other) const + { + return !operator==(other); + } + private: + // This is independent of the general configuration + Aws::String m_name; + Aws::String m_ssoRegion; + Aws::String m_ssoStartUrl; + Aws::Map<Aws::String, Aws::String> m_allKeyValPairs; + }; + + inline const Aws::String& GetName() const { return m_name; } + inline void SetName(const Aws::String& value) { m_name = value; } + inline const Aws::Auth::AWSCredentials& GetCredentials() const { return m_credentials; } + inline void SetCredentials(const Aws::Auth::AWSCredentials& value) { m_credentials = value; } + inline const Aws::String& GetRegion() const { return m_region; } + inline void SetRegion(const Aws::String& value) { m_region = value; } + inline const Aws::String& GetRoleArn() const { return m_roleArn; } + inline void SetRoleArn(const Aws::String& value) { m_roleArn = value; } + inline const Aws::String& GetExternalId() const { return m_externalId; } + inline void SetExternalId(const Aws::String& value) { m_externalId = value; } + inline const Aws::String& GetSsoStartUrl() const { return m_ssoStartUrl; } + inline void SetSsoStartUrl(const Aws::String& value) { m_ssoStartUrl = value; } + inline const Aws::String& GetSsoRegion() const { return m_ssoRegion; } + inline void SetSsoRegion(const Aws::String& value) { m_ssoRegion = value; } + inline const Aws::String& GetSsoAccountId() const { return m_ssoAccountId; } + inline void SetSsoAccountId(const Aws::String& value) { m_ssoAccountId = value; } + inline const Aws::String& GetSsoRoleName() const { return m_ssoRoleName; } + inline void SetSsoRoleName(const Aws::String& value) { m_ssoRoleName = value; } + inline const Aws::String& GetDefaultsMode() const { return m_defaultsMode; } + inline void SetDefaultsMode(const Aws::String& value) { m_defaultsMode = value; } + inline const Aws::String& GetSourceProfile() const { return m_sourceProfile; } + inline void SetSourceProfile(const Aws::String& value ) { m_sourceProfile = value; } + inline const Aws::String& GetCredentialProcess() const { return m_credentialProcess; } + inline void SetCredentialProcess(const Aws::String& value ) { m_credentialProcess = value; } + inline void SetAllKeyValPairs(const Aws::Map<Aws::String, Aws::String>& map) { m_allKeyValPairs = map; } + inline void SetAllKeyValPairs(Aws::Map<Aws::String, Aws::String>&& map) { m_allKeyValPairs = std::move(map); } + inline const Aws::String GetValue(const Aws::String& key) const + { + auto iter = m_allKeyValPairs.find(key); + if (iter == m_allKeyValPairs.end()) return {}; + return iter->second; + } + + inline bool IsSsoSessionSet() const { return m_ssoSessionSet; } + inline const SsoSession& GetSsoSession() const { return m_ssoSession; } + inline void SetSsoSession(const SsoSession& value) { m_ssoSessionSet = true; m_ssoSession = value; } + inline void SetSsoSession(SsoSession&& value) { m_ssoSessionSet = true; m_ssoSession = std::move(value); } + + private: + Aws::String m_name; + Aws::String m_region; + Aws::Auth::AWSCredentials m_credentials; + Aws::String m_roleArn; + Aws::String m_externalId; + Aws::String m_sourceProfile; + Aws::String m_credentialProcess; + Aws::String m_ssoStartUrl; + Aws::String m_ssoRegion; + Aws::String m_ssoAccountId; + Aws::String m_ssoRoleName; + Aws::String m_defaultsMode; + Aws::Map<Aws::String, Aws::String> m_allKeyValPairs; + + bool m_ssoSessionSet = false; + SsoSession m_ssoSession; + }; + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/AWSProfileConfigLoader.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/AWSProfileConfigLoader.h index ee467c56409..b9b4bd9e301 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/AWSProfileConfigLoader.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/AWSProfileConfigLoader.h @@ -1,261 +1,14 @@ -/** +/**AWSProfileConfigLoaderBaseAWSProfileConfigLoader * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ #pragma once -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/memory/stl/AWSMap.h> -#include <aws/core/auth/AWSCredentials.h> -#include <aws/core/utils/DateTime.h> -#include <aws/core/utils/threading/ReaderWriterLock.h> +#include <aws/core/config/AWSProfileConfig.h> +#include <aws/core/config/AWSProfileConfigLoaderBase.h> +#include <aws/core/config/AWSConfigFileProfileConfigLoader.h> +#include <aws/core/config/EC2InstanceProfileConfigLoader.h> +#include <aws/core/config/ConfigAndCredentialsCacheManager.h> -namespace Aws -{ - namespace Internal - { - class EC2MetadataClient; - } - - namespace Config - { - /** - * Simple data container for a Profile. - */ - class Profile - { - public: - inline const Aws::String& GetName() const { return m_name; } - inline void SetName(const Aws::String& value) { m_name = value; } - inline const Aws::Auth::AWSCredentials& GetCredentials() const { return m_credentials; } - inline void SetCredentials(const Aws::Auth::AWSCredentials& value) { m_credentials = value; } - inline const Aws::String& GetRegion() const { return m_region; } - inline void SetRegion(const Aws::String& value) { m_region = value; } - inline const Aws::String& GetRoleArn() const { return m_roleArn; } - inline void SetRoleArn(const Aws::String& value) { m_roleArn = value; } - inline const Aws::String& GetExternalId() const { return m_externalId; } - inline void SetExternalId(const Aws::String& value) { m_externalId = value; } - inline const Aws::String& GetSsoStartUrl() const { return m_ssoStartUrl; } - inline void SetSsoStartUrl(const Aws::String& value) { m_ssoStartUrl = value; } - inline const Aws::String& GetSsoRegion() const { return m_ssoRegion; } - inline void SetSsoRegion(const Aws::String& value) { m_ssoRegion = value; } - inline const Aws::String& GetSsoAccountId() const { return m_ssoAccountId; } - inline void SetSsoAccountId(const Aws::String& value) { m_ssoAccountId = value; } - inline const Aws::String& GetSsoRoleName() const { return m_ssoRoleName; } - inline void SetSsoRoleName(const Aws::String& value) { m_ssoRoleName = value; } - inline const Aws::String& GetSourceProfile() const { return m_sourceProfile; } - inline void SetSourceProfile(const Aws::String& value ) { m_sourceProfile = value; } - inline const Aws::String& GetCredentialProcess() const { return m_credentialProcess; } - inline void SetCredentialProcess(const Aws::String& value ) { m_credentialProcess = value; } - inline void SetAllKeyValPairs(const Aws::Map<Aws::String, Aws::String>& map) { m_allKeyValPairs = map; } - inline const Aws::String GetValue(const Aws::String& key) const - { - auto iter = m_allKeyValPairs.find(key); - if (iter == m_allKeyValPairs.end()) return {}; - return iter->second; - } - - private: - Aws::String m_name; - Aws::String m_region; - Aws::Auth::AWSCredentials m_credentials; - Aws::String m_roleArn; - Aws::String m_externalId; - Aws::String m_sourceProfile; - Aws::String m_credentialProcess; - Aws::String m_ssoStartUrl; - Aws::String m_ssoRegion; - Aws::String m_ssoAccountId; - Aws::String m_ssoRoleName; - Aws::Map<Aws::String, Aws::String> m_allKeyValPairs; - }; - - /** - * Loads Configuration such as .aws/config, .aws/credentials or ec2 metadata service. - */ - class AWS_CORE_API AWSProfileConfigLoader - { - public: - virtual ~AWSProfileConfigLoader() = default; - - /** - * Load the configuration - */ - bool Load(); - - /** - * Over writes the entire config source with the newly configured profile data. - */ - bool PersistProfiles(const Aws::Map<Aws::String, Aws::Config::Profile>& profiles); - - /** - * Gets all profiles from the configuration file. - */ - inline const Aws::Map<Aws::String, Aws::Config::Profile>& GetProfiles() const { return m_profiles; }; - - /** - * the timestamp from the last time the profile information was loaded from file. - */ - inline const Aws::Utils::DateTime& LastLoadTime() const { return m_lastLoadTime; } - - using ProfilesContainer = Aws::Map<Aws::String, Aws::Config::Profile>; - - protected: - /** - * Subclasses override this method to implement fetching the profiles. - */ - virtual bool LoadInternal() = 0; - - /** - * Subclasses override this method to implement persisting the profiles. Default returns false. - */ - virtual bool PersistInternal(const Aws::Map<Aws::String, Aws::Config::Profile>&) { return false; } - - ProfilesContainer m_profiles; - Aws::Utils::DateTime m_lastLoadTime; - }; - - /** - * Reads configuration from a config file (e.g. $HOME/.aws/config or $HOME/.aws/credentials - */ - class AWS_CORE_API AWSConfigFileProfileConfigLoader : public AWSProfileConfigLoader - { - public: - /** - * fileName - file to load config from - * useProfilePrefix - whether or not the profiles are prefixed with "profile", credentials file is not - * while the config file is. Defaults to off. - */ - AWSConfigFileProfileConfigLoader(const Aws::String& fileName, bool useProfilePrefix = false); - - virtual ~AWSConfigFileProfileConfigLoader() = default; - - /** - * File path being used for the config loader. - */ - const Aws::String& GetFileName() const { return m_fileName; } - - /** - * Give loader the ability to change the file path to load config from. - * This can avoid creating new loader object if the file changed. - */ - void SetFileName(const Aws::String& fileName) { m_fileName = fileName; } - - protected: - virtual bool LoadInternal() override; - virtual bool PersistInternal(const Aws::Map<Aws::String, Aws::Config::Profile>&) override; - - private: - Aws::String m_fileName; - bool m_useProfilePrefix; - }; - - static const char* const INSTANCE_PROFILE_KEY = "InstanceProfile"; - - /** - * Loads configuration from the EC2 Metadata Service - */ - class AWS_CORE_API EC2InstanceProfileConfigLoader : public AWSProfileConfigLoader - { - public: - /** - * If client is nullptr, the default EC2MetadataClient will be created. - */ - EC2InstanceProfileConfigLoader(const std::shared_ptr<Aws::Internal::EC2MetadataClient>& = nullptr); - - virtual ~EC2InstanceProfileConfigLoader() = default; - - protected: - virtual bool LoadInternal() override; - private: - std::shared_ptr<Aws::Internal::EC2MetadataClient> m_ec2metadataClient; - }; - - /** - * Stores the contents of config file and credentials file to avoid multiple file readings. - * At the same time provides the flexibility to reload from file. - */ - class AWS_CORE_API ConfigAndCredentialsCacheManager - { - public: - ConfigAndCredentialsCacheManager(); - - void ReloadConfigFile(); - - void ReloadCredentialsFile(); - - bool HasConfigProfile(const Aws::String& profileName) const; - - /** - * Returns cached config profile with the specified profile name. - * Using copy instead of const reference to avoid reading bad contents due to thread contention. - */ - Aws::Config::Profile GetConfigProfile(const Aws::String& profileName) const; - - /** - * Returns cached config profiles - * Using copy instead of const reference to avoid reading bad contents due to thread contention. - */ - Aws::Map<Aws::String, Aws::Config::Profile> GetConfigProfiles() const; - - /** - * Returns cached config value with the specified profile name and key. - * Using copy instead of const reference to avoid reading bad contents due to thread contention. - */ - Aws::String GetConfig(const Aws::String& profileName, const Aws::String& key) const; - - bool HasCredentialsProfile(const Aws::String& profileName) const; - /** - * Returns cached credentials profile with the specified profile name. - * Using copy instead of const reference to avoid reading bad contents due to thread contention. - */ - Aws::Config::Profile GetCredentialsProfile(const Aws::String& profileName) const; - - /** - * Returns cached credentials profiles. - * Using copy instead of const reference to avoid reading bad contents due to thread contention. - */ - Aws::Map<Aws::String, Aws::Config::Profile> GetCredentialsProfiles() const; - - /** - * Returns cached credentials with the specified profile name. - * Using copy instead of const reference to avoid reading bad contents due to thread contention. - */ - Aws::Auth::AWSCredentials GetCredentials(const Aws::String& profileName) const; - - private: - mutable Aws::Utils::Threading::ReaderWriterLock m_credentialsLock; - Aws::Config::AWSConfigFileProfileConfigLoader m_credentialsFileLoader; - mutable Aws::Utils::Threading::ReaderWriterLock m_configLock; - Aws::Config::AWSConfigFileProfileConfigLoader m_configFileLoader; - }; - - AWS_CORE_API void InitConfigAndCredentialsCacheManager(); - - AWS_CORE_API void CleanupConfigAndCredentialsCacheManager(); - - AWS_CORE_API void ReloadCachedConfigFile(); - - AWS_CORE_API void ReloadCachedCredentialsFile(); - - AWS_CORE_API bool HasCachedConfigProfile(const Aws::String& profileName); - - AWS_CORE_API Aws::Config::Profile GetCachedConfigProfile(const Aws::String& profileName); - - AWS_CORE_API Aws::Map<Aws::String, Aws::Config::Profile> GetCachedConfigProfiles(); - - AWS_CORE_API Aws::String GetCachedConfigValue(const Aws::String& profileName, const Aws::String& key); - - AWS_CORE_API Aws::String GetCachedConfigValue(const Aws::String& key); - - AWS_CORE_API bool HasCachedCredentialsProfile(const Aws::String &profileName); - - AWS_CORE_API Aws::Config::Profile GetCachedCredentialsProfile(const Aws::String& profileName); - - AWS_CORE_API Aws::Auth::AWSCredentials GetCachedCredentials(const Aws::String& profileName); - - AWS_CORE_API Aws::Map<Aws::String, Aws::Config::Profile> GetCachedCredentialsProfiles(); - - } -} +// This is a header that represents old legacy all-in-one header to maintain backward compatibility diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/AWSProfileConfigLoaderBase.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/AWSProfileConfigLoaderBase.h new file mode 100644 index 00000000000..8403f8fed08 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/AWSProfileConfigLoaderBase.h @@ -0,0 +1,71 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/config/AWSProfileConfig.h> + +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/memory/stl/AWSMap.h> +#include <aws/core/auth/AWSCredentials.h> +#include <aws/core/utils/DateTime.h> +#include <aws/core/utils/threading/ReaderWriterLock.h> + +namespace Aws +{ + namespace Config { + /** + * Loads Configuration such as .aws/config, .aws/credentials or ec2 metadata service. + */ + class AWS_CORE_API AWSProfileConfigLoader + { + public: + virtual ~AWSProfileConfigLoader() = default; + + /** + * Load the configuration + */ + bool Load(); + + /** + * Over writes the entire config source with the newly configured profile data. + */ + bool PersistProfiles(const Aws::Map<Aws::String, Aws::Config::Profile> &profiles); + + /** + * Gets all profiles from the configuration file. + */ + inline const Aws::Map<Aws::String, Aws::Config::Profile> &GetProfiles() const { return m_profiles; }; + + /** + * the timestamp from the last time the profile information was loaded from file. + */ + inline const Aws::Utils::DateTime &LastLoadTime() const { return m_lastLoadTime; } + + using ProfilesContainer = Aws::Map<Aws::String, Aws::Config::Profile>; + + // Delete copy c-tor and assignment operator + AWSProfileConfigLoader() = default; + + AWSProfileConfigLoader(const AWSProfileConfigLoader &) = delete; + + const AWSProfileConfigLoader &operator=(AWSProfileConfigLoader &) = delete; + + protected: + /** + * Subclasses override this method to implement fetching the profiles. + */ + virtual bool LoadInternal() = 0; + + /** + * Subclasses override this method to implement persisting the profiles. Default returns false. + */ + virtual bool PersistInternal(const Aws::Map<Aws::String, Aws::Config::Profile> &) { return false; } + + ProfilesContainer m_profiles; + Aws::Utils::DateTime m_lastLoadTime; + }; + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/ConfigAndCredentialsCacheManager.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/ConfigAndCredentialsCacheManager.h new file mode 100644 index 00000000000..12470b4087c --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/ConfigAndCredentialsCacheManager.h @@ -0,0 +1,104 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/config/AWSProfileConfigLoader.h> + +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/memory/stl/AWSMap.h> +#include <aws/core/auth/AWSCredentials.h> +#include <aws/core/utils/threading/ReaderWriterLock.h> + +namespace Aws +{ + namespace Config + { + /** + * Stores the contents of config file and credentials file to avoid multiple file readings. + * At the same time provides the flexibility to reload from file. + */ + class AWS_CORE_API ConfigAndCredentialsCacheManager + { + public: + ConfigAndCredentialsCacheManager(); + + void ReloadConfigFile(); + + void ReloadCredentialsFile(); + + bool HasConfigProfile(const Aws::String& profileName) const; + + /** + * Returns cached config profile with the specified profile name. + * Using copy instead of const reference to avoid reading bad contents due to thread contention. + */ + Aws::Config::Profile GetConfigProfile(const Aws::String& profileName) const; + + /** + * Returns cached config profiles + * Using copy instead of const reference to avoid reading bad contents due to thread contention. + */ + Aws::Map<Aws::String, Aws::Config::Profile> GetConfigProfiles() const; + + /** + * Returns cached config value with the specified profile name and key. + * Using copy instead of const reference to avoid reading bad contents due to thread contention. + */ + Aws::String GetConfig(const Aws::String& profileName, const Aws::String& key) const; + + bool HasCredentialsProfile(const Aws::String& profileName) const; + /** + * Returns cached credentials profile with the specified profile name. + * Using copy instead of const reference to avoid reading bad contents due to thread contention. + */ + Aws::Config::Profile GetCredentialsProfile(const Aws::String& profileName) const; + + /** + * Returns cached credentials profiles. + * Using copy instead of const reference to avoid reading bad contents due to thread contention. + */ + Aws::Map<Aws::String, Aws::Config::Profile> GetCredentialsProfiles() const; + + /** + * Returns cached credentials with the specified profile name. + * Using copy instead of const reference to avoid reading bad contents due to thread contention. + */ + Aws::Auth::AWSCredentials GetCredentials(const Aws::String& profileName) const; + + private: + mutable Aws::Utils::Threading::ReaderWriterLock m_credentialsLock; + Aws::Config::AWSConfigFileProfileConfigLoader m_credentialsFileLoader; + mutable Aws::Utils::Threading::ReaderWriterLock m_configLock; + Aws::Config::AWSConfigFileProfileConfigLoader m_configFileLoader; + }; + + AWS_CORE_API void InitConfigAndCredentialsCacheManager(); + + AWS_CORE_API void CleanupConfigAndCredentialsCacheManager(); + + AWS_CORE_API void ReloadCachedConfigFile(); + + AWS_CORE_API void ReloadCachedCredentialsFile(); + + AWS_CORE_API bool HasCachedConfigProfile(const Aws::String& profileName); + + AWS_CORE_API Aws::Config::Profile GetCachedConfigProfile(const Aws::String& profileName); + + AWS_CORE_API Aws::Map<Aws::String, Aws::Config::Profile> GetCachedConfigProfiles(); + + AWS_CORE_API Aws::String GetCachedConfigValue(const Aws::String& profileName, const Aws::String& key); + + AWS_CORE_API Aws::String GetCachedConfigValue(const Aws::String& key); + + AWS_CORE_API bool HasCachedCredentialsProfile(const Aws::String &profileName); + + AWS_CORE_API Aws::Config::Profile GetCachedCredentialsProfile(const Aws::String& profileName); + + AWS_CORE_API Aws::Auth::AWSCredentials GetCachedCredentials(const Aws::String& profileName); + + AWS_CORE_API Aws::Map<Aws::String, Aws::Config::Profile> GetCachedCredentialsProfiles(); + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/EC2InstanceProfileConfigLoader.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/EC2InstanceProfileConfigLoader.h new file mode 100644 index 00000000000..ae3a743fc3f --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/EC2InstanceProfileConfigLoader.h @@ -0,0 +1,47 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/config/AWSProfileConfigLoaderBase.h> + +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/memory/stl/AWSMap.h> +#include <aws/core/utils/DateTime.h> +#include <aws/core/utils/threading/ReaderWriterLock.h> + +namespace Aws +{ + namespace Internal + { + class EC2MetadataClient; + } + + namespace Config + { + static const char* const INSTANCE_PROFILE_KEY = "InstanceProfile"; + + /** + * Loads configuration from the EC2 Metadata Service + */ + class AWS_CORE_API EC2InstanceProfileConfigLoader : public AWSProfileConfigLoader + { + public: + /** + * If client is nullptr, the default EC2MetadataClient will be created. + */ + EC2InstanceProfileConfigLoader(const std::shared_ptr<Aws::Internal::EC2MetadataClient>& = nullptr); + + virtual ~EC2InstanceProfileConfigLoader() = default; + + protected: + virtual bool LoadInternal() override; + private: + std::shared_ptr<Aws::Internal::EC2MetadataClient> m_ec2metadataClient; + int64_t credentialsValidUntilMillis = 0; + int64_t calculateRetryTime() const; + }; + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/defaults/ClientConfigurationDefaults.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/defaults/ClientConfigurationDefaults.h new file mode 100644 index 00000000000..cbea1ce997f --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/defaults/ClientConfigurationDefaults.h @@ -0,0 +1,124 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +/** + * Please note that this file is autogenerated. + * The backwards compatibility of the default values provided by new client configuration defaults is not guaranteed; + * the values might change over time. + */ + +#pragma once + +#include <aws/core/client/ClientConfiguration.h> + +namespace Aws +{ + namespace Config + { + namespace Defaults + { + /** + * Set default client configuration parameters per provided default mode + * + * @param clientConfig, a ClientConfiguration to update + * @param defaultMode, requested default mode name + * @param hasEc2MetadataRegion, if ec2 metadata region has been already queried + * @param ec2MetadataRegion, a region resolved by EC2 Instance Metadata service + */ + AWS_CORE_API void SetSmartDefaultsConfigurationParameters(Aws::Client::ClientConfiguration& clientConfig, + const Aws::String& defaultMode, + bool hasEc2MetadataRegion, + const Aws::String& ec2MetadataRegion); + + /** + * Resolve the name of an actual mode for a default mode "auto" + * + * The AUTO mode is an experimental mode that builds on the standard mode. The SDK + * will attempt to discover the execution environment to determine the appropriate + * settings automatically. + * + * Note that the auto detection is heuristics-based and does not guarantee 100% + * accuracy. STANDARD mode will be used if the execution environment cannot be + * determined. The auto detection might query EC2 Instance Metadata service, which + * might introduce latency. Therefore we recommend choosing an explicit + * defaults_mode instead if startup latency is critical to your application. + */ + AWS_CORE_API const char* ResolveAutoClientConfiguration(const Aws::Client::ClientConfiguration& clientConfig, + const Aws::String& ec2MetadataRegion); + + /** + * Default mode "legacy" + * + * The LEGACY mode provides default settings that vary per SDK and were used prior + * to establishment of defaults_mode. + */ + AWS_CORE_API void SetLegacyClientConfiguration(Aws::Client::ClientConfiguration& clientConfig); + + /** + * Default mode "standard" + * + * The STANDARD mode provides the latest recommended default values that should be + * safe to run in most scenarios. + * + * Note that the default values vended from this mode might change as best + * practices may evolve. As a result, it is encouraged to perform tests when + * upgrading the SDK. + */ + AWS_CORE_API void SetStandardClientConfiguration(Aws::Client::ClientConfiguration& clientConfig); + + /** + * Default mode "in-region" + * + * The IN_REGION mode builds on the standard mode and includes optimization + * tailored for applications which call AWS services from within the same AWS + * region. + * + * Note that the default values vended from this mode might change as best + * practices may evolve. As a result, it is encouraged to perform tests when + * upgrading the SDK. + */ + AWS_CORE_API void SetInRegionClientConfiguration(Aws::Client::ClientConfiguration& clientConfig); + + /** + * Default mode "cross-region" + * + * The CROSS_REGION mode builds on the standard mode and includes optimization + * tailored for applications which call AWS services in a different region. + * + * Note that the default values vended from this mode might change as best + * practices may evolve. As a result, it is encouraged to perform tests when + * upgrading the SDK. + */ + AWS_CORE_API void SetCrossRegionClientConfiguration(Aws::Client::ClientConfiguration& clientConfig); + + /** + * Default mode "mobile" + * + * The MOBILE mode builds on the standard mode and includes optimization tailored + * for mobile applications. + * + * Note that the default values vended from this mode might change as best + * practices may evolve. As a result, it is encouraged to perform tests when + * upgrading the SDK. + */ + AWS_CORE_API void SetMobileClientConfiguration(Aws::Client::ClientConfiguration& clientConfig); + + /** + * Internal helper function to resolve smart defaults mode if not provided + * + * @param clientConfig, a ClientConfiguration to update + * @param requestedDefaultMode, requested default mode name + * @param configFileDefaultMode, default mode specified in a config file + * @param hasEc2MetadataRegion, if ec2 metadata region has been already queried + * @param ec2MetadataRegion, a region resolved by EC2 Instance Metadata service + */ + AWS_CORE_API Aws::String ResolveDefaultModeName(const Aws::Client::ClientConfiguration& clientConfig, + Aws::String requestedDefaultMode, + const Aws::String& configFileDefaultMode, + bool hasEc2MetadataRegion, + Aws::String ec2MetadataRegion); + } //namespace Defaults + } //namespace Config +} //namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/AWSEndpoint.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/AWSEndpoint.h new file mode 100644 index 00000000000..311ac71426f --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/AWSEndpoint.h @@ -0,0 +1,71 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/memory/stl/AWSMap.h> + +#include <aws/core/endpoint/internal/AWSEndpointAttribute.h> + +namespace Aws +{ + namespace Endpoint + { + /** + * A public type that encapsulates the information about an endpoint + */ + class AWS_CORE_API AWSEndpoint + { + public: + using EndpointAttributes = Internal::Endpoint::EndpointAttributes; + + virtual ~AWSEndpoint() + {}; + + Aws::String GetURL() const; + void SetURL(Aws::String url); + + const Aws::Http::URI& GetURI() const; + void SetURI(Aws::Http::URI uri); + + template<typename T> + inline void AddPathSegment(T&& pathSegment) + { + m_uri.AddPathSegment(std::forward<T>(pathSegment)); + } + + template<typename T> + inline void AddPathSegments(T&& pathSegments) + { + m_uri.AddPathSegments(std::forward<T>(pathSegments)); + } + + using OptionalError = Crt::Optional<Aws::Client::AWSError<Aws::Client::CoreErrors>>; + OptionalError AddPrefixIfMissing(const Aws::String& prefix); + + void SetQueryString(const Aws::String& queryString); + + const Crt::Optional<EndpointAttributes>& GetAttributes() const; + Crt::Optional<EndpointAttributes>& AccessAttributes(); + void SetAttributes(EndpointAttributes&& attributes); + + const Aws::UnorderedMap<Aws::String, Aws::String>& GetHeaders() const; + void SetHeaders(Aws::UnorderedMap<Aws::String, Aws::String> headers); + + protected: + // A URI containing at minimum the scheme and host. May optionally include a port and a path. + Aws::Http::URI m_uri; + + // A grab bag property map of endpoint attributes. The values here are considered unstable. + Crt::Optional<EndpointAttributes> m_attributes; + + // A map of additional headers to be set when calling the endpoint. + // Note: the values in these maps are Lists to support multi-value headers. + Aws::UnorderedMap<Aws::String, Aws::String> m_headers; + }; + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/AWSPartitions.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/AWSPartitions.h new file mode 100644 index 00000000000..fe08b9f4b68 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/AWSPartitions.h @@ -0,0 +1,23 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once +#include <cstddef> +#include <aws/core/Core_EXPORTS.h> + +namespace Aws +{ +namespace Endpoint +{ + struct AWS_CORE_API AWSPartitions + { + public: + static const size_t PartitionsBlobStrLen; + static const size_t PartitionsBlobSize; + + static const char* GetPartitionsBlob(); + }; +} // namespace Endpoint +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/BuiltInParameters.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/BuiltInParameters.h new file mode 100644 index 00000000000..c55dac969fe --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/BuiltInParameters.h @@ -0,0 +1,44 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + + +#pragma once + +#include <aws/core/endpoint/EndpointParameter.h> +#include <aws/core/client/ClientConfiguration.h> +#include <aws/core/client/GenericClientConfiguration.h> +#include <aws/core/utils/memory/stl/AWSVector.h> + +namespace Aws +{ + namespace Endpoint + { + class AWS_CORE_API BuiltInParameters + { + public: + using EndpointParameter = Aws::Endpoint::EndpointParameter; + + BuiltInParameters() = default; + BuiltInParameters(const BuiltInParameters&) = delete; // avoid accidental copy + virtual ~BuiltInParameters(){}; + + virtual void SetFromClientConfiguration(const Client::ClientConfiguration& config); + virtual void SetFromClientConfiguration(const Client::GenericClientConfiguration<false>& config); + virtual void SetFromClientConfiguration(const Client::GenericClientConfiguration<true>& config); + + virtual void OverrideEndpoint(const Aws::String& endpoint, const Aws::Http::Scheme& scheme = Aws::Http::Scheme::HTTPS); + + const EndpointParameter& GetParameter(const Aws::String& name) const; + void SetParameter(EndpointParameter param); + void SetStringParameter(Aws::String name, Aws::String value); + void SetBooleanParameter(Aws::String name, bool value); + + const Aws::Vector<EndpointParameter>& GetAllParameters() const; + + protected: + Aws::Vector<EndpointParameter> m_params; + }; + } // namespace Endpoint +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/ClientContextParameters.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/ClientContextParameters.h new file mode 100644 index 00000000000..e39eeed2e6e --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/ClientContextParameters.h @@ -0,0 +1,37 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + + +#pragma once + +#include <aws/core/endpoint/EndpointParameter.h> +#include <aws/core/utils/memory/stl/AWSVector.h> + +namespace Aws +{ + namespace Endpoint + { + class AWS_CORE_API ClientContextParameters + { + public: + using EndpointParameter = Aws::Endpoint::EndpointParameter; + + ClientContextParameters() = default; + // avoid accidental copy from endpointProvider::AccessClientContextParameters() + ClientContextParameters(const ClientContextParameters&) = delete; + + virtual ~ClientContextParameters(){}; + + const EndpointParameter& GetParameter(const Aws::String& name) const; + void SetParameter(EndpointParameter param); + void SetStringParameter(Aws::String name, Aws::String value); + void SetBooleanParameter(Aws::String name, bool value); + + const Aws::Vector<EndpointParameter>& GetAllParameters() const; + protected: + Aws::Vector<EndpointParameter> m_params; + }; + } // namespace Endpoint +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/DefaultEndpointProvider.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/DefaultEndpointProvider.h new file mode 100644 index 00000000000..d4d5cdd941c --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/DefaultEndpointProvider.h @@ -0,0 +1,116 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + + +#pragma once + +#include <aws/core/endpoint/AWSPartitions.h> +#include <aws/core/endpoint/EndpointProviderBase.h> +#include <aws/core/endpoint/EndpointParameter.h> +#include <aws/core/endpoint/ClientContextParameters.h> +#include <aws/core/endpoint/BuiltInParameters.h> +#include <aws/core/utils/memory/stl/AWSArray.h> + +#include <aws/crt/endpoints/RuleEngine.h> + +#include <aws/core/utils/Outcome.h> +#include <aws/core/client/AWSError.h> +#include <aws/core/client/CoreErrors.h> +#include "aws/core/utils/logging/LogMacros.h" + +namespace Aws +{ + namespace Endpoint + { + static const char DEFAULT_ENDPOINT_PROVIDER_TAG[] = "Aws::Endpoint::DefaultEndpointProvider"; + + /** + * Default template implementation for endpoint resolution + * @param ruleEngine + * @param builtInParameters + * @param clientContextParameters + * @param endpointParameters + * @return + */ + AWS_CORE_API ResolveEndpointOutcome + ResolveEndpointDefaultImpl(const Aws::Crt::Endpoints::RuleEngine& ruleEngine, + const EndpointParameters& builtInParameters, + const EndpointParameters& clientContextParameters, + const EndpointParameters& endpointParameters); + + /** + * Default endpoint provider template used in this SDK. + */ + template<typename ClientConfigurationT = Aws::Client::GenericClientConfiguration<false>, + typename BuiltInParametersT = Aws::Endpoint::BuiltInParameters, + typename ClientContextParametersT = Aws::Endpoint::ClientContextParameters> + class AWS_CORE_API DefaultEndpointProvider : public EndpointProviderBase<ClientConfigurationT, BuiltInParametersT, ClientContextParametersT> + { + public: + DefaultEndpointProvider(const char* endpointRulesBlob, const size_t endpointRulesBlobSz) + : m_crtRuleEngine(Aws::Crt::ByteCursorFromArray((const uint8_t*) endpointRulesBlob, endpointRulesBlobSz), + Aws::Crt::ByteCursorFromArray((const uint8_t*) AWSPartitions::GetPartitionsBlob(), AWSPartitions::PartitionsBlobSize)) + { + if(!m_crtRuleEngine) { + AWS_LOGSTREAM_FATAL(DEFAULT_ENDPOINT_PROVIDER_TAG, "Invalid CRT Rule Engine state"); + } + } + + virtual ~DefaultEndpointProvider() + { + } + + void InitBuiltInParameters(const ClientConfigurationT& config) override + { + m_builtInParameters.SetFromClientConfiguration(config); + } + + /** + * Default implementation of the ResolveEndpoint + */ + ResolveEndpointOutcome ResolveEndpoint(const EndpointParameters& endpointParameters) const override + { + auto ResolveEndpointDefaultImpl = Aws::Endpoint::ResolveEndpointDefaultImpl; + return ResolveEndpointDefaultImpl(m_crtRuleEngine, m_builtInParameters.GetAllParameters(), m_clientContextParameters.GetAllParameters(), endpointParameters); + }; + + const ClientContextParametersT& GetClientContextParameters() const override + { + return m_clientContextParameters; + } + ClientContextParametersT& AccessClientContextParameters() override + { + return m_clientContextParameters; + } + + const BuiltInParametersT& GetBuiltInParameters() const + { + return m_builtInParameters; + } + BuiltInParametersT& AccessBuiltInParameters() + { + return m_builtInParameters; + } + + void OverrideEndpoint(const Aws::String& endpoint) override + { + m_builtInParameters.OverrideEndpoint(endpoint); + } + + protected: + /* Crt RuleEngine evaluator built using the service's Rule engine */ + Aws::Crt::Endpoints::RuleEngine m_crtRuleEngine; + + /* Also known as a configurable parameters defined by the AWS Service in their c2j/smithy model definition */ + ClientContextParametersT m_clientContextParameters; + + /* Also known as parameters on the ClientConfiguration in this SDK */ + BuiltInParametersT m_builtInParameters; + }; + + // Export symbol from the DLL: + template class AWS_CORE_API DefaultEndpointProvider<Aws::Client::GenericClientConfiguration</*HasEndpointDiscovery*/ true> >; + } // namespace Endpoint +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/EndpointParameter.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/EndpointParameter.h new file mode 100644 index 00000000000..85911eb94a3 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/EndpointParameter.h @@ -0,0 +1,139 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + + +#pragma once + +#include <aws/core/client/AWSError.h> +#include <aws/core/utils/memory/stl/AWSVector.h> + +namespace Aws +{ + namespace Endpoint + { + class AWS_CORE_API EndpointParameter + { + public: + enum class ParameterType + { + BOOLEAN, + STRING + }; + enum class ParameterOrigin + { + STATIC_CONTEXT, + OPERATION_CONTEXT, + CLIENT_CONTEXT, + BUILT_IN, + NOT_SET = -1 + }; + + EndpointParameter(Aws::String name, bool initialValue, ParameterOrigin parameterOrigin = ParameterOrigin::NOT_SET) + : m_storedType(ParameterType::BOOLEAN), + m_parameterOrigin(parameterOrigin), + m_name(std::move(name)), + m_boolValue(initialValue) + {} + + EndpointParameter(Aws::String name, Aws::String initialValue, ParameterOrigin parameterOrigin = ParameterOrigin::NOT_SET) + : m_storedType(ParameterType::STRING), + m_parameterOrigin(parameterOrigin), + m_name(std::move(name)), + m_stringValue(std::move(initialValue)) + {} + + EndpointParameter(Aws::String name, const char* initialValue, ParameterOrigin parameterOrigin = ParameterOrigin::NOT_SET) + : m_storedType(ParameterType::STRING), + m_parameterOrigin(parameterOrigin), + m_name(std::move(name)), + m_stringValue(initialValue) + {} + + EndpointParameter(ParameterType storedType, ParameterOrigin parameterOrigin, Aws::String name) + : m_storedType(storedType), + m_parameterOrigin(parameterOrigin), + m_name(std::move(name)) + {} + + EndpointParameter(const EndpointParameter&) = default; + EndpointParameter(EndpointParameter&&) = default; + EndpointParameter& operator=(const EndpointParameter&) = default; + EndpointParameter& operator=(EndpointParameter&&) = default; + + inline ParameterType GetStoredType() const + { + return m_storedType; + } + + inline ParameterOrigin GetParameterOrigin() const + { + return m_parameterOrigin; + } + + inline const Aws::String& GetName() const + { + return m_name; + } + + enum class GetSetResult + { + SUCCESS, + ERROR_WRONG_TYPE + }; + + inline GetSetResult GetBool(bool& ioValue) const + { + if(m_storedType != ParameterType::BOOLEAN) + return GetSetResult::ERROR_WRONG_TYPE; + ioValue = m_boolValue; + return GetSetResult::SUCCESS; + } + + inline GetSetResult GetString(Aws::String& ioValue) const + { + // disabled RTTI... + if(m_storedType != ParameterType::STRING) + return GetSetResult::ERROR_WRONG_TYPE; + ioValue = m_stringValue; + return GetSetResult::SUCCESS; + } + + inline GetSetResult SetBool(bool iValue) + { + if(m_storedType != ParameterType::BOOLEAN) + return GetSetResult::ERROR_WRONG_TYPE; + m_boolValue = iValue; + return GetSetResult::SUCCESS; + } + + inline GetSetResult SetString(Aws::String iValue) + { + if(m_storedType != ParameterType::STRING) + return GetSetResult::ERROR_WRONG_TYPE; + m_stringValue = std::move(iValue); + return GetSetResult::SUCCESS; + } + + bool GetBoolValueNoCheck() const + { + return m_boolValue; + } + const Aws::String& GetStrValueNoCheck() const + { + return m_stringValue; + } + + protected: + ParameterType m_storedType; + ParameterOrigin m_parameterOrigin; + Aws::String m_name; + + bool m_boolValue = false; + Aws::String m_stringValue; + }; + + using EndpointParameters = Aws::Vector<Aws::Endpoint::EndpointParameter>; + } // namespace Endpoint +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/EndpointProviderBase.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/EndpointProviderBase.h new file mode 100644 index 00000000000..29b67626e38 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/EndpointProviderBase.h @@ -0,0 +1,76 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + + +#pragma once + +#include <aws/core/endpoint/AWSEndpoint.h> +#include <aws/core/client/AWSError.h> +#include <aws/core/endpoint/EndpointParameter.h> +#include <aws/core/endpoint/BuiltInParameters.h> +#include <aws/core/endpoint/ClientContextParameters.h> + +namespace Aws +{ + namespace Utils + { + template< typename R, typename E> class Outcome; + } // namespace Utils + namespace Client + { + enum class CoreErrors; + } // namespace CoreErrors + + namespace Endpoint + { + using EndpointParameters = Aws::Vector<EndpointParameter>; + using ResolveEndpointOutcome = Aws::Utils::Outcome<AWSEndpoint, Aws::Client::AWSError<Aws::Client::CoreErrors> >; + + /** + * EndpointProviderBase is an interface definition that resolves the provided + * EndpointParameters to either an Endpoint or an error. + * This Base class represents a min interface required to be implemented to override an endpoint provider. + */ + template<typename ClientConfigurationT = Aws::Client::GenericClientConfiguration<false>, + typename BuiltInParametersT = Aws::Endpoint::BuiltInParameters, + typename ClientContextParametersT = Aws::Endpoint::ClientContextParameters> + class AWS_CORE_API EndpointProviderBase + { + public: + using BuiltInParameters = BuiltInParametersT; + using ClientContextParameters = ClientContextParametersT; + + virtual ~EndpointProviderBase() = default; + + /** + * Initialize client context parameters from a ClientConfiguration + */ + virtual void InitBuiltInParameters(const ClientConfigurationT& config) = 0; + + /** + * Function to override endpoint, i.e. to set built-in parameter "AWS::Endpoint" + */ + virtual void OverrideEndpoint(const Aws::String& endpoint) = 0; + + /** + * Method for write access to Client Context Parameters (i.e. configurable service-specific parameters) + */ + virtual ClientContextParametersT& AccessClientContextParameters() = 0; + + /** + * Method for read-only access to Client Context Parameters (i.e. configurable service-specific parameters) + */ + virtual const ClientContextParametersT& GetClientContextParameters() const = 0; + + /** + * The core of the endpoint provider interface. + */ + virtual ResolveEndpointOutcome ResolveEndpoint(const EndpointParameters& endpointParameters) const = 0; + }; + + // Export symbol from the DLL: + template class AWS_CORE_API EndpointProviderBase<Aws::Client::GenericClientConfiguration</*HasEndpointDiscovery*/ true> >; + } // namespace Endpoint +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/internal/AWSEndpointAttribute.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/internal/AWSEndpointAttribute.h new file mode 100644 index 00000000000..c4dfd07eb3f --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/endpoint/internal/AWSEndpointAttribute.h @@ -0,0 +1,89 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + + +#pragma once + +#include <aws/core/client/AWSError.h> +#include <aws/crt/Optional.h> + +namespace Aws +{ + namespace Internal + { + namespace Endpoint + { + class AWS_CORE_API EndpointAuthScheme + { + public: + virtual ~EndpointAuthScheme(){}; + + inline const Aws::String& GetName() const + { + return m_name; + } + inline void SetName(Aws::String name) + { + m_name = std::move(name); + } + + inline const Crt::Optional<Aws::String>& GetSigningName() const + { + return m_signingName; + } + inline void SetSigningName(Aws::String signingName) + { + m_signingName = std::move(signingName); + } + + inline const Crt::Optional<Aws::String>& GetSigningRegion() const + { + return m_signingRegion; + } + inline void SetSigningRegion(Aws::String signingRegion) + { + m_signingRegion = std::move(signingRegion); + } + + inline const Crt::Optional<Aws::String>& GetSigningRegionSet() const + { + return m_signingRegionSet; + } + inline void SetSigningRegionSet(Aws::String signingRegionSet) + { + m_signingRegionSet = std::move(signingRegionSet); + } + + inline const Crt::Optional<bool>& GetDisableDoubleEncoding() const + { + return m_disableDoubleEncoding; + } + inline void SetDisableDoubleEncoding(bool disableDoubleEncoding) + { + m_disableDoubleEncoding = disableDoubleEncoding; + } + + private: + Aws::String m_name; + + Crt::Optional<Aws::String> m_signingName; + Crt::Optional<Aws::String> m_signingRegion; + Crt::Optional<Aws::String> m_signingRegionSet; + Crt::Optional<bool> m_disableDoubleEncoding; + }; + + /** + * A grab bag property map of endpoint attributes. The values here are considered unstable. + * C++ SDK supports only (and single so far) endpoint attribute "AuthScheme" + */ + struct AWS_CORE_API EndpointAttributes + { + Aws::Internal::Endpoint::EndpointAuthScheme authScheme; + + static EndpointAttributes BuildEndpointAttributesFromJson(const Aws::String& iJsonStr); + }; + } // namespace Endpoint + } // namespace Internal +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/external/cjson/cJSON.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/external/cjson/cJSON.h index 92ccec786c9..a069f3c7729 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/external/cjson/cJSON.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/external/cjson/cJSON.h @@ -183,8 +183,10 @@ CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_GetArrayItem(const cJSON *array, int i CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_GetObjectItem(const cJSON * const object, const char * const string); CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string); CJSON_AS4CPP_PUBLIC(cJSON_AS4CPP_bool) cJSON_AS4CPP_HasObjectItem(const cJSON *object, const char *string); -/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_AS4CPP_Parse() returns 0. 0 when cJSON_AS4CPP_Parse() succeeds. */ +/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_AS4CPP_Parse() returns 0. 0 when cJSON_AS4CPP_Parse() succeeds. + * NOTE: disabled, since this method is not thread-safe. See comments in source/external/cjson/cJSON.cpp. CJSON_AS4CPP_PUBLIC(const char *) cJSON_AS4CPP_GetErrorPtr(void); + */ /* Check item type and return its value */ CJSON_AS4CPP_PUBLIC(char *) cJSON_AS4CPP_GetStringValue(const cJSON * const item); diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpRequest.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpRequest.h index ab71a3a29b4..129bd3bd364 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpRequest.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpRequest.h @@ -18,6 +18,20 @@ namespace Aws { + namespace Crt + { + namespace Http + { + class HttpRequest; + } + } + namespace Utils + { + namespace Crypto + { + class Hash; + } + } namespace Http { extern AWS_CORE_API const char DATE_HEADER[]; @@ -29,8 +43,10 @@ namespace Aws extern AWS_CORE_API const char AUTHORIZATION_HEADER[]; extern AWS_CORE_API const char AWS_AUTHORIZATION_HEADER[]; extern AWS_CORE_API const char COOKIE_HEADER[]; + extern AWS_CORE_API const char DECODED_CONTENT_LENGTH_HEADER[]; extern AWS_CORE_API const char CONTENT_LENGTH_HEADER[]; extern AWS_CORE_API const char CONTENT_TYPE_HEADER[]; + extern AWS_CORE_API const char CONTENT_ENCODING_HEADER[]; extern AWS_CORE_API const char TRANSFER_ENCODING_HEADER[]; extern AWS_CORE_API const char USER_AGENT_HEADER[]; extern AWS_CORE_API const char VIA_HEADER[]; @@ -39,9 +55,13 @@ namespace Aws extern AWS_CORE_API const char X_AMZ_EXPIRES_HEADER[]; extern AWS_CORE_API const char CONTENT_MD5_HEADER[]; extern AWS_CORE_API const char API_VERSION_HEADER[]; + extern AWS_CORE_API const char AWS_TRAILER_HEADER[]; extern AWS_CORE_API const char SDK_INVOCATION_ID_HEADER[]; extern AWS_CORE_API const char SDK_REQUEST_HEADER[]; + extern AWS_CORE_API const char X_AMZN_TRACE_ID_HEADER[]; extern AWS_CORE_API const char CHUNKED_VALUE[]; + extern AWS_CORE_API const char AWS_CHUNKED_VALUE[]; + extern AWS_CORE_API const char X_AMZN_ERROR_TYPE[]; class HttpRequest; class HttpResponse; @@ -107,7 +127,7 @@ namespace Aws */ virtual bool HasHeader(const char* name) const = 0; /** - * Get size in bytes of the request when as it will be going accross the wire. + * Get size in bytes of the request when as it will be going across the wire. */ virtual int64_t GetSize() const = 0; /** @@ -525,6 +545,21 @@ namespace Aws bool IsEventStreamRequest() { return m_isEvenStreamRequest; } void SetEventStreamRequest(bool eventStreamRequest) { m_isEvenStreamRequest = eventStreamRequest; } + + virtual std::shared_ptr<Aws::Crt::Http::HttpRequest> ToCrtHttpRequest(); + + void SetRequestHash(const Aws::String& algorithmName, const std::shared_ptr<Aws::Utils::Crypto::Hash>& hash) + { + m_requestHash = std::make_pair(algorithmName, hash); + } + const std::pair<Aws::String, std::shared_ptr<Aws::Utils::Crypto::Hash>>& GetRequestHash() { return m_requestHash; } + + void AddResponseValidationHash(const Aws::String& algorithmName, const std::shared_ptr<Aws::Utils::Crypto::Hash>& hash) + { + m_responseValidationHashes.emplace_back(algorithmName, hash); + } + const Aws::Vector<std::pair<Aws::String, std::shared_ptr<Aws::Utils::Crypto::Hash>>>& GetResponseValidationHashes() const { return m_responseValidationHashes; } + private: URI m_uri; HttpMethod m_method; @@ -536,6 +571,8 @@ namespace Aws Aws::String m_signingAccessKey; Aws::String m_resolvedRemoteHost; Aws::Monitoring::HttpClientMetricsCollection m_httpRequestMetrics; + std::pair<Aws::String, std::shared_ptr<Aws::Utils::Crypto::Hash>> m_requestHash; + Aws::Vector<std::pair<Aws::String, std::shared_ptr<Aws::Utils::Crypto::Hash>>> m_responseValidationHashes; }; } // namespace Http diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpResponse.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpResponse.h index 1db30d1730a..8082547a717 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpResponse.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpResponse.h @@ -105,6 +105,11 @@ namespace Aws NETWORK_CONNECT_TIMEOUT = 599 }; + /** + * Overload ostream operator<< for HttpResponseCode enum class for a prettier output such as "200" + */ + AWS_CORE_API Aws::OStream& operator<< (Aws::OStream& oStream, HttpResponseCode code); + inline bool IsRetryableHttpResponseCode(HttpResponseCode responseCode) { switch (responseCode) @@ -137,7 +142,8 @@ namespace Aws HttpResponse(const std::shared_ptr<const HttpRequest>& originatingRequest) : m_httpRequest(originatingRequest), m_responseCode(HttpResponseCode::REQUEST_NOT_MADE), - m_hasClientError(false) + m_hasClientError(false), + m_clientErrorType(Aws::Client::CoreErrors::OK) {} virtual ~HttpResponse() = default; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/URI.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/URI.h index d72e96b863f..724c24379f2 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/URI.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/URI.h @@ -9,7 +9,7 @@ #include <aws/core/http/Scheme.h> #include <aws/core/utils/memory/stl/AWSMap.h> -#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/StringUtils.h> #include <stdint.h> @@ -21,6 +21,9 @@ namespace Aws static const uint16_t HTTP_DEFAULT_PORT = 80; static const uint16_t HTTPS_DEFAULT_PORT = 443; + extern bool s_compliantRfc3986Encoding; + AWS_CORE_API void SetCompliantRfc3986Encoding(bool compliant); + //per https://tools.ietf.org/html/rfc3986#section-3.4 there is nothing preventing servers from allowing //multiple values for the same key. So use a multimap instead of a map. typedef Aws::MultiMap<Aws::String, Aws::String> QueryStringParameterCollection; @@ -89,12 +92,17 @@ namespace Aws * Gets the path portion of the uri e.g. the portion after the first slash after the authority and prior to the * query string. This is not url encoded. */ - inline const Aws::String& GetPath() const { return m_path; } + Aws::String GetPath() const; /** * Gets the path portion of the uri, url encodes it and returns it */ - inline Aws::String GetURLEncodedPath() const { return URLEncodePath(m_path); } + Aws::String GetURLEncodedPath() const; + + /** + * Gets the path portion of the uri, url encodes it according to RFC3986 and returns it. + */ + Aws::String GetURLEncodedPathRFC3986() const; /** * Sets the path portion of the uri. URL encodes it if needed @@ -102,6 +110,39 @@ namespace Aws void SetPath(const Aws::String& value); /** + * Add a path segment to the uri. + * Leading slashes and trailing slashes will be removed. + * Use AddPathSegments() to enable trailing slashes. + */ + template<typename T> + inline void AddPathSegment(T pathSegment) + { + Aws::StringStream ss; + ss << pathSegment; + Aws::String segment = ss.str(); + segment.erase(0, segment.find_first_not_of('/')); + segment.erase(segment.find_last_not_of('/') + 1); + m_pathSegments.push_back(segment); + m_pathHasTrailingSlash = false; + } + + /** + * Add path segments to the uri. + */ + template<typename T> + inline void AddPathSegments(T pathSegments) + { + Aws::StringStream ss; + ss << pathSegments; + Aws::String segments = ss.str(); + for (const auto& segment : Aws::Utils::StringUtils::Split(segments, '/')) + { + m_pathSegments.push_back(segment); + } + m_pathHasTrailingSlash = (!segments.empty() && segments.back() == '/'); + } + + /** * Gets the raw query string including the ? */ inline const Aws::String& GetQueryString() const { return m_queryString; } @@ -159,10 +200,11 @@ namespace Aws void ExtractAndSetQueryString(const Aws::String& uri); bool CompareURIParts(const URI& other) const; - Scheme m_scheme; + Scheme m_scheme = Scheme::HTTP; Aws::String m_authority; - uint16_t m_port; - Aws::String m_path; + uint16_t m_port = HTTP_DEFAULT_PORT; + Aws::Vector<Aws::String> m_pathSegments; + bool m_pathHasTrailingSlash = false; Aws::String m_queryString; }; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/curl/CurlHandleContainer.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/curl/CurlHandleContainer.h index c2745753eb8..15cfdbf10ac 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/curl/CurlHandleContainer.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/curl/CurlHandleContainer.h @@ -43,7 +43,7 @@ public: void ReleaseCurlHandle(CURL* handle); /** - * When the handle has bad DNS entries, problematic live connections, we need to destory the handle from pool. + * When the handle has bad DNS entries, problematic live connections, we need to destroy the handle from pool. */ void DestroyCurlHandle(CURL* handle); diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/standard/StandardHttpRequest.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/standard/StandardHttpRequest.h index c9c0016ef52..adf10fd182f 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/standard/StandardHttpRequest.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/standard/StandardHttpRequest.h @@ -63,7 +63,7 @@ namespace Aws */ virtual bool HasHeader(const char*) const override; /** - * Get size in bytes of the request when as it will be going accross the wire. + * Get size in bytes of the request when as it will be going across the wire. */ virtual int64_t GetSize() const override; /** @@ -79,7 +79,6 @@ namespace Aws HeaderValueCollection headerMap; std::shared_ptr<Aws::IOStream> bodyStream; Aws::IOStreamFactory m_responseStreamFactory; - Aws::String m_emptyHeader; }; } // namespace Standard diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/internal/AWSHttpResourceClient.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/internal/AWSHttpResourceClient.h index bc28cd88611..ba03f6f39a4 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/internal/AWSHttpResourceClient.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/internal/AWSHttpResourceClient.h @@ -118,12 +118,13 @@ namespace Aws */ virtual Aws::String GetResource(const char* resourcePath) const; +#if !defined(DISABLE_IMDSV1) /** * Connects to the Amazon EC2 Instance Metadata Service to retrieve the * default credential information (if any). */ virtual Aws::String GetDefaultCredentials() const; - +#endif /** * Connects to the Amazon EC2 Instance Metadata Service to retrieve the * credential information (if any) in a more secure way. @@ -136,8 +137,19 @@ namespace Aws */ virtual Aws::String GetCurrentRegion() const; + /** + * Sets endpoint used to connect to the EC2 Instance metadata Service + */ + virtual void SetEndpoint(const Aws::String& endpoint); + + /** + * Gets endpoint used to connect to the EC2 Instance metadata Service + */ + virtual Aws::String GetEndpoint() const; + private: Aws::String m_endpoint; + bool m_disableIMDS; mutable std::recursive_mutex m_tokenMutex; mutable Aws::String m_token; mutable bool m_tokenRequired; @@ -249,8 +261,31 @@ namespace Aws SSOGetRoleCredentialsResult GetSSOCredentials(const SSOGetRoleCredentialsRequest& request); + struct SSOCreateTokenRequest + { + Aws::String clientId; + Aws::String clientSecret; + Aws::String grantType; + Aws::String refreshToken; + }; + + struct SSOCreateTokenResult + { + Aws::String accessToken; + size_t expiresIn = 0; //seconds + Aws::String idToken; + Aws::String refreshToken; + Aws::String clientId; + Aws::String tokenType; + }; + + SSOCreateTokenResult CreateToken(const SSOCreateTokenRequest& request); private: + Aws::String buildEndpoint(const Aws::Client::ClientConfiguration& clientConfiguration, + const Aws::String& domain, + const Aws::String& endpoint); Aws::String m_endpoint; + Aws::String m_oidcEndpoint; }; } // namespace Internal } // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringInterface.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringInterface.h index ebe50722c79..68a308a092f 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringInterface.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringInterface.h @@ -26,7 +26,7 @@ namespace Aws /** * @brief This function lets you do preparation work when a http attempt(request) starts. It returns a pointer to an implementation defined context which will be * passed down with the other facilities that completes the request's lifetime. This context can be used to track the lifetime of the request and record metrics - * specific to this particular request. You are responsible for deleteing the context during your OnFinish call. + * specific to this particular request. You are responsible for deleting the context during your OnFinish call. * @param serviceName, the service client who initiates this http attempt. like "s3", "ec2", etc. * @param requestName, the operation or API name of this http attempt, like "GetObject" in s3. * @param request, the actual Http Request. diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringManager.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringManager.h index aaa5bca5d1a..87b04fcbbf1 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringManager.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringManager.h @@ -57,7 +57,8 @@ namespace Aws AWS_CORE_API void InitMonitoring(const std::vector<MonitoringFactoryCreateFunction>& monitoringFactoryCreateFunctions); /** - * Clean up monitoring related global variables + * Clean up monitoring related global variables. This should be done first at shutdown, to avoid a race condition in + * testing whether the global Monitoring instance has been destructed. */ AWS_CORE_API void CleanupMonitoring(); } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/net/SimpleUDP.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/net/SimpleUDP.h index 2e96b509fb9..a9f2f4f59ff 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/net/SimpleUDP.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/net/SimpleUDP.h @@ -26,7 +26,7 @@ namespace Aws * @brief Constructor of SimpleUDP * @param addressFamily, AF_INET for IPV4 or AF_INET6 for IPV6 * @param sendBufSize, if nonzero, try set socket's send buffer size to this value. - * @param receieveBufSize, if nonzero, try set socket's receive buffer size to this value. + * @param receiveBufSize, if nonzero, try set socket's receive buffer size to this value. * @param nonBlocking, if it is true, implementation will try to create a non-blocking underlying UDP socket. * Implementation should create and set the underlying udp socket. */ @@ -36,7 +36,7 @@ namespace Aws * @brief An easy constructor of an IPV4 or IPV6 SimpleUDP * @param addressFamily, either AF_INET for IPV4 or AF_INET6 for IPV6 * @param sendBufSize, if nonzero, try set socket's send buffer size to this value. - * @param receieveBufSize, if nonzero, try set socket's receive buffer size to this value. + * @param receiveBufSize, if nonzero, try set socket's receive buffer size to this value. * @param nonBlocking, if it is true, implementation will try to create a non-blocking underlying UDP socket. * Implementation should create and set the underlying udp socket. */ @@ -48,7 +48,7 @@ namespace Aws * Note that "localhost" is not necessarily bind to 127.0.0.1, it could bind to ipv6 address ::1, or other type of ip addresses. If you pass localhost here, we will go through getaddrinfo procedure on Linux and Windows. * @param port, the port number that the host listens on. * @param sendBufSize, if nonzero, try set socket's send buffer size to this value. - * @param receieveBufSize, if nonzero, try set socket's receive buffer size to this value. + * @param receiveBufSize, if nonzero, try set socket's receive buffer size to this value. * @param nonBlocking, if it is true, implementation will try to create a non-blocking underlying UDP socket. * Implementation should create and set the underlying udp socket. */ @@ -131,7 +131,7 @@ namespace Aws /** * @brief Receive data from network. * @param address, if not null and underlying implementation supply the incoming data's source address, this will be filled with source address info. - * @param addressLength, the size of source adddress, should not be null. + * @param addressLength, the size of source address, should not be null. * @param buffer, the memory address where you want to store received data. * @param bufferLen, the size of data buffer. * @return -1 on failure, check errno for detailed error information, on success, returns the actual bytes of data received. diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/DateTime.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/DateTime.h index a4102790116..878fc1ac636 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/DateTime.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/DateTime.h @@ -49,7 +49,7 @@ namespace Aws }; /** - * Wrapper for all the weird crap we need to do with timestamps. + * Wrapper for timestamp functionality. */ class AWS_CORE_API DateTime { @@ -145,6 +145,11 @@ namespace Aws double SecondsWithMSPrecision() const; /** + * Get the seconds without millisecond precision. + */ + int64_t Seconds() const; + + /** * Milliseconds since epoch of this datetime. */ int64_t Millis() const; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/Document.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/Document.h new file mode 100644 index 00000000000..2c062b8ca6c --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/Document.h @@ -0,0 +1,370 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/Array.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/memory/stl/AWSMap.h> +#include <aws/core/external/cjson/cJSON.h> + +#include <utility> + +namespace Aws +{ + namespace Utils + { + namespace Json + { + class JsonValue; + class JsonView; + } + + class DocumentView; + /** + * A Document type represents open content that is serialized using the same format as its surroundings and requires no additional encoding or escaping. + * Document types provide a JSON "view" of data regardless of the underlying protocol. This normalized JSON interface makes document types protocol-agnostic. + * Clients can use the data stored in a document without prior knowledge of the protocol by interacting with the normalized JSON view of the data. + * Document types are only initially supported in JSON protocol, so it's identical to Aws::Utils::Json::JsonValue and Aws::Utils::Json::JsonView at this moment. + */ + class AWS_CORE_API Document + { + public: + /** + * Constructs empty Document. + */ + Document(); + + /** + * Constructs a Document by parsing the input string. + */ + Document(const Aws::String& value); + + /** + * Constructs a Document by parsing the text in the input stream. + */ + Document(Aws::IStream& istream); + + /** + * Performs a deep copy of the Document parameter. + * Prefer using a @ref DocumentView if copying is not needed. + */ + Document(const Document& value); + + /** + * Moves the ownership of the internal Document. + * No copying is performed. + */ + Document(Document&& value); + + /** + * Performs a deep copy of the JsonView parameter. + */ + Document(const Json::JsonView& view); + + ~Document(); + + /** + * Performs a deep copy of the Document parameter. + */ + Document& operator=(const Document& other); + + /** + * Performs a deep copy of the JsonView parameter. + */ + Document& operator=(const Json::JsonView& view); + + /** + * Moves the ownership of the internal Document of the parameter to the current object. + * No copying is performed. + * A Document currently owned by the object will be freed prior to copying. + * @warning This will result in invalidating any outstanding views of the current Document. However, views + * to the moved-from Document would still valid. + */ + Document& operator=(Document&& other); + + bool operator==(const Document& other) const; + bool operator!=(const Document& other) const; + + /** + * Adds a string to the top level of this Document with key. + */ + Document& WithString(const Aws::String& key, const Aws::String& value); + Document& WithString(const char* key, const Aws::String& value); + /** + * Converts the current Document to a string. + */ + Document& AsString(const Aws::String& value); + + /** + * Adds a bool value with key to the top level of this Document. + */ + Document& WithBool(const Aws::String& key, bool value); + Document& WithBool(const char* key, bool value); + /** + * Converts the current Document to a bool. + */ + Document& AsBool(bool value); + + /** + * Adds an integer value at key at the top level of this Document. + */ + Document& WithInteger(const Aws::String& key, int value); + Document& WithInteger(const char* key, int value); + /** + * Converts the current Document to an integer. + */ + Document& AsInteger(int value); + + /** + * Adds a 64-bit integer value at key to the top level of this Document. + */ + Document& WithInt64(const Aws::String& key, long long value); + Document& WithInt64(const char* key, long long value); + /** + * Converts the current Document to a 64-bit integer. + */ + Document& AsInt64(long long value); + + /** + * Adds a double value at key at the top level of this Document. + */ + Document& WithDouble(const Aws::String& key, double value); + Document& WithDouble(const char* key, double value); + /** + * Converts the current Document to a double. + */ + Document& AsDouble(double value); + + /** + * Adds an array of strings to the top level of this Document at key. + */ + Document& WithArray(const Aws::String& key, const Array<Aws::String>& array); + Document& WithArray(const char* key, const Array<Aws::String>& array); + /** + * Adds an array of arbitrary Document objects to the top level of this Document at key. + * The values in the array parameter will be deep-copied. + */ + Document& WithArray(const Aws::String& key, const Array<Document>& array); + /** + * Adds an array of arbitrary Document objects to the top level of this Document at key. + * The values in the array parameter will be moved-from. + */ + Document& WithArray(const Aws::String& key, Array<Document>&& array); + /** + * Converts the current Document to an array whose values are deep-copied from the array parameter. + */ + Document& AsArray(const Array<Document>& array); + /** + * Converts the current Document to an array whose values are moved from the array parameter. + */ + Document& AsArray(Array<Document>&& array); + + /** + * Adds a Document object to the top level of this Document at key. + * The object parameter is deep-copied. + */ + Document& WithObject(const Aws::String& key, const Document& value); + Document& WithObject(const char* key, const Document& value); + /** + * Adds a Document object to the top level of this Document at key. + */ + Document& WithObject(const Aws::String& key, Document&& value); + Document& WithObject(const char* key, Document&& value); + /** + * Converts the current Document to a Document object by deep-copying the parameter. + */ + Document& AsObject(const Document& value); + /** + * Converts the current Document to a Document object by moving from the parameter. + */ + Document& AsObject(Document&& value); + + /** + * Returns true if the last parse request was successful. If this returns false, + * you can call GetErrorMessage() to find the cause. + */ + inline bool WasParseSuccessful() const + { + return m_wasParseSuccessful; + } + + /** + * Returns the last error message from a failed parse attempt. Returns empty string if no error. + */ + inline const Aws::String& GetErrorMessage() const + { + return m_errorMessage; + } + + /** + * Creates a view from the current Document. + */ + DocumentView View() const; + + private: + void Destroy(); + Document(cJSON* value); + cJSON* m_json; + bool m_wasParseSuccessful; + Aws::String m_errorMessage; + friend DocumentView; + }; + + /** + * Provides read-only view to an existing Document. This allows lightweight copying without making deep + * copies of the Document. + * Note: This class does not extend the lifetime of the given Document. It's your responsibility to ensure + * the lifetime of the Document is extended beyond the lifetime of its view. + */ + class AWS_CORE_API DocumentView + { + public: + /* constructors */ + DocumentView(); + DocumentView(const Document& value); + DocumentView& operator=(const Document& value); + + /** + * Gets a string from this Document by its key. + */ + Aws::String GetString(const Aws::String& key) const; + /** + * Returns the value of this Document as a string. + */ + Aws::String AsString() const; + /** + * Tests whether the current value is a string. + */ + bool IsString() const; + + /** + * Gets a boolean value from this Document by its key. + */ + bool GetBool(const Aws::String& key) const; + /** + * Returns the value of this Document as a boolean. + */ + bool AsBool() const; + /** + * Tests whether the current value is a boolean. + */ + bool IsBool() const; + + /** + * Gets an integer value from this Document by its key. + * The integer is of the same size as an int on the machine. + */ + int GetInteger(const Aws::String& key) const; + /** + * Returns the value of this Document as an int. + */ + int AsInteger() const; + /** + * Tests whether the current value is an int or int64_t. + * Returns false if the value is floating-point. + */ + bool IsIntegerType() const; + + /** + * Converts the current Document to a 64-bit integer. + */ + Document& AsInt64(long long value); + /** + * Gets a 64-bit integer value from this Document by its key. + * The value is 64-bit regardless of the platform/machine. + */ + int64_t GetInt64(const Aws::String& key) const; + /** + * Returns the value of this Document as 64-bit integer. + */ + int64_t AsInt64() const; + + /** + * Gets a double precision floating-point value from this Document by its key. + */ + double GetDouble(const Aws::String& key) const; + /** + * Returns the value of this Document as a double precision floating-point. + */ + double AsDouble() const; + /** + * Tests whether the current value is a floating-point. + */ + bool IsFloatingPointType() const; + + /** + * Gets an array of DocumentView objects from this Document by its key. + */ + Array<DocumentView> GetArray(const Aws::String& key) const; + /** + * Returns the value of this Document as an array of DocumentView objects. + */ + Array<DocumentView> AsArray() const; + /** + * Tests whether the current value is a Document array. + */ + bool IsListType() const; + + /** + * Gets a DocumentView object from this Document by its key. + */ + DocumentView GetObject(const Aws::String& key) const; + /** + * Returns the value of this Document as a DocumentView object. + */ + DocumentView AsObject() const; + /** + * Reads all Document objects at the top level of this Document (does not traverse the tree any further) + * along with their keys. + */ + Aws::Map<Aws::String, DocumentView> GetAllObjects() const; + /** + * Tests whether the current value is a Document object. + */ + bool IsObject() const; + + /** + * Tests whether the current value is NULL. + */ + bool IsNull() const; + + /** + * Tests whether a value exists at the current Document level for the given key. + * Returns true if a value has been found and its value is not null, false otherwise. + */ + bool ValueExists(const Aws::String& key) const; + + /** + * Tests whether a key exists at the current Document level. + */ + bool KeyExists(const Aws::String& key) const; + + /** + * Writes the current Document view without whitespace characters starting at the current level to a string. + */ + Aws::String WriteCompact() const; + + /** + * Writes the current Document view to a string in a human friendly format. + */ + Aws::String WriteReadable() const; + + /** + * Creates a deep copy of the JSON value rooted in the current JSON view. + */ + Document Materialize() const; + private: + DocumentView(cJSON* value); + DocumentView& operator=(cJSON* value); + cJSON* m_json; + friend Aws::Utils::Json::JsonValue; + }; + + } // namespace Utils +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/FileSystemUtils.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/FileSystemUtils.h index d62ff4c094a..430e7ae4418 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/FileSystemUtils.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/FileSystemUtils.h @@ -45,7 +45,7 @@ namespace Aws */ TempFile(const char* prefix, std::ios_base::openmode openFlags); /** - * Creates a temporary file with a randome string for the name. + * Creates a temporary file with a random string for the name. */ TempFile(std::ios_base::openmode openFlags); diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/HashingUtils.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/HashingUtils.h index 465c9827b2c..d09fe5c94f7 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/HashingUtils.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/HashingUtils.h @@ -87,6 +87,26 @@ namespace Aws */ static ByteBuffer CalculateMD5(Aws::IOStream& stream); + /** + * Calculates a CRC32 Hash value + */ + static ByteBuffer CalculateCRC32(const Aws::String& str); + + /** + * Calculates a CRC32 Hash value + */ + static ByteBuffer CalculateCRC32(Aws::IOStream& stream); + + /** + * Calculates a CRC32C Hash value + */ + static ByteBuffer CalculateCRC32C(const Aws::String& str); + + /** + * Calculates a CRC32C Hash value + */ + static ByteBuffer CalculateCRC32C(Aws::IOStream& stream); + static int HashString(const char* strToHash); }; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/ResourceManager.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/ResourceManager.h index 517f65d0fa5..c564e586502 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/ResourceManager.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/ResourceManager.h @@ -96,7 +96,6 @@ namespace Aws */ Aws::Vector<RESOURCE_TYPE> ShutdownAndWait(size_t resourceCount) { - Aws::Vector<RESOURCE_TYPE> resources; std::unique_lock<std::mutex> locker(m_queueLock); m_shutdown = true; @@ -106,8 +105,7 @@ namespace Aws m_semaphore.wait(locker, [&]() { return m_resources.size() == resourceCount; }); } - resources = m_resources; - m_resources.clear(); + Aws::Vector<RESOURCE_TYPE> resources{std::move(m_resources)}; return resources; } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/StringUtils.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/StringUtils.h index 312342b86ad..0281a8fe06c 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/StringUtils.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/StringUtils.h @@ -10,7 +10,7 @@ #include <aws/core/utils/memory/stl/AWSString.h> #include <aws/core/utils/memory/stl/AWSVector.h> #include <aws/core/utils/memory/stl/AWSStringStream.h> - +#include <aws/common/byte_buf.h> namespace Aws @@ -82,14 +82,14 @@ namespace Aws /** * @brief Splits a string on a delimiter (empty items are excluded). * @param toSplit, the original string to split - * @param splitOn, the delemiter you want to use. + * @param splitOn, the delimiter you want to use. */ static Aws::Vector<Aws::String> Split(const Aws::String& toSplit, char splitOn); /** * @brief Splits a string on a delimiter. * @param toSplit, the original string to split - * @param splitOn, the delemiter you want to use. + * @param splitOn, the delimiter you want to use. * @param option, if INCLUDE_EMPTY_ENTRIES, includes empty entries in the result, otherwise removes empty entries. */ static Aws::Vector<Aws::String> Split(const Aws::String& toSplit, char splitOn, SplitOptions option); @@ -97,7 +97,7 @@ namespace Aws /** * @brief Splits a string on a delimiter (empty items are excluded). * @param toSplit, the original string to split - * @param splitOn, the delemiter you want to use. + * @param splitOn, the delimiter you want to use. * @param numOfTargetParts, how many target parts you want to get, if it is 0, as many as possible. */ static Aws::Vector<Aws::String> Split(const Aws::String& toSplit, char splitOn, size_t numOfTargetParts); @@ -105,7 +105,7 @@ namespace Aws /** * @brief Splits a string on a delimiter. * @param toSplit, the original string to split - * @param splitOn, the delemiter you want to use. + * @param splitOn, the delimiter you want to use. * @param numOfTargetParts, how many target parts you want to get, if it is 0, as many as possible. * @param option, if INCLUDE_EMPTY_ENTRIES, includes empty entries in the result, otherwise removes empty entries. */ @@ -212,8 +212,13 @@ namespace Aws std::reverse(s.begin(), s.end()); return s; } + + static Aws::String FromByteCursor(aws_byte_cursor cursor) + { + return Aws::String(reinterpret_cast<char *>(cursor.ptr), cursor.len); + } }; } // namespace Utils -} // namespace Aws
\ No newline at end of file +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/CRC32.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/CRC32.h new file mode 100644 index 00000000000..75fc30f0d56 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/CRC32.h @@ -0,0 +1,147 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +/* +* Interface for CRC32 and CRC32C +*/ +#pragma once + +#ifdef __APPLE__ + +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif // __clang__ + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif // __GNUC__ + +#endif // __APPLE__ + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/crypto/Hash.h> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + /** + * CRC32 hash implementation. + */ + class AWS_CORE_API CRC32 : public Hash + { + public: + /** + * Initializes platform crypto libs for crc32. + */ + CRC32(); + virtual ~CRC32(); + + /** + * Calculates a CRC32 Hash digest + */ + virtual HashResult Calculate(const Aws::String& str) override; + + /** + * Calculates a CRC32 Hash digest on a stream (the entire stream is read) + */ + virtual HashResult Calculate(Aws::IStream& stream) override; + + /** + * Updates a Hash digest + */ + virtual void Update(unsigned char* buffer, size_t bufferSize) override; + + /** + * Get the result in the current value + */ + virtual HashResult GetHash() override; + private: + + std::shared_ptr< Hash > m_hashImpl; + }; + + /** + * CRC32C hash implementation. + */ + class AWS_CORE_API CRC32C : public Hash + { + public: + /** + * Initializes platform crypto libs for crc32c. + */ + CRC32C(); + virtual ~CRC32C(); + + /** + * Calculates a CRC32C Hash digest + */ + virtual HashResult Calculate(const Aws::String& str) override; + + /** + * Calculates a CRC32C Hash digest on a stream (the entire stream is read) + */ + virtual HashResult Calculate(Aws::IStream& stream) override; + + /** + * Updates a Hash digest + */ + virtual void Update(unsigned char* buffer, size_t bufferSize) override; + + /** + * Get the result in the current value + */ + virtual HashResult GetHash() override; + + private: + + std::shared_ptr< Hash > m_hashImpl; + }; + + class AWS_CORE_API CRC32Impl : public Hash + { + public: + + CRC32Impl(); + virtual ~CRC32Impl() {} + + virtual HashResult Calculate(const Aws::String& str) override; + + virtual HashResult Calculate(Aws::IStream& stream) override; + + virtual void Update(unsigned char* buffer, size_t bufferSize) override; + + virtual HashResult GetHash() override; + + private: + int m_runningCrc32; + }; + + class AWS_CORE_API CRC32CImpl : public Hash + { + public: + + CRC32CImpl(); + virtual ~CRC32CImpl() {} + + virtual HashResult Calculate(const Aws::String& str) override; + + virtual HashResult Calculate(Aws::IStream& stream) override; + + virtual void Update(unsigned char* buffer, size_t bufferSize) override; + + virtual HashResult GetHash() override; + + private: + int m_runningCrc32c; + }; + + } // namespace Crypto + } // namespace Utils +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Factories.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Factories.h index a219d3eae50..12f610d4de1 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Factories.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Factories.h @@ -44,6 +44,14 @@ namespace Aws */ AWS_CORE_API std::shared_ptr<Hash> CreateMD5Implementation(); /** + * Create a CRC32 Hash provider + */ + AWS_CORE_API std::shared_ptr<Hash> CreateCRC32Implementation(); + /** + * Create a CRC32C Hash provider + */ + AWS_CORE_API std::shared_ptr<Hash> CreateCRC32CImplementation(); + /** * Create a Sha1 Hash provider */ AWS_CORE_API std::shared_ptr<Hash> CreateSha1Implementation(); @@ -106,18 +114,26 @@ namespace Aws /** * Create AES in Key Wrap mode off of a 256 bit key. */ - AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_KeyWrapImplementation(const CryptoBuffer& key); + AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_KeyWrapImplementation(const CryptoBuffer& key); /** * Create SecureRandomBytes instance */ AWS_CORE_API std::shared_ptr<SecureRandomBytes> CreateSecureRandomBytesImplementation(); - + /** * Set the global factory for MD5 Hash providers */ AWS_CORE_API void SetMD5Factory(const std::shared_ptr<HashFactory>& factory); /** + * Set the global factory for CRC32 Hash providers + */ + AWS_CORE_API void SetCRC32Factory(const std::shared_ptr<HashFactory>& factory); + /** + * Set the global factory for CRC32C Hash providers + */ + AWS_CORE_API void SetCRC32CFactory(const std::shared_ptr<HashFactory>& factory); + /** * Set the global factory for Sha1 Hash providers */ AWS_CORE_API void SetSha1Factory(const std::shared_ptr<HashFactory>& factory); diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Hash.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Hash.h index 8ebbe009fc4..c39f012f4c8 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Hash.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Hash.h @@ -36,6 +36,16 @@ namespace Aws */ virtual HashResult Calculate(Aws::IStream& stream) = 0; + /** + * Updates a Hash digest + */ + virtual void Update(unsigned char*, size_t bufferSize) = 0; + + /** + * Get the result in the current value + */ + virtual HashResult GetHash() = 0; + // when hashing streams, this is the size of our internal buffer we read the stream into static const uint32_t INTERNAL_HASH_STREAM_BUFFER_SIZE = 8192; }; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/MD5.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/MD5.h index 59304a4a88e..6cc7178630a 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/MD5.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/MD5.h @@ -55,6 +55,16 @@ namespace Aws */ virtual HashResult Calculate(Aws::IStream& stream) override; + /** + * Updates a Hash digest + */ + virtual void Update(unsigned char* buffer, size_t bufferSize) override; + + /** + * Get the result in the current value + */ + virtual HashResult GetHash() override; + private: std::shared_ptr<Hash> m_hashImpl; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Sha1.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Sha1.h index 5d9d44f867f..547ca655557 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Sha1.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Sha1.h @@ -54,6 +54,15 @@ namespace Aws */ virtual HashResult Calculate(Aws::IStream& stream) override; + /** + * Updates a Hash digest + */ + virtual void Update(unsigned char* buffer, size_t bufferSize) override; + + /** + * Get the result in the current value + */ + virtual HashResult GetHash() override; private: std::shared_ptr< Hash > m_hashImpl; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Sha256.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Sha256.h index 441752b0a66..40782cd58ed 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Sha256.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Sha256.h @@ -54,6 +54,16 @@ namespace Aws */ virtual HashResult Calculate(Aws::IStream& stream) override; + /** + * Updates a Hash digest + */ + virtual void Update(unsigned char* buffer, size_t bufferSize) override; + + /** + * Get the result in the current value + */ + virtual HashResult GetHash() override; + private: std::shared_ptr< Hash > m_hashImpl; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/openssl/CryptoImpl.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/openssl/CryptoImpl.h index 39f5e5fcd4e..aa31d3602fb 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/openssl/CryptoImpl.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/openssl/CryptoImpl.h @@ -39,7 +39,7 @@ namespace Aws * OpenSSL implementation for SecureRandomBytes. * Incidentally, this implementation is thread safe, though it is not * on other platforms. You should treat an instance of SecureRandomBytes - * as needed to be memory fenced if you will be using accross multiple threads + * as needed to be memory fenced if you will be using across multiple threads */ class SecureRandomBytes_OpenSSLImpl : public SecureRandomBytes { @@ -59,40 +59,59 @@ namespace Aws { public: - MD5OpenSSLImpl() - { } + MD5OpenSSLImpl(); - virtual ~MD5OpenSSLImpl() = default; + virtual ~MD5OpenSSLImpl(); virtual HashResult Calculate(const Aws::String& str) override; virtual HashResult Calculate(Aws::IStream& stream) override; + virtual void Update(unsigned char* buffer, size_t bufferSize) override; + + virtual HashResult GetHash() override; + + private: + EVP_MD_CTX *m_ctx; }; class Sha1OpenSSLImpl : public Hash { public: - Sha1OpenSSLImpl() {} - virtual ~Sha1OpenSSLImpl() = default; + Sha1OpenSSLImpl(); + + virtual ~Sha1OpenSSLImpl(); virtual HashResult Calculate(const Aws::String& str) override; virtual HashResult Calculate(Aws::IStream& stream) override; + + virtual void Update(unsigned char* buffer, size_t bufferSize) override; + + virtual HashResult GetHash() override; + + private: + EVP_MD_CTX *m_ctx; }; class Sha256OpenSSLImpl : public Hash { public: - Sha256OpenSSLImpl() - { } + Sha256OpenSSLImpl(); - virtual ~Sha256OpenSSLImpl() = default; + virtual ~Sha256OpenSSLImpl(); virtual HashResult Calculate(const Aws::String& str) override; virtual HashResult Calculate(Aws::IStream& stream) override; + + virtual void Update(unsigned char* buffer, size_t bufferSize) override; + + virtual HashResult GetHash() override; + + private: + EVP_MD_CTX *m_ctx; }; class Sha256HMACOpenSSLImpl : public HMAC @@ -187,7 +206,7 @@ namespace Aws void Cleanup(); /* openssl has bug finalize decryption of an empty string */ - bool m_emptyPlaintext; + bool m_emptyPlaintext = false; }; /** diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/event/EventHeader.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/event/EventHeader.h index c60dda04358..ae58ad5def1 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/event/EventHeader.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/event/EventHeader.h @@ -44,10 +44,11 @@ namespace Aws UNKNOWN }; - EventHeaderValue() = default; + EventHeaderValue() : m_eventHeaderType(EventHeaderType::UNKNOWN), m_eventHeaderStaticValue({0}) {} EventHeaderValue(aws_event_stream_header_value_pair* header) : - m_eventHeaderType(static_cast<EventHeaderType>(header->header_value_type)) + m_eventHeaderType(static_cast<EventHeaderType>(header->header_value_type)), + m_eventHeaderStaticValue({0}) { switch (m_eventHeaderType) { @@ -88,49 +89,57 @@ namespace Aws EventHeaderValue(const Aws::String& s) : m_eventHeaderType(EventHeaderType::STRING), - m_eventHeaderVariableLengthValue(reinterpret_cast<const uint8_t*>(s.data()), s.length()) + m_eventHeaderVariableLengthValue(reinterpret_cast<const uint8_t*>(s.data()), s.length()), + m_eventHeaderStaticValue({0}) { } EventHeaderValue(const ByteBuffer& bb) : m_eventHeaderType(EventHeaderType::BYTE_BUF), - m_eventHeaderVariableLengthValue(bb) + m_eventHeaderVariableLengthValue(bb), + m_eventHeaderStaticValue({0}) { } EventHeaderValue(ByteBuffer&& bb) : m_eventHeaderType(EventHeaderType::BYTE_BUF), - m_eventHeaderVariableLengthValue(std::move(bb)) + m_eventHeaderVariableLengthValue(std::move(bb)), + m_eventHeaderStaticValue({0}) { } explicit EventHeaderValue(unsigned char byte) : - m_eventHeaderType(EventHeaderType::BYTE) + m_eventHeaderType(EventHeaderType::BYTE), + m_eventHeaderStaticValue({0}) { m_eventHeaderStaticValue.byteValue = byte; } explicit EventHeaderValue(bool b) : - m_eventHeaderType(b ? EventHeaderType::BOOL_TRUE : EventHeaderType::BOOL_FALSE) + m_eventHeaderType(b ? EventHeaderType::BOOL_TRUE : EventHeaderType::BOOL_FALSE), + m_eventHeaderStaticValue({0}) { m_eventHeaderStaticValue.boolValue = b; } explicit EventHeaderValue(int16_t n) : - m_eventHeaderType(EventHeaderType::INT16) + m_eventHeaderType(EventHeaderType::INT16), + m_eventHeaderStaticValue({0}) { m_eventHeaderStaticValue.int16Value = n; } explicit EventHeaderValue(int32_t n) : - m_eventHeaderType(EventHeaderType::INT32) + m_eventHeaderType(EventHeaderType::INT32), + m_eventHeaderStaticValue({0}) { m_eventHeaderStaticValue.int32Value = n; } explicit EventHeaderValue(int64_t n, EventHeaderType type = EventHeaderType::INT64) : - m_eventHeaderType(type) + m_eventHeaderType(type), + m_eventHeaderStaticValue({0}) { if (type == EventHeaderType::TIMESTAMP) { @@ -295,12 +304,12 @@ namespace Aws ByteBuffer m_eventHeaderVariableLengthValue; union { - bool boolValue; - uint8_t byteValue; - int16_t int16Value; - int32_t int32Value; - int64_t int64Value; int64_t timestampValue; + int64_t int64Value; + int32_t int32Value; + int16_t int16Value; + uint8_t byteValue; + bool boolValue; } m_eventHeaderStaticValue; }; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/event/EventMessage.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/event/EventMessage.h index 4540fbe79c5..48e13c08656 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/event/EventMessage.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/event/EventMessage.h @@ -109,9 +109,9 @@ namespace Aws inline Aws::String GetEventPayloadAsString() { return Aws::String(m_eventPayload.begin(), m_eventPayload.end()); } private: - size_t m_totalLength; - size_t m_headersLength; - size_t m_payloadLength; + size_t m_totalLength = 0; + size_t m_headersLength = 0; + size_t m_payloadLength = 0; Aws::Utils::Event::EventHeaderValueCollection m_eventHeaders; Aws::Vector<unsigned char> m_eventPayload; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/event/EventStreamEncoder.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/event/EventStreamEncoder.h index 3cd06a9df22..8b9c123241c 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/event/EventStreamEncoder.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/event/EventStreamEncoder.h @@ -41,8 +41,20 @@ namespace Aws */ Aws::Vector<unsigned char> EncodeAndSign(const Aws::Utils::Event::Message& msg); private: - aws_event_stream_message Encode(const Aws::Utils::Event::Message& msg); - aws_event_stream_message Sign(aws_event_stream_message* msg); + /** + * Initialize C struct based on C++ object. + * Returns true if successful. + * A successfully initialized struct must be cleaned up when you're done with it. + */ + bool InitEncodedStruct(const Aws::Utils::Event::Message& msg, aws_event_stream_message* encoded); + + /** + * Initialize signed C struct based on unsigned C struct. + * Returns true if successful. + * A successfully initialized struct must be cleaned up when you're done with it. + */ + bool InitSignedStruct(const aws_event_stream_message* msg, aws_event_stream_message* signedmsg); + Aws::Client::AWSAuthSigner* m_signer; Aws::String m_signatureSeed; }; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/event/EventStreamHandler.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/event/EventStreamHandler.h index 257bfd82888..ac13c8ee28b 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/event/EventStreamHandler.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/event/EventStreamHandler.h @@ -29,7 +29,7 @@ namespace Aws { public: EventStreamHandler() : - m_failure(false), m_internalError(EventStreamErrors::EVENT_STREAM_NO_ERROR), m_headersBytesReceived(0), m_payloadBytesReceived(0) + m_failure(false), m_internalError(EventStreamErrors::EVENT_STREAM_NO_ERROR), m_headersBytesReceived(0), m_payloadBytesReceived(0), m_message() {} virtual ~EventStreamHandler() = default; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/json/JsonSerializer.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/json/JsonSerializer.h index 657ee6eff48..8b2ccc139bb 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/json/JsonSerializer.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/json/JsonSerializer.h @@ -19,6 +19,9 @@ namespace Aws { namespace Utils { + class Document; + class DocumentView; + namespace Json { class JsonView; @@ -56,6 +59,11 @@ namespace Aws */ JsonValue(JsonValue&& value); + /** + * Performs a deep copy of the Document parameter. + */ + JsonValue(const Aws::Utils::DocumentView& value); + ~JsonValue(); /** @@ -72,6 +80,11 @@ namespace Aws */ JsonValue& operator=(JsonValue&& other); + /** + * Performs a deep copy of the Document parameter. + */ + JsonValue& operator=(const Aws::Utils::DocumentView& value); + bool operator==(const JsonValue& other) const; bool operator!=(const JsonValue& other) const; @@ -373,6 +386,7 @@ namespace Aws JsonView(cJSON* val); JsonView& operator=(cJSON* val); cJSON* m_value; + friend class Aws::Utils::Document; }; } // namespace Json diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/CRTLogSystem.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/CRTLogSystem.h new file mode 100644 index 00000000000..204f974bbfb --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/CRTLogSystem.h @@ -0,0 +1,67 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/logging/LogLevel.h> +#include <aws/common/logging.h> + +#include <atomic> + +namespace Aws +{ + namespace Utils + { + namespace Logging + { + enum class LogLevel : int; + + /** + * Interface for CRT (common runtime libraries) logging implementations. + * A wrapper on the top of aws_logger, the logging interface used by common runtime libraries. + */ + class AWS_CORE_API CRTLogSystemInterface + { + public: + virtual ~CRTLogSystemInterface() = default; + }; + + /** + * The default CRT log system will just do a redirection of all logs from common runtime libraries to C++ SDK. + * You can override virtual function Log() in your subclass to change the default behaviors. + */ + class AWS_CORE_API DefaultCRTLogSystem : public CRTLogSystemInterface + { + public: + DefaultCRTLogSystem(LogLevel logLevel); + virtual ~DefaultCRTLogSystem(); + + /** + * Gets the currently configured log level. + */ + LogLevel GetLogLevel() const { return m_logLevel; } + /** + * Set a new log level. This has the immediate effect of changing the log output to the new level. + */ + void SetLogLevel(LogLevel logLevel) { m_logLevel.store(logLevel); } + + /** + * Handle the logging information from common runtime libraries. + * Redirect them to C++ SDK logging system by default. + */ + virtual void Log(LogLevel logLevel, const char* subjectName, const char* formatStr, va_list args); + + protected: + std::atomic<LogLevel> m_logLevel; + /** + * Underlying logging interface used by common runtime libraries. + */ + aws_logger m_logger; + }; + + } // namespace Logging + } // namespace Utils +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/CRTLogging.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/CRTLogging.h new file mode 100644 index 00000000000..5b0e6ac580a --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/CRTLogging.h @@ -0,0 +1,31 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <memory> + +namespace Aws +{ + namespace Utils + { + namespace Logging + { + class CRTLogSystemInterface; + + /** + * Initialize CRT (common runtime libraries) log system to handle loggings from common runtime libraries, including aws-c-auth, aws-c-http, aws-c-event-stream and etc. + */ + AWS_CORE_API void InitializeCRTLogging(const std::shared_ptr<CRTLogSystemInterface>& crtLogSystem); + + /** + * Shutdown CRT (common runtime libraries) log system. + */ + AWS_CORE_API void ShutdownCRTLogging(); + + } // namespace Logging + } // namespace Utils +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/ErrorMacros.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/ErrorMacros.h new file mode 100644 index 00000000000..8783ba9c0a7 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/ErrorMacros.h @@ -0,0 +1,57 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/logging/LogLevel.h> +#include <aws/core/utils/logging/AWSLogging.h> +#include <aws/core/utils/logging/LogMacros.h> + +#define AWS_OPERATION_CHECK_PTR(PTR, OPERATION, ERROR_TYPE, ERROR) \ +do { \ + if (PTR == nullptr) \ + { \ + AWS_LOGSTREAM_FATAL(#OPERATION, "Unexpected nullptr: " #PTR); \ + return OPERATION##Outcome(Aws::Client::AWSError<ERROR_TYPE>(ERROR, #ERROR, "Unexpected nullptr: " #PTR, false)); \ + } \ +} while (0) + +#define AWS_CHECK(LOG_TAG, CONDITION, ERROR_MESSAGE, RETURN) \ +do { \ + if (!(CONDITION)) \ + { \ + AWS_LOGSTREAM_ERROR(LOG_TAG, ERROR_MESSAGE); \ + return RETURN; \ + } \ +} while (0) + +#define AWS_CHECK_PTR(LOG_TAG, PTR) \ +do { \ + if (PTR == nullptr) \ + { \ + AWS_LOGSTREAM_FATAL(LOG_TAG, "Unexpected nullptr: " #PTR); \ + return; \ + } \ +} while (0) + +#define AWS_OPERATION_CHECK_SUCCESS(OUTCOME, OPERATION, ERROR_TYPE, ERROR, ERROR_MESSAGE) \ +do { \ + if (!OUTCOME.IsSuccess()) \ + { \ + AWS_LOGSTREAM_ERROR(#OPERATION, ERROR_MESSAGE); \ + return OPERATION##Outcome(Aws::Client::AWSError<ERROR_TYPE>(ERROR, #ERROR, ERROR_MESSAGE, false)); \ + } \ +} while (0) + +#define AWS_OPERATION_CHECK_PARAMETER_PRESENT(REQUEST, FIELD, OPERATION, CLIENT_NAMESPACE) \ +do { \ + if (!REQUEST##.##FIELD##HasBeenSet()) \ + { \ + AWS_LOGSTREAM_ERROR(#OPERATION, "Required field: "#FIELD" is not set"); \ + return OPERATION##Outcome(Aws::Client::AWSError<CLIENT_NAMESPACE##Errors>(CLIENT_NAMESPACE##Errors::MISSING_PARAMETER, "MISSING_PARAMETER", "Missing required field ["#FIELD"]", false)); \ + } \ +} while (0) diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/AWSMemory.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/AWSMemory.h index 5b1221917a8..125b4e05a53 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/AWSMemory.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/AWSMemory.h @@ -9,6 +9,7 @@ #include <aws/core/utils/UnreferencedParam.h> #include <aws/core/utils/memory/MemorySystemInterface.h> +#include <assert.h> #include <memory> #include <cstdlib> #include <algorithm> @@ -246,7 +247,50 @@ namespace Aws } }; - template< typename T > using UniquePtr = std::unique_ptr< T, Deleter< T > >; + template< typename T, typename D = Deleter< T > > using UniquePtr = std::unique_ptr< T, D >; + + /* + * A UniquePtr that ensures that underlying pointer is set to null on destruction. + * ...thanks to the legacy design, UniquePtr is used as a static global variable that may be destructed twice. + */ + template< typename T, typename D = Deleter< T > > + class UniquePtrSafeDeleted : public UniquePtr< T, D > + { + public: + using UniquePtr<T,D>::UniquePtr; + UniquePtrSafeDeleted(const UniquePtrSafeDeleted&) noexcept = delete; + UniquePtrSafeDeleted(UniquePtrSafeDeleted&&) noexcept = default; + UniquePtrSafeDeleted& operator=( const UniquePtrSafeDeleted<T,D>& r ) noexcept = delete; + UniquePtrSafeDeleted& operator=( UniquePtrSafeDeleted<T,D>&& r ) noexcept + { + if(&r != this) { + UniquePtr<T, D>::operator=(std::move(r)); + r.forceReset(); + } + return *this; + } + UniquePtrSafeDeleted& operator=( std::nullptr_t ) noexcept + { + forceReset(); + return *this; + } + + void forceReset() + { + if(!this->get()) + return; + this->reset(nullptr); + T volatile* newVal = this->get(); // volatile to prohibit optimizing out setting ptr to null + AWS_UNREFERENCED_PARAM(newVal); + // issue happens in Release where asserts are not enabled, so the next statement is for you, my dear reader + assert(newVal == nullptr && this->get() == nullptr); + } + + ~UniquePtrSafeDeleted() + { + forceReset(); + } + }; /** * ::new, ::delete, ::malloc, ::free, std::make_shared, and std::make_unique should not be used in SDK code @@ -255,9 +299,20 @@ namespace Aws template<typename T, typename ...ArgTypes> UniquePtr<T> MakeUnique(const char* allocationTag, ArgTypes&&... args) { + static_assert(!std::is_array<T>::value || std::is_trivial<T>::value, + "This wrapper/function is not designed to support non-trivial arrays."); return UniquePtr<T>(Aws::New<T>(allocationTag, std::forward<ArgTypes>(args)...)); } + template<typename T, typename D = Deleter<T>, typename ...ArgTypes> + UniquePtrSafeDeleted<T, D> MakeUniqueSafeDeleted(const char* allocationTag, ArgTypes&&... args) + { + static_assert(!std::is_array<T>::value || std::is_trivial<T>::value, + "This wrapper/function is not designed to support non-trivial arrays."); + + return UniquePtrSafeDeleted<T, D>(Aws::New<T>(allocationTag, std::forward<ArgTypes>(args)...), D()); + } + template<typename T> struct ArrayDeleter { diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSAllocator.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSAllocator.h index 932408b761d..0e680cb9b11 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSAllocator.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSAllocator.h @@ -10,6 +10,7 @@ #include <aws/core/SDKConfig.h> #include <aws/core/utils/memory/AWSMemory.h> #include <aws/core/utils/memory/MemorySystemInterface.h> +#include <aws/crt/StlAllocator.h> #include <memory> #include <cstdlib> @@ -17,54 +18,8 @@ namespace Aws { #ifdef USE_AWS_MEMORY_MANAGEMENT - /** - * Std allocator interface that is used for all STL types in the event that Custom Memory Management is being used. - */ - template <typename T> - class Allocator : public std::allocator<T> - { - public: - - typedef std::allocator<T> Base; - - Allocator() throw() : - Base() - {} - - Allocator(const Allocator<T>& a) throw() : - Base(a) - {} - - template <class U> - Allocator(const Allocator<U>& a) throw() : - Base(a) - {} - - ~Allocator() throw() {} - typedef std::size_t size_type; - - template<typename U> - struct rebind - { - typedef Allocator<U> other; - }; - - typename Base::pointer allocate(size_type n, const void *hint = nullptr) - { - AWS_UNREFERENCED_PARAM(hint); - - return reinterpret_cast<typename Base::pointer>(Malloc("AWSSTL", n * sizeof(T))); - } - - void deallocate(typename Base::pointer p, size_type n) - { - AWS_UNREFERENCED_PARAM(n); - - Free(p); - } - - }; + template< typename T > using Allocator = Aws::Crt::StlAllocator<T>; #ifdef __ANDROID__ #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 @@ -80,7 +35,7 @@ namespace Aws #endif // __ANDROID__ #else - + template< typename T > using Allocator = std::allocator<T>; #endif // USE_AWS_MEMORY_MANAGEMENT diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSArray.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSArray.h new file mode 100644 index 00000000000..f80be9e4a5e --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSArray.h @@ -0,0 +1,12 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#pragma once +#include <array> + +namespace Aws +{ + template< typename T, std::size_t N > using Array = std::array< T, N >; +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSSet.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSSet.h index 6aee204f398..e3ee9a0c6d7 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSSet.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSSet.h @@ -10,10 +10,12 @@ #include <aws/core/utils/memory/stl/AWSAllocator.h> #include <set> +#include <unordered_set> namespace Aws { template< typename T > using Set = std::set< T, std::less< T >, Aws::Allocator< T > >; +template< typename T > using UnorderedSet = std::unordered_set< T, std::hash< T >, std::equal_to< T >, Aws::Allocator< T > >; } // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSString.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSString.h index 3cd013e3f8d..8b6b691b848 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSString.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSString.h @@ -104,5 +104,18 @@ using WString = std::basic_string< wchar_t, std::char_traits< wchar_t >, Aws::Al } // namespace Aws +#ifdef USE_AWS_MEMORY_MANAGEMENT +#include <aws/crt/StringUtils.h> - +/* Inject hash method for an Aws::String with a custom allocator to workaround original C++ defect: + * "hash support for std::basic_string with customized allocators was not enabled" + * see LWG 3705: https://en.cppreference.com/w/cpp/string/basic_string/hash */ +namespace std +{ + template<> + struct hash<Aws::String> + { + size_t operator()(const Aws::String& t) const { return Aws::Crt::HashString(t.c_str()); } + }; +} +#endif diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/stream/ResponseStream.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/stream/ResponseStream.h index e82e6448cde..b4488a7636f 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/stream/ResponseStream.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/stream/ResponseStream.h @@ -49,14 +49,22 @@ namespace Aws /** * Gives access to underlying stream, but keep in mind that this changes state of the stream */ - inline Aws::IOStream& GetUnderlyingStream() const { return *m_underlyingStream; } + Aws::IOStream& GetUnderlyingStream() const; private: void ReleaseStream(); + void RegisterStream(); + void DeregisterStream(); - Aws::IOStream* m_underlyingStream; + Aws::IOStream* m_underlyingStream = nullptr; + + static const int xindex; + static void StreamCallback(Aws::IOStream::event evt, std::ios_base& str, int idx); }; + /** + * A default IOStream for ResponseStream. + */ class AWS_CORE_API DefaultUnderlyingStream : public Aws::IOStream { public: diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/Executor.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/Executor.h index 36975af5130..376abf480a0 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/Executor.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/Executor.h @@ -42,6 +42,12 @@ namespace Aws return SubmitToThread(std::move(callable)); } + /* explicit _overload_ of the template function above to avoid template bloat */ + bool Submit(std::function<void()>&& callable) + { + return SubmitToThread(std::move(callable)); + } + protected: /** * To implement your own executor implementation, then simply subclass Executor and implement this method. @@ -71,7 +77,7 @@ namespace Aws enum class OverflowPolicy { - QUEUE_TASKS_EVENLY_ACCROSS_THREADS, + QUEUE_TASKS_EVENLY_ACROSS_THREADS, REJECT_IMMEDIATELY }; @@ -81,7 +87,7 @@ namespace Aws class AWS_CORE_API PooledThreadExecutor : public Executor { public: - PooledThreadExecutor(size_t poolSize, OverflowPolicy overflowPolicy = OverflowPolicy::QUEUE_TASKS_EVENLY_ACCROSS_THREADS); + PooledThreadExecutor(size_t poolSize, OverflowPolicy overflowPolicy = OverflowPolicy::QUEUE_TASKS_EVENLY_ACROSS_THREADS); ~PooledThreadExecutor(); /** diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/xml/XmlSerializer.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/xml/XmlSerializer.h index d1ca79ffabf..bb6fe2ca584 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/xml/XmlSerializer.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/xml/XmlSerializer.h @@ -160,6 +160,7 @@ namespace Aws */ XmlDocument(const XmlDocument& other); XmlDocument(XmlDocument&& doc); + XmlDocument(); XmlDocument& operator=(const XmlDocument& other); XmlDocument& operator=(XmlDocument&& other); @@ -197,7 +198,6 @@ namespace Aws static XmlDocument CreateWithRootNode(const Aws::String&); private: - XmlDocument(); void InitDoc(); Aws::External::tinyxml2::XMLDocument* m_doc; @@ -215,4 +215,3 @@ namespace Aws } // namespace Xml } // namespace Utils } // namespace Aws - diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonWebServiceRequest.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonWebServiceRequest.cpp index a6b0406683c..c0f89adad01 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonWebServiceRequest.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonWebServiceRequest.cpp @@ -18,3 +18,17 @@ AmazonWebServiceRequest::AmazonWebServiceRequest() : { } +AmazonWebServiceRequest::EndpointParameters AmazonWebServiceRequest::GetEndpointContextParams() const +{ + return AmazonWebServiceRequest::EndpointParameters(); +} + +const Aws::Http::HeaderValueCollection& AmazonWebServiceRequest::GetAdditionalCustomHeaders() const +{ + return m_additionalCustomHeaders; +} + +void AmazonWebServiceRequest::SetAdditionalCustomHeaderValue(const Aws::String& headerName, const Aws::String& headerValue) +{ + m_additionalCustomHeaders[Utils::StringUtils::ToLower(headerName.c_str())] = Utils::StringUtils::Trim(headerValue.c_str()); +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Aws.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Aws.cpp index 0711fd69d66..4fd97618f30 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Aws.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Aws.cpp @@ -7,6 +7,7 @@ #include <aws/core/Aws.h> #include <aws/core/client/CoreErrors.h> #include <aws/core/utils/logging/AWSLogging.h> +#include <aws/core/utils/logging/CRTLogging.h> #include <aws/core/utils/logging/DefaultLogSystem.h> #include <aws/core/Globals.h> #include <aws/core/external/cjson/cJSON.h> @@ -27,6 +28,7 @@ namespace Aws Aws::Utils::Memory::InitializeAWSMemorySystem(*options.memoryManagementOptions.memoryManager); } #endif // USE_AWS_MEMORY_MANAGEMENT + Aws::InitializeCrt(); Aws::Client::CoreErrorsMapper::InitCoreErrorsMapper(); if(options.loggingOptions.logLevel != Aws::Utils::Logging::LogLevel::Off) { @@ -39,12 +41,46 @@ namespace Aws Aws::Utils::Logging::InitializeAWSLogging( Aws::MakeShared<Aws::Utils::Logging::DefaultLogSystem>(ALLOCATION_TAG, options.loggingOptions.logLevel, options.loggingOptions.defaultLogPrefix)); } + if(options.loggingOptions.crt_logger_create_fn) + { + Aws::Utils::Logging::InitializeCRTLogging(options.loggingOptions.crt_logger_create_fn()); + } + else + { + Aws::Utils::Logging::InitializeCRTLogging( + Aws::MakeShared<Aws::Utils::Logging::DefaultCRTLogSystem>(ALLOCATION_TAG, options.loggingOptions.logLevel)); + } // For users to better debugging in case multiple versions of SDK installed AWS_LOGSTREAM_INFO(ALLOCATION_TAG, "Initiate AWS SDK for C++ with Version:" << Aws::String(Aws::Version::GetVersionString())); } Aws::Config::InitConfigAndCredentialsCacheManager(); + if (options.ioOptions.clientBootstrap_create_fn) + { + Aws::SetDefaultClientBootstrap(options.ioOptions.clientBootstrap_create_fn()); + } + else + { + Aws::Crt::Io::EventLoopGroup eventLoopGroup; + Aws::Crt::Io::DefaultHostResolver defaultHostResolver(eventLoopGroup, 8, 30); + auto clientBootstrap = Aws::MakeShared<Aws::Crt::Io::ClientBootstrap>(ALLOCATION_TAG, eventLoopGroup, defaultHostResolver); + clientBootstrap->EnableBlockingShutdown(); + Aws::SetDefaultClientBootstrap(clientBootstrap); + } + + if (options.ioOptions.tlsConnectionOptions_create_fn) + { + Aws::SetDefaultTlsConnectionOptions(options.ioOptions.tlsConnectionOptions_create_fn()); + } + else + { + Aws::Crt::Io::TlsContextOptions tlsCtxOptions = Aws::Crt::Io::TlsContextOptions::InitDefaultClient(); + Aws::Crt::Io::TlsContext tlsContext(tlsCtxOptions, Aws::Crt::Io::TlsMode::CLIENT); + auto tlsConnectionOptions = Aws::MakeShared<Aws::Crt::Io::TlsConnectionOptions>(ALLOCATION_TAG, tlsContext.NewConnectionOptions()); + Aws::SetDefaultTlsConnectionOptions(tlsConnectionOptions); + } + if (options.cryptoOptions.aes_CBCFactory_create_fn) { Aws::Utils::Crypto::SetAES_CBCFactory(options.cryptoOptions.aes_CBCFactory_create_fn()); @@ -100,6 +136,7 @@ namespace Aws Aws::Http::SetInitCleanupCurlFlag(options.httpOptions.initAndCleanupCurl); Aws::Http::SetInstallSigPipeHandlerFlag(options.httpOptions.installSigPipeHandler); + Aws::Http::SetCompliantRfc3986Encoding(options.httpOptions.compliantRfc3986Encoding); Aws::Http::InitHttp(); Aws::InitializeEnumOverflowContainer(); cJSON_AS4CPP_Hooks hooks; @@ -122,13 +159,13 @@ namespace Aws Aws::Config::CleanupConfigAndCredentialsCacheManager(); - if(options.loggingOptions.logLevel != Aws::Utils::Logging::LogLevel::Off) + Aws::Client::CoreErrorsMapper::CleanupCoreErrorsMapper(); + Aws::CleanupCrt(); + if (options.loggingOptions.logLevel != Aws::Utils::Logging::LogLevel::Off) { + Aws::Utils::Logging::ShutdownCRTLogging(); Aws::Utils::Logging::ShutdownAWSLogging(); } - - Aws::Client::CoreErrorsMapper::CleanupCoreErrorsMapper(); - #ifdef USE_AWS_MEMORY_MANAGEMENT if(options.memoryManagementOptions.memoryManager) { diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Globals.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Globals.cpp index 55f2ee92203..8c26d2389dd 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Globals.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Globals.cpp @@ -2,13 +2,61 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ + +#include <aws/crt/Api.h> +#include <aws/crt/io/TlsOptions.h> +#include <aws/crt/io/Bootstrap.h> #include <aws/core/Globals.h> #include <aws/core/utils/EnumParseOverflowContainer.h> #include <aws/core/utils/memory/AWSMemory.h> +#include <aws/auth/auth.h> namespace Aws { static const char TAG[] = "GlobalEnumOverflowContainer"; + + static Aws::Crt::ApiHandle* g_apiHandle; + static std::shared_ptr<Aws::Crt::Io::ClientBootstrap> g_defaultClientBootstrap(nullptr); + static std::shared_ptr<Aws::Crt::Io::TlsConnectionOptions> g_defaultTlsConnectionOptions(nullptr); + + Aws::Crt::ApiHandle* GetApiHandle() + { + return g_apiHandle; + } + + void SetDefaultClientBootstrap(const std::shared_ptr<Aws::Crt::Io::ClientBootstrap>& clientBootstrap) + { + g_defaultClientBootstrap = clientBootstrap; + } + + Aws::Crt::Io::ClientBootstrap* GetDefaultClientBootstrap() + { + return g_defaultClientBootstrap.get(); + } + + void SetDefaultTlsConnectionOptions(const std::shared_ptr<Aws::Crt::Io::TlsConnectionOptions>& tlsConnectionOptions) + { + g_defaultTlsConnectionOptions = tlsConnectionOptions; + } + + Aws::Crt::Io::TlsConnectionOptions* GetDefaultTlsConnectionOptions() + { + return g_defaultTlsConnectionOptions.get(); + } + + void InitializeCrt() + { + g_apiHandle = Aws::New<Aws::Crt::ApiHandle>(TAG, Aws::get_aws_allocator()); + } + + void CleanupCrt() + { + Aws::SetDefaultClientBootstrap(nullptr); + Aws::SetDefaultTlsConnectionOptions(nullptr); + Aws::Delete(g_apiHandle); + g_apiHandle = nullptr; + } + static Utils::EnumParseOverflowContainer* g_enumOverflow; Utils::EnumParseOverflowContainer* GetEnumOverflowContainer() diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Region.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Region.cpp index 4b18bf2a2af..620923d6cdd 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Region.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Region.cpp @@ -15,6 +15,10 @@ namespace Aws { return Aws::Region::US_EAST_1; } + else if (region == "fips-aws-global") + { + return Aws::Region::US_EAST_1; + } else if (region == "s3-external-1") { return Aws::Region::US_EAST_1; @@ -32,5 +36,18 @@ namespace Aws return region; } } + + bool IsFipsRegion(const Aws::String& region) + { + if (region.size() >= 5 && region.compare(0, 5, "fips-") == 0) + { + return true; + } + else if (region.size() >= 5 && region.compare(region.size() - 5, 5, "-fips") == 0) + { + return true; + } + return false; + } } }
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp deleted file mode 100644 index 0baa00058f9..00000000000 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp +++ /dev/null @@ -1,806 +0,0 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ - -#include <aws/core/auth/AWSAuthSigner.h> - -#include <aws/core/auth/AWSCredentialsProvider.h> -#include <aws/core/client/ClientConfiguration.h> -#include <aws/core/http/HttpRequest.h> -#include <aws/core/http/HttpResponse.h> -#include <aws/core/utils/DateTime.h> -#include <aws/core/utils/HashingUtils.h> -#include <aws/core/utils/Outcome.h> -#include <aws/core/utils/StringUtils.h> -#include <aws/core/utils/logging/LogMacros.h> -#include <aws/core/utils/memory/AWSMemory.h> -#include <aws/core/utils/crypto/Sha256.h> -#include <aws/core/utils/crypto/Sha256HMAC.h> -#include <aws/core/utils/stream/PreallocatedStreamBuf.h> -#include <aws/core/utils/event/EventMessage.h> -#include <aws/core/utils/event/EventHeader.h> - -#include <cstdio> -#include <iomanip> -#include <math.h> -#include <cstring> - -using namespace Aws; -using namespace Aws::Client; -using namespace Aws::Auth; -using namespace Aws::Http; -using namespace Aws::Utils; -using namespace Aws::Utils::Logging; - -static const char* EQ = "="; -static const char* AWS_HMAC_SHA256 = "AWS4-HMAC-SHA256"; -static const char* EVENT_STREAM_CONTENT_SHA256 = "STREAMING-AWS4-HMAC-SHA256-EVENTS"; -static const char* EVENT_STREAM_PAYLOAD = "AWS4-HMAC-SHA256-PAYLOAD"; -static const char* AWS4_REQUEST = "aws4_request"; -static const char* SIGNED_HEADERS = "SignedHeaders"; -static const char* CREDENTIAL = "Credential"; -static const char* NEWLINE = "\n"; -static const char* X_AMZ_SIGNED_HEADERS = "X-Amz-SignedHeaders"; -static const char* X_AMZ_ALGORITHM = "X-Amz-Algorithm"; -static const char* X_AMZ_CREDENTIAL = "X-Amz-Credential"; -static const char* UNSIGNED_PAYLOAD = "UNSIGNED-PAYLOAD"; -static const char* X_AMZ_SIGNATURE = "X-Amz-Signature"; -static const char* X_AMZN_TRACE_ID = "x-amzn-trace-id"; -static const char* X_AMZ_CONTENT_SHA256 = "x-amz-content-sha256"; -static const char* USER_AGENT = "user-agent"; -static const char* SIGNING_KEY = "AWS4"; -static const char* SIMPLE_DATE_FORMAT_STR = "%Y%m%d"; -static const char* EMPTY_STRING_SHA256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"; - -static const char v4LogTag[] = "AWSAuthV4Signer"; -static const char v4StreamingLogTag[] = "AWSAuthEventStreamV4Signer"; - -namespace Aws -{ - namespace Auth - { - const char SIGNATURE[] = "Signature"; - const char SIGV4_SIGNER[] = "SignatureV4"; - const char EVENTSTREAM_SIGV4_SIGNER[] = "EventStreamSignatureV4"; - const char EVENTSTREAM_SIGNATURE_HEADER[] = ":chunk-signature"; - const char EVENTSTREAM_DATE_HEADER[] = ":date"; - const char NULL_SIGNER[] = "NullSigner"; - } -} - -static Aws::String CanonicalizeRequestSigningString(HttpRequest& request, bool urlEscapePath) -{ - request.CanonicalizeRequest(); - Aws::StringStream signingStringStream; - signingStringStream << HttpMethodMapper::GetNameForHttpMethod(request.GetMethod()); - - URI uriCpy = request.GetUri(); - // Many AWS services do not decode the URL before calculating SignatureV4 on their end. - // This results in the signature getting calculated with a double encoded URL. - // That means we have to double encode it here for the signature to match on the service side. - if(urlEscapePath) - { - // RFC3986 is how we encode the URL before sending it on the wire. - auto rfc3986EncodedPath = URI::URLEncodePathRFC3986(uriCpy.GetPath()); - uriCpy.SetPath(rfc3986EncodedPath); - // However, SignatureV4 uses this URL encoding scheme - signingStringStream << NEWLINE << uriCpy.GetURLEncodedPath() << NEWLINE; - } - else - { - // For the services that DO decode the URL first; we don't need to double encode it. - uriCpy.SetPath(uriCpy.GetURLEncodedPath()); - signingStringStream << NEWLINE << uriCpy.GetPath() << NEWLINE; - } - - if (request.GetQueryString().find('=') != std::string::npos) - { - signingStringStream << request.GetQueryString().substr(1) << NEWLINE; - } - else if (request.GetQueryString().size() > 1) - { - signingStringStream << request.GetQueryString().substr(1) << "=" << NEWLINE; - } - else - { - signingStringStream << NEWLINE; - } - - return signingStringStream.str(); -} - -static Http::HeaderValueCollection CanonicalizeHeaders(Http::HeaderValueCollection&& headers) -{ - Http::HeaderValueCollection canonicalHeaders; - for (const auto& header : headers) - { - auto trimmedHeaderName = StringUtils::Trim(header.first.c_str()); - auto trimmedHeaderValue = StringUtils::Trim(header.second.c_str()); - - //multiline gets converted to line1,line2,etc... - auto headerMultiLine = StringUtils::SplitOnLine(trimmedHeaderValue); - Aws::String headerValue = headerMultiLine.size() == 0 ? "" : headerMultiLine[0]; - - if (headerMultiLine.size() > 1) - { - for(size_t i = 1; i < headerMultiLine.size(); ++i) - { - headerValue += ","; - headerValue += StringUtils::Trim(headerMultiLine[i].c_str()); - } - } - - //duplicate spaces need to be converted to one. - Aws::String::iterator new_end = - std::unique(headerValue.begin(), headerValue.end(), - [=](char lhs, char rhs) { return (lhs == rhs) && (lhs == ' '); } - ); - headerValue.erase(new_end, headerValue.end()); - - canonicalHeaders[trimmedHeaderName] = headerValue; - } - - return canonicalHeaders; -} - -AWSAuthV4Signer::AWSAuthV4Signer(const std::shared_ptr<Auth::AWSCredentialsProvider>& credentialsProvider, - const char* serviceName, const Aws::String& region, PayloadSigningPolicy signingPolicy, bool urlEscapePath) : - m_includeSha256HashHeader(true), - m_credentialsProvider(credentialsProvider), - m_serviceName(serviceName), - m_region(region), - m_hash(Aws::MakeUnique<Aws::Utils::Crypto::Sha256>(v4LogTag)), - m_HMAC(Aws::MakeUnique<Aws::Utils::Crypto::Sha256HMAC>(v4LogTag)), - m_unsignedHeaders({USER_AGENT, X_AMZN_TRACE_ID}), - m_payloadSigningPolicy(signingPolicy), - m_urlEscapePath(urlEscapePath) -{ - //go ahead and warm up the signing cache. - ComputeHash(credentialsProvider->GetAWSCredentials().GetAWSSecretKey(), DateTime::CalculateGmtTimestampAsString(SIMPLE_DATE_FORMAT_STR), region, m_serviceName); -} - -AWSAuthV4Signer::~AWSAuthV4Signer() -{ - // empty destructor in .cpp file to keep from needing the implementation of (AWSCredentialsProvider, Sha256, Sha256HMAC) in the header file -} - - -bool AWSAuthV4Signer::ShouldSignHeader(const Aws::String& header) const -{ - return m_unsignedHeaders.find(Aws::Utils::StringUtils::ToLower(header.c_str())) == m_unsignedHeaders.cend(); -} - -bool AWSAuthV4Signer::SignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, bool signBody) const -{ - AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials(); - - //don't sign anonymous requests - if (credentials.GetAWSAccessKeyId().empty() || credentials.GetAWSSecretKey().empty()) - { - return true; - } - - if (!credentials.GetSessionToken().empty()) - { - request.SetAwsSessionToken(credentials.GetSessionToken()); - } - - Aws::String payloadHash(UNSIGNED_PAYLOAD); - switch(m_payloadSigningPolicy) - { - case PayloadSigningPolicy::Always: - signBody = true; - break; - case PayloadSigningPolicy::Never: - signBody = false; - break; - case PayloadSigningPolicy::RequestDependent: - // respect the request setting - default: - break; - } - - if(signBody || request.GetUri().GetScheme() != Http::Scheme::HTTPS) - { - payloadHash = ComputePayloadHash(request); - if (payloadHash.empty()) - { - return false; - } - } - else - { - AWS_LOGSTREAM_DEBUG(v4LogTag, "Note: Http payloads are not being signed. signPayloads=" << signBody - << " http scheme=" << Http::SchemeMapper::ToString(request.GetUri().GetScheme())); - } - - if(m_includeSha256HashHeader) - { - request.SetHeaderValue(X_AMZ_CONTENT_SHA256, payloadHash); - } - - //calculate date header to use in internal signature (this also goes into date header). - DateTime now = GetSigningTimestamp(); - Aws::String dateHeaderValue = now.ToGmtString(DateFormat::ISO_8601_BASIC); - request.SetHeaderValue(AWS_DATE_HEADER, dateHeaderValue); - - Aws::StringStream headersStream; - Aws::StringStream signedHeadersStream; - - for (const auto& header : CanonicalizeHeaders(request.GetHeaders())) - { - if(ShouldSignHeader(header.first)) - { - headersStream << header.first.c_str() << ":" << header.second.c_str() << NEWLINE; - signedHeadersStream << header.first.c_str() << ";"; - } - } - - Aws::String canonicalHeadersString = headersStream.str(); - AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Header String: " << canonicalHeadersString); - - //calculate signed headers parameter - Aws::String signedHeadersValue = signedHeadersStream.str(); - //remove that last semi-colon - if (!signedHeadersValue.empty()) - { - signedHeadersValue.pop_back(); - } - - AWS_LOGSTREAM_DEBUG(v4LogTag, "Signed Headers value:" << signedHeadersValue); - - //generate generalized canonicalized request string. - Aws::String canonicalRequestString = CanonicalizeRequestSigningString(request, m_urlEscapePath); - - //append v4 stuff to the canonical request string. - canonicalRequestString.append(canonicalHeadersString); - canonicalRequestString.append(NEWLINE); - canonicalRequestString.append(signedHeadersValue); - canonicalRequestString.append(NEWLINE); - canonicalRequestString.append(payloadHash); - - AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Request String: " << canonicalRequestString); - - //now compute sha256 on that request string - auto hashResult = m_hash->Calculate(canonicalRequestString); - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to hash (sha256) request string"); - AWS_LOGSTREAM_DEBUG(v4LogTag, "The request string is: \"" << canonicalRequestString << "\""); - return false; - } - - auto sha256Digest = hashResult.GetResult(); - Aws::String canonicalRequestHash = HashingUtils::HexEncode(sha256Digest); - Aws::String simpleDate = now.ToGmtString(SIMPLE_DATE_FORMAT_STR); - - Aws::String signingRegion = region ? region : m_region; - Aws::String signingServiceName = serviceName ? serviceName : m_serviceName; - Aws::String stringToSign = GenerateStringToSign(dateHeaderValue, simpleDate, canonicalRequestHash, signingRegion, signingServiceName); - auto finalSignature = GenerateSignature(credentials, stringToSign, simpleDate, signingRegion, signingServiceName); - - Aws::StringStream ss; - ss << AWS_HMAC_SHA256 << " " << CREDENTIAL << EQ << credentials.GetAWSAccessKeyId() << "/" << simpleDate - << "/" << signingRegion << "/" << signingServiceName << "/" << AWS4_REQUEST << ", " << SIGNED_HEADERS << EQ - << signedHeadersValue << ", " << SIGNATURE << EQ << finalSignature; - - auto awsAuthString = ss.str(); - AWS_LOGSTREAM_DEBUG(v4LogTag, "Signing request with: " << awsAuthString); - request.SetAwsAuthorization(awsAuthString); - request.SetSigningAccessKey(credentials.GetAWSAccessKeyId()); - request.SetSigningRegion(signingRegion); - return true; -} - -bool AWSAuthV4Signer::PresignRequest(Aws::Http::HttpRequest& request, long long expirationTimeInSeconds) const -{ - return PresignRequest(request, m_region.c_str(), expirationTimeInSeconds); -} - -bool AWSAuthV4Signer::PresignRequest(Aws::Http::HttpRequest& request, const char* region, long long expirationInSeconds) const -{ - return PresignRequest(request, region, m_serviceName.c_str(), expirationInSeconds); -} - -bool AWSAuthV4Signer::PresignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, long long expirationTimeInSeconds) const -{ - AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials(); - - //don't sign anonymous requests - if (credentials.GetAWSAccessKeyId().empty() || credentials.GetAWSSecretKey().empty()) - { - return true; - } - - Aws::StringStream intConversionStream; - intConversionStream << expirationTimeInSeconds; - request.AddQueryStringParameter(Http::X_AMZ_EXPIRES_HEADER, intConversionStream.str()); - - if (!credentials.GetSessionToken().empty()) - { - request.AddQueryStringParameter(Http::AWS_SECURITY_TOKEN, credentials.GetSessionToken()); - } - - //calculate date header to use in internal signature (this also goes into date header). - DateTime now = GetSigningTimestamp(); - Aws::String dateQueryValue = now.ToGmtString(DateFormat::ISO_8601_BASIC); - request.AddQueryStringParameter(Http::AWS_DATE_HEADER, dateQueryValue); - - Aws::StringStream headersStream; - Aws::StringStream signedHeadersStream; - for (const auto& header : CanonicalizeHeaders(request.GetHeaders())) - { - if(ShouldSignHeader(header.first)) - { - headersStream << header.first.c_str() << ":" << header.second.c_str() << NEWLINE; - signedHeadersStream << header.first.c_str() << ";"; - } - } - - Aws::String canonicalHeadersString = headersStream.str(); - AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Header String: " << canonicalHeadersString); - - //calculate signed headers parameter - Aws::String signedHeadersValue(signedHeadersStream.str()); - //remove that last semi-colon - if (!signedHeadersValue.empty()) - { - signedHeadersValue.pop_back(); - } - - request.AddQueryStringParameter(X_AMZ_SIGNED_HEADERS, signedHeadersValue); - AWS_LOGSTREAM_DEBUG(v4LogTag, "Signed Headers value: " << signedHeadersValue); - - Aws::StringStream ss; - Aws::String signingRegion = region ? region : m_region; - Aws::String signingServiceName = serviceName ? serviceName : m_serviceName; - Aws::String simpleDate = now.ToGmtString(SIMPLE_DATE_FORMAT_STR); - ss << credentials.GetAWSAccessKeyId() << "/" << simpleDate - << "/" << signingRegion << "/" << signingServiceName << "/" << AWS4_REQUEST; - - request.AddQueryStringParameter(X_AMZ_ALGORITHM, AWS_HMAC_SHA256); - request.AddQueryStringParameter(X_AMZ_CREDENTIAL, ss.str()); - ss.str(""); - - request.SetSigningAccessKey(credentials.GetAWSAccessKeyId()); - request.SetSigningRegion(signingRegion); - - //generate generalized canonicalized request string. - Aws::String canonicalRequestString = CanonicalizeRequestSigningString(request, m_urlEscapePath); - - //append v4 stuff to the canonical request string. - canonicalRequestString.append(canonicalHeadersString); - canonicalRequestString.append(NEWLINE); - canonicalRequestString.append(signedHeadersValue); - canonicalRequestString.append(NEWLINE); - if (ServiceRequireUnsignedPayload(signingServiceName)) - { - canonicalRequestString.append(UNSIGNED_PAYLOAD); - } - else - { - canonicalRequestString.append(EMPTY_STRING_SHA256); - } - AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Request String: " << canonicalRequestString); - - //now compute sha256 on that request string - auto hashResult = m_hash->Calculate(canonicalRequestString); - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to hash (sha256) request string"); - AWS_LOGSTREAM_DEBUG(v4LogTag, "The request string is: \"" << canonicalRequestString << "\""); - return false; - } - - auto sha256Digest = hashResult.GetResult(); - auto canonicalRequestHash = HashingUtils::HexEncode(sha256Digest); - - auto stringToSign = GenerateStringToSign(dateQueryValue, simpleDate, canonicalRequestHash, signingRegion, signingServiceName); - auto finalSigningHash = GenerateSignature(credentials, stringToSign, simpleDate, signingRegion, signingServiceName); - if (finalSigningHash.empty()) - { - return false; - } - - //add that the signature to the query string - request.AddQueryStringParameter(X_AMZ_SIGNATURE, finalSigningHash); - - return true; -} - -bool AWSAuthV4Signer::ServiceRequireUnsignedPayload(const Aws::String& serviceName) const -{ - // S3 uses a magic string (instead of the empty string) for its body hash for presigned URLs as outlined here: - // https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html - // this is true for PUT, POST, GET, DELETE and HEAD operations. - // However, other services (for example RDS) implement the specification as outlined here: - // https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html - // which states that body-less requests should use the empty-string SHA256 hash. - return "s3" == serviceName || "s3-object-lambda" == serviceName; -} - -Aws::String AWSAuthV4Signer::GenerateSignature(const AWSCredentials& credentials, const Aws::String& stringToSign, - const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const -{ - auto key = ComputeHash(credentials.GetAWSSecretKey(), simpleDate, region, serviceName); - return GenerateSignature(stringToSign, key); -} - -Aws::String AWSAuthV4Signer::GenerateSignature(const Aws::String& stringToSign, const ByteBuffer& key) const -{ - AWS_LOGSTREAM_DEBUG(v4LogTag, "Final String to sign: " << stringToSign); - - Aws::StringStream ss; - - auto hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)stringToSign.c_str(), stringToSign.length()), key); - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to hmac (sha256) final string"); - AWS_LOGSTREAM_DEBUG(v4LogTag, "The final string is: \"" << stringToSign << "\""); - return {}; - } - - //now we finally sign our request string with our hex encoded derived hash. - auto finalSigningDigest = hashResult.GetResult(); - - auto finalSigningHash = HashingUtils::HexEncode(finalSigningDigest); - AWS_LOGSTREAM_DEBUG(v4LogTag, "Final computed signing hash: " << finalSigningHash); - - return finalSigningHash; -} - -Aws::String AWSAuthV4Signer::ComputePayloadHash(Aws::Http::HttpRequest& request) const -{ - if (!request.GetContentBody()) - { - AWS_LOGSTREAM_DEBUG(v4LogTag, "Using cached empty string sha256 " << EMPTY_STRING_SHA256 << " because payload is empty."); - return EMPTY_STRING_SHA256; - } - - //compute hash on payload if it exists. - auto hashResult = m_hash->Calculate(*request.GetContentBody()); - - if(request.GetContentBody()) - { - request.GetContentBody()->clear(); - request.GetContentBody()->seekg(0); - } - - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to hash (sha256) request body"); - return {}; - } - - auto sha256Digest = hashResult.GetResult(); - - Aws::String payloadHash(HashingUtils::HexEncode(sha256Digest)); - AWS_LOGSTREAM_DEBUG(v4LogTag, "Calculated sha256 " << payloadHash << " for payload."); - return payloadHash; -} - -Aws::String AWSAuthV4Signer::GenerateStringToSign(const Aws::String& dateValue, const Aws::String& simpleDate, - const Aws::String& canonicalRequestHash, const Aws::String& region, const Aws::String& serviceName) const -{ - //generate the actual string we will use in signing the final request. - Aws::StringStream ss; - - ss << AWS_HMAC_SHA256 << NEWLINE << dateValue << NEWLINE << simpleDate << "/" << region << "/" - << serviceName << "/" << AWS4_REQUEST << NEWLINE << canonicalRequestHash; - - return ss.str(); -} - -Aws::Utils::ByteBuffer AWSAuthV4Signer::ComputeHash(const Aws::String& secretKey, - const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const -{ - Aws::String signingKey(SIGNING_KEY); - signingKey.append(secretKey); - auto hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)simpleDate.c_str(), simpleDate.length()), - ByteBuffer((unsigned char*)signingKey.c_str(), signingKey.length())); - - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to HMAC (SHA256) date string \"" << simpleDate << "\""); - return {}; - } - - auto kDate = hashResult.GetResult(); - hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)region.c_str(), region.length()), kDate); - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to HMAC (SHA256) region string \"" << region << "\""); - return {}; - } - - auto kRegion = hashResult.GetResult(); - hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)serviceName.c_str(), serviceName.length()), kRegion); - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to HMAC (SHA256) service string \"" << m_serviceName << "\""); - return {}; - } - - auto kService = hashResult.GetResult(); - hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)AWS4_REQUEST, strlen(AWS4_REQUEST)), kService); - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to HMAC (SHA256) request string"); - AWS_LOGSTREAM_DEBUG(v4LogTag, "The request string is: \"" << AWS4_REQUEST << "\""); - return {}; - } - return hashResult.GetResult(); -} - -AWSAuthEventStreamV4Signer::AWSAuthEventStreamV4Signer(const std::shared_ptr<Auth::AWSCredentialsProvider>& - credentialsProvider, const char* serviceName, const Aws::String& region) : - m_serviceName(serviceName), - m_region(region), - m_credentialsProvider(credentialsProvider) -{ - - m_unsignedHeaders.emplace_back(X_AMZN_TRACE_ID); - m_unsignedHeaders.emplace_back(USER_AGENT_HEADER); -} - -bool AWSAuthEventStreamV4Signer::SignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, bool /* signBody */) const -{ - AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials(); - - //don't sign anonymous requests - if (credentials.GetAWSAccessKeyId().empty() || credentials.GetAWSSecretKey().empty()) - { - return true; - } - - if (!credentials.GetSessionToken().empty()) - { - request.SetAwsSessionToken(credentials.GetSessionToken()); - } - - request.SetHeaderValue(X_AMZ_CONTENT_SHA256, EVENT_STREAM_CONTENT_SHA256); - - //calculate date header to use in internal signature (this also goes into date header). - DateTime now = GetSigningTimestamp(); - Aws::String dateHeaderValue = now.ToGmtString(DateFormat::ISO_8601_BASIC); - request.SetHeaderValue(AWS_DATE_HEADER, dateHeaderValue); - - Aws::StringStream headersStream; - Aws::StringStream signedHeadersStream; - - for (const auto& header : CanonicalizeHeaders(request.GetHeaders())) - { - if(ShouldSignHeader(header.first)) - { - headersStream << header.first.c_str() << ":" << header.second.c_str() << NEWLINE; - signedHeadersStream << header.first.c_str() << ";"; - } - } - - Aws::String canonicalHeadersString = headersStream.str(); - AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Canonical Header String: " << canonicalHeadersString); - - //calculate signed headers parameter - Aws::String signedHeadersValue = signedHeadersStream.str(); - //remove that last semi-colon - if (!signedHeadersValue.empty()) - { - signedHeadersValue.pop_back(); - } - - AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Signed Headers value:" << signedHeadersValue); - - //generate generalized canonicalized request string. - Aws::String canonicalRequestString = CanonicalizeRequestSigningString(request, true/* m_urlEscapePath */); - - //append v4 stuff to the canonical request string. - canonicalRequestString.append(canonicalHeadersString); - canonicalRequestString.append(NEWLINE); - canonicalRequestString.append(signedHeadersValue); - canonicalRequestString.append(NEWLINE); - canonicalRequestString.append(EVENT_STREAM_CONTENT_SHA256); - - AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Canonical Request String: " << canonicalRequestString); - - //now compute sha256 on that request string - auto hashResult = m_hash.Calculate(canonicalRequestString); - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to hash (sha256) request string"); - AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "The request string is: \"" << canonicalRequestString << "\""); - return false; - } - - auto sha256Digest = hashResult.GetResult(); - Aws::String canonicalRequestHash = HashingUtils::HexEncode(sha256Digest); - Aws::String simpleDate = now.ToGmtString(SIMPLE_DATE_FORMAT_STR); - - Aws::String signingRegion = region ? region : m_region; - Aws::String signingServiceName = serviceName ? serviceName : m_serviceName; - Aws::String stringToSign = GenerateStringToSign(dateHeaderValue, simpleDate, canonicalRequestHash, signingRegion, signingServiceName); - auto finalSignature = GenerateSignature(credentials, stringToSign, simpleDate, signingRegion, signingServiceName); - - Aws::StringStream ss; - ss << AWS_HMAC_SHA256 << " " << CREDENTIAL << EQ << credentials.GetAWSAccessKeyId() << "/" << simpleDate - << "/" << signingRegion << "/" << signingServiceName << "/" << AWS4_REQUEST << ", " << SIGNED_HEADERS << EQ - << signedHeadersValue << ", " << SIGNATURE << EQ << HashingUtils::HexEncode(finalSignature); - - auto awsAuthString = ss.str(); - AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Signing request with: " << awsAuthString); - request.SetAwsAuthorization(awsAuthString); - request.SetSigningAccessKey(credentials.GetAWSAccessKeyId()); - request.SetSigningRegion(signingRegion); - return true; -} - -// this works regardless if the current machine is Big/Little Endian -static void WriteBigEndian(Aws::String& str, uint64_t n) -{ - int shift = 56; - while(shift >= 0) - { - str.push_back((n >> shift) & 0xFF); - shift -= 8; - } -} - -bool AWSAuthEventStreamV4Signer::SignEventMessage(Event::Message& message, Aws::String& priorSignature) const -{ - using Event::EventHeaderValue; - - Aws::StringStream stringToSign; - stringToSign << EVENT_STREAM_PAYLOAD << NEWLINE; - const DateTime now = GetSigningTimestamp(); - const auto simpleDate = now.ToGmtString(SIMPLE_DATE_FORMAT_STR); - stringToSign << now.ToGmtString(DateFormat::ISO_8601_BASIC) << NEWLINE - << simpleDate << "/" << m_region << "/" - << m_serviceName << "/aws4_request" << NEWLINE << priorSignature << NEWLINE; - - - Aws::String nonSignatureHeaders; - nonSignatureHeaders.push_back(char(sizeof(EVENTSTREAM_DATE_HEADER) - 1)); // length of the string - nonSignatureHeaders += EVENTSTREAM_DATE_HEADER; - nonSignatureHeaders.push_back(static_cast<char>(EventHeaderValue::EventHeaderType::TIMESTAMP)); // type of the value - WriteBigEndian(nonSignatureHeaders, static_cast<uint64_t>(now.Millis())); // the value of the timestamp in big-endian - - auto hashOutcome = m_hash.Calculate(nonSignatureHeaders); - if (!hashOutcome.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to hash (sha256) non-signature headers."); - return false; - } - - const auto nonSignatureHeadersHash = hashOutcome.GetResult(); - stringToSign << HashingUtils::HexEncode(nonSignatureHeadersHash) << NEWLINE; - - if (message.GetEventPayload().empty()) - { - AWS_LOGSTREAM_WARN(v4StreamingLogTag, "Attempting to sign an empty message (no payload and no headers). " - "It is unlikely that this is the intended behavior."); - } - else - { - // use a preallocatedStreamBuf to avoid making a copy. - // The Hashing API requires either Aws::String or IStream as input. - // TODO: the hashing API should be accept 'unsigned char*' as input. - Utils::Stream::PreallocatedStreamBuf streamBuf(message.GetEventPayload().data(), message.GetEventPayload().size()); - Aws::IOStream payload(&streamBuf); - hashOutcome = m_hash.Calculate(payload); - - if (!hashOutcome.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to hash (sha256) non-signature headers."); - return false; - } - const auto payloadHash = hashOutcome.GetResult(); - stringToSign << HashingUtils::HexEncode(payloadHash); - AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Payload hash - " << HashingUtils::HexEncode(payloadHash)); - } - - Utils::ByteBuffer finalSignatureDigest = GenerateSignature(m_credentialsProvider->GetAWSCredentials(), stringToSign.str(), simpleDate, m_region, m_serviceName); - const auto finalSignature = HashingUtils::HexEncode(finalSignatureDigest); - AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Final computed signing hash: " << finalSignature); - priorSignature = finalSignature; - - message.InsertEventHeader(EVENTSTREAM_DATE_HEADER, EventHeaderValue(now.Millis(), EventHeaderValue::EventHeaderType::TIMESTAMP)); - message.InsertEventHeader(EVENTSTREAM_SIGNATURE_HEADER, std::move(finalSignatureDigest)); - - AWS_LOGSTREAM_INFO(v4StreamingLogTag, "Event chunk final signature - " << finalSignature); - return true; -} - -bool AWSAuthEventStreamV4Signer::ShouldSignHeader(const Aws::String& header) const -{ - return std::find(m_unsignedHeaders.cbegin(), m_unsignedHeaders.cend(), Aws::Utils::StringUtils::ToLower(header.c_str())) == m_unsignedHeaders.cend(); -} - -Utils::ByteBuffer AWSAuthEventStreamV4Signer::GenerateSignature(const AWSCredentials& credentials, const Aws::String& stringToSign, - const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const -{ - Utils::Threading::ReaderLockGuard guard(m_derivedKeyLock); - const auto& secretKey = credentials.GetAWSSecretKey(); - if (secretKey != m_currentSecretKey || simpleDate != m_currentDateStr) - { - guard.UpgradeToWriterLock(); - // double-checked lock to prevent updating twice - if (m_currentDateStr != simpleDate || m_currentSecretKey != secretKey) - { - m_currentSecretKey = secretKey; - m_currentDateStr = simpleDate; - m_derivedKey = ComputeHash(m_currentSecretKey, m_currentDateStr, region, serviceName); - } - - } - return GenerateSignature(stringToSign, m_derivedKey); -} - -Utils::ByteBuffer AWSAuthEventStreamV4Signer::GenerateSignature(const Aws::String& stringToSign, const ByteBuffer& key) const -{ - AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Final String to sign: " << stringToSign); - - Aws::StringStream ss; - - auto hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)stringToSign.c_str(), stringToSign.length()), key); - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Unable to hmac (sha256) final string"); - AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "The final string is: \"" << stringToSign << "\""); - return {}; - } - - return hashResult.GetResult(); -} - -Aws::String AWSAuthEventStreamV4Signer::GenerateStringToSign(const Aws::String& dateValue, const Aws::String& simpleDate, - const Aws::String& canonicalRequestHash, const Aws::String& region, const Aws::String& serviceName) const -{ - //generate the actual string we will use in signing the final request. - Aws::StringStream ss; - - ss << AWS_HMAC_SHA256 << NEWLINE << dateValue << NEWLINE << simpleDate << "/" << region << "/" - << serviceName << "/" << AWS4_REQUEST << NEWLINE << canonicalRequestHash; - - return ss.str(); -} - -Aws::Utils::ByteBuffer AWSAuthEventStreamV4Signer::ComputeHash(const Aws::String& secretKey, - const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const -{ - Aws::String signingKey(SIGNING_KEY); - signingKey.append(secretKey); - auto hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)simpleDate.c_str(), simpleDate.length()), - ByteBuffer((unsigned char*)signingKey.c_str(), signingKey.length())); - - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to HMAC (SHA256) date string \"" << simpleDate << "\""); - return {}; - } - - auto kDate = hashResult.GetResult(); - hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)region.c_str(), region.length()), kDate); - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to HMAC (SHA256) region string \"" << region << "\""); - return {}; - } - - auto kRegion = hashResult.GetResult(); - hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)serviceName.c_str(), serviceName.length()), kRegion); - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to HMAC (SHA256) service string \"" << m_serviceName << "\""); - return {}; - } - - auto kService = hashResult.GetResult(); - hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)AWS4_REQUEST, strlen(AWS4_REQUEST)), kService); - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Unable to HMAC (SHA256) request string"); - AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "The request string is: \"" << AWS4_REQUEST << "\""); - return {}; - } - return hashResult.GetResult(); -} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp index bf20ede35e1..084e4bca6e2 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp @@ -48,7 +48,7 @@ static const char DEFAULT_CREDENTIALS_FILE[] = "credentials"; extern const char DEFAULT_CONFIG_FILE[] = "config"; -static const int EXPIRATION_GRACE_PERIOD = 5 * 1000; +static const int AWS_CREDENTIAL_PROVIDER_EXPIRATION_GRACE_PERIOD = 5 * 1000; void AWSCredentialsProvider::Reload() { @@ -183,9 +183,10 @@ AWSCredentials ProfileConfigFileAWSCredentialsProvider::GetAWSCredentials() { RefreshIfExpired(); ReaderLockGuard guard(m_reloadLock); - auto credsFileProfileIter = m_credentialsFileLoader.GetProfiles().find(m_profileToUse); + const Aws::Map<Aws::String, Aws::Config::Profile>& profiles = m_credentialsFileLoader.GetProfiles(); + auto credsFileProfileIter = profiles.find(m_profileToUse); - if(credsFileProfileIter != m_credentialsFileLoader.GetProfiles().end()) + if(credsFileProfileIter != profiles.end()) { return credsFileProfileIter->second.GetCredentials(); } @@ -239,37 +240,71 @@ AWSCredentials InstanceProfileCredentialsProvider::GetAWSCredentials() { RefreshIfExpired(); ReaderLockGuard guard(m_reloadLock); + if (m_ec2MetadataConfigLoader) + { + const Aws::Map<Aws::String, Aws::Config::Profile> &profiles = m_ec2MetadataConfigLoader->GetProfiles(); + auto profileIter = profiles.find(Aws::Config::INSTANCE_PROFILE_KEY); + + if (profileIter != profiles.end()) { + return profileIter->second.GetCredentials(); + } + } + else + { + AWS_LOGSTREAM_ERROR(INSTANCE_LOG_TAG, "EC2 Metadata config loader is a nullptr"); + } + + return AWSCredentials(); +} + +bool InstanceProfileCredentialsProvider::ExpiresSoon() const +{ + ReaderLockGuard guard(m_reloadLock); auto profileIter = m_ec2MetadataConfigLoader->GetProfiles().find(Aws::Config::INSTANCE_PROFILE_KEY); + AWSCredentials credentials; if(profileIter != m_ec2MetadataConfigLoader->GetProfiles().end()) { - return profileIter->second.GetCredentials(); + credentials = profileIter->second.GetCredentials(); } - return AWSCredentials(); + return ((credentials.GetExpiration() - Aws::Utils::DateTime::Now()).count() < AWS_CREDENTIAL_PROVIDER_EXPIRATION_GRACE_PERIOD); } void InstanceProfileCredentialsProvider::Reload() { - AWS_LOGSTREAM_INFO(INSTANCE_LOG_TAG, "Credentials have expired attempting to repull from EC2 Metadata Service."); - m_ec2MetadataConfigLoader->Load(); - AWSCredentialsProvider::Reload(); + AWS_LOGSTREAM_INFO(INSTANCE_LOG_TAG, "Credentials have expired attempting to re-pull from EC2 Metadata Service."); + if (m_ec2MetadataConfigLoader) { + m_ec2MetadataConfigLoader->Load(); + AWSCredentialsProvider::Reload(); + } else { + AWS_LOGSTREAM_ERROR(INSTANCE_LOG_TAG, "EC2 Metadata config loader is a nullptr"); + } } void InstanceProfileCredentialsProvider::RefreshIfExpired() { AWS_LOGSTREAM_DEBUG(INSTANCE_LOG_TAG, "Checking if latest credential pull has expired."); ReaderLockGuard guard(m_reloadLock); - if (!IsTimeToRefresh(m_loadFrequencyMs)) - { - return; - } + auto profileIter = m_ec2MetadataConfigLoader->GetProfiles().find(Aws::Config::INSTANCE_PROFILE_KEY); + AWSCredentials credentials; - guard.UpgradeToWriterLock(); - if (!IsTimeToRefresh(m_loadFrequencyMs)) // double-checked lock to avoid refreshing twice + if(profileIter != m_ec2MetadataConfigLoader->GetProfiles().end()) { - return; + credentials = profileIter->second.GetCredentials(); + + if (!credentials.IsEmpty() && !IsTimeToRefresh(m_loadFrequencyMs) && !ExpiresSoon()) + { + return; + } + + guard.UpgradeToWriterLock(); + if (!credentials.IsEmpty() && !IsTimeToRefresh(m_loadFrequencyMs) && !ExpiresSoon()) // double-checked lock to avoid refreshing twice + { + return; + } } + Reload(); } @@ -306,12 +341,17 @@ AWSCredentials TaskRoleCredentialsProvider::GetAWSCredentials() bool TaskRoleCredentialsProvider::ExpiresSoon() const { - return ((m_credentials.GetExpiration() - Aws::Utils::DateTime::Now()).count() < EXPIRATION_GRACE_PERIOD); + return ((m_credentials.GetExpiration() - Aws::Utils::DateTime::Now()).count() < AWS_CREDENTIAL_PROVIDER_EXPIRATION_GRACE_PERIOD); } void TaskRoleCredentialsProvider::Reload() { - AWS_LOGSTREAM_INFO(TASK_ROLE_LOG_TAG, "Credentials have expired or will expire, attempting to repull from ECS IAM Service."); + AWS_LOGSTREAM_INFO(TASK_ROLE_LOG_TAG, "Credentials have expired or will expire, attempting to re-pull from ECS IAM Service."); + if (!m_ecsCredentialsClient) + { + AWS_LOGSTREAM_ERROR(INSTANCE_LOG_TAG, "ECS Credentials client is a nullptr"); + return; + } auto credentialsStr = m_ecsCredentialsClient->GetECSCredentials(); if (credentialsStr.empty()) return; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp index 8b019a16642..403bd380c46 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp @@ -77,3 +77,9 @@ DefaultAWSCredentialsProviderChain::DefaultAWSCredentialsProviderChain() : AWSCr AWS_LOGSTREAM_INFO(DefaultCredentialsProviderChainTag, "Added EC2 metadata service credentials provider to the provider chain."); } } + +DefaultAWSCredentialsProviderChain::DefaultAWSCredentialsProviderChain(const DefaultAWSCredentialsProviderChain& chain) { + for (const auto& provider: chain.GetProviders()) { + AddProvider(provider); + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/SSOCredentialsProvider.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/SSOCredentialsProvider.cpp index e8f780762ea..9576e9d9999 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/SSOCredentialsProvider.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/SSOCredentialsProvider.cpp @@ -33,7 +33,8 @@ SSOCredentialsProvider::SSOCredentialsProvider() : m_profileToUse(GetConfigProfi AWS_LOGSTREAM_INFO(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Setting sso credentials provider to read config from " << m_profileToUse); } -SSOCredentialsProvider::SSOCredentialsProvider(const Aws::String& profile) : m_profileToUse(profile) +SSOCredentialsProvider::SSOCredentialsProvider(const Aws::String& profile) : m_profileToUse(profile), + m_bearerTokenProvider(profile) { AWS_LOGSTREAM_INFO(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Setting sso credentials provider to read config from " << m_profileToUse); } @@ -48,15 +49,24 @@ AWSCredentials SSOCredentialsProvider::GetAWSCredentials() void SSOCredentialsProvider::Reload() { auto profile = Aws::Config::GetCachedConfigProfile(m_profileToUse); - - Aws::String hashedStartUrl = Aws::Utils::HashingUtils::HexEncode(Aws::Utils::HashingUtils::CalculateSHA1(profile.GetSsoStartUrl())); - auto profileDirectory = ProfileConfigFileAWSCredentialsProvider::GetProfileDirectory(); - Aws::StringStream ssToken; - ssToken << profileDirectory; - ssToken << PATH_DELIM << "sso" << PATH_DELIM << "cache" << PATH_DELIM << hashedStartUrl << ".json"; - auto ssoTokenPath = ssToken.str(); - AWS_LOGSTREAM_DEBUG(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Loading token from: " << ssoTokenPath) - Aws::String accessToken = LoadAccessTokenFile(ssoTokenPath); + const auto accessToken = [&]() -> Aws::String { + // If we have an SSO Session set, use the refreshed token. + if (profile.IsSsoSessionSet()) { + m_ssoRegion = profile.GetSsoSession().GetSsoRegion(); + auto token = m_bearerTokenProvider.GetAWSBearerToken(); + m_expiresAt = token.GetExpiration(); + return token.GetToken(); + } + Aws::String hashedStartUrl = Aws::Utils::HashingUtils::HexEncode(Aws::Utils::HashingUtils::CalculateSHA1(profile.GetSsoStartUrl())); + auto profileDirectory = ProfileConfigFileAWSCredentialsProvider::GetProfileDirectory(); + Aws::StringStream ssToken; + ssToken << profileDirectory; + ssToken << PATH_DELIM << "sso" << PATH_DELIM << "cache" << PATH_DELIM << hashedStartUrl << ".json"; + auto ssoTokenPath = ssToken.str(); + AWS_LOGSTREAM_DEBUG(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Loading token from: " << ssoTokenPath) + m_ssoRegion = profile.GetSsoRegion(); + return LoadAccessTokenFile(ssoTokenPath); + }(); if (accessToken.empty()) { AWS_LOGSTREAM_TRACE(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Access token for SSO not available"); return; @@ -72,7 +82,7 @@ void SSOCredentialsProvider::Reload() Aws::Client::ClientConfiguration config; config.scheme = Aws::Http::Scheme::HTTPS; - config.region = profile.GetSsoRegion(); + config.region = m_ssoRegion; AWS_LOGSTREAM_DEBUG(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Passing config to client for region: " << m_ssoRegion); Aws::Vector<Aws::String> retryableErrors; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/STSCredentialsProvider.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/STSCredentialsProvider.cpp index 3f48c9e0c7d..b861e6132b1 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/STSCredentialsProvider.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/STSCredentialsProvider.cpp @@ -30,6 +30,8 @@ using Aws::Utils::Threading::ReaderLockGuard; using Aws::Utils::Threading::WriterLockGuard; static const char STS_ASSUME_ROLE_WEB_IDENTITY_LOG_TAG[] = "STSAssumeRoleWithWebIdentityCredentialsProvider"; +static const int STS_CREDENTIAL_PROVIDER_EXPIRATION_GRACE_PERIOD = 5 * 1000; + STSAssumeRoleWebIdentityCredentialsProvider::STSAssumeRoleWebIdentityCredentialsProvider() : m_initialized(false) { @@ -145,16 +147,21 @@ void STSAssumeRoleWebIdentityCredentialsProvider::Reload() m_credentials = result.creds; } +bool STSAssumeRoleWebIdentityCredentialsProvider::ExpiresSoon() const +{ + return ((m_credentials.GetExpiration() - Aws::Utils::DateTime::Now()).count() < STS_CREDENTIAL_PROVIDER_EXPIRATION_GRACE_PERIOD); +} + void STSAssumeRoleWebIdentityCredentialsProvider::RefreshIfExpired() { ReaderLockGuard guard(m_reloadLock); - if (!m_credentials.IsExpiredOrEmpty()) + if (!m_credentials.IsEmpty() && !ExpiresSoon()) { return; } guard.UpgradeToWriterLock(); - if (!m_credentials.IsExpiredOrEmpty()) // double-checked lock to avoid refreshing twice + if (!m_credentials.IsExpiredOrEmpty() && !ExpiresSoon()) // double-checked lock to avoid refreshing twice { return; } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/DefaultBearerTokenProviderChain.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/DefaultBearerTokenProviderChain.cpp new file mode 100644 index 00000000000..16b301cd678 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/DefaultBearerTokenProviderChain.cpp @@ -0,0 +1,35 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/auth/bearer-token-provider/DefaultBearerTokenProviderChain.h> +#include <aws/core/auth/AWSBearerToken.h> +#include <aws/core/auth/bearer-token-provider/SSOBearerTokenProvider.h> +#include <aws/core/utils/logging/LogMacros.h> + + +static const char SSO_DEFAULT_BEARER_TOKEN_PROVIDER_CHAIN_LOG_TAG[] = "SSOBearerTokenProvider"; + +Aws::Auth::AWSBearerToken Aws::Auth::DefaultBearerTokenProviderChain::GetAWSBearerToken() +{ + for (auto&& bearerTokenProvider : m_providerChain) + { + if(!bearerTokenProvider) { + AWS_LOGSTREAM_FATAL(SSO_DEFAULT_BEARER_TOKEN_PROVIDER_CHAIN_LOG_TAG, + "Unexpected nullptr in DefaultBearerTokenProviderChain::m_providerChain"); + break; + } + AWSBearerToken bearerToken = bearerTokenProvider->GetAWSBearerToken(); + if(!bearerToken.IsExpiredOrEmpty()) + { + return bearerToken; + } + } + return AWSBearerToken("", Aws::Utils::DateTime(0.0)); +} + +Aws::Auth::DefaultBearerTokenProviderChain::DefaultBearerTokenProviderChain() +{ + AddProvider(Aws::MakeShared<Aws::Auth::SSOBearerTokenProvider>(SSO_DEFAULT_BEARER_TOKEN_PROVIDER_CHAIN_LOG_TAG)); +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/SSOBearerTokenProvider.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/SSOBearerTokenProvider.cpp new file mode 100644 index 00000000000..b55131e340d --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/SSOBearerTokenProvider.cpp @@ -0,0 +1,244 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + + +#include <aws/core/auth/bearer-token-provider/SSOBearerTokenProvider.h> +#include <aws/core/auth/AWSCredentialsProvider.h> +#include <aws/core/config/AWSProfileConfigLoader.h> +#include <aws/core/internal/AWSHttpResourceClient.h> +#include <aws/core/platform/Environment.h> +#include <aws/core/platform/FileSystem.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/utils/FileSystemUtils.h> +#include <aws/core/client/SpecifiedRetryableErrorsRetryStrategy.h> +#include <aws/core/utils/HashingUtils.h> +#include <aws/core/utils/json/JsonSerializer.h> + +using namespace Aws::Auth; + +using Aws::Utils::Threading::ReaderLockGuard; + + +static const char SSO_BEARER_TOKEN_PROVIDER_LOG_TAG[] = "SSOBearerTokenProvider"; +static const char SSO_GRANT_TYPE[] = "refresh_token"; + +const size_t SSOBearerTokenProvider::REFRESH_WINDOW_BEFORE_EXPIRATION_S = 600; +const size_t SSOBearerTokenProvider::REFRESH_ATTEMPT_INTERVAL_S = 30; + +SSOBearerTokenProvider::SSOBearerTokenProvider() + : m_profileToUse(Aws::Auth::GetConfigProfileName()), + m_lastUpdateAttempt((int64_t) 0) +{ + AWS_LOGSTREAM_INFO(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Setting sso bearerToken provider to read config from " << m_profileToUse); +} + +SSOBearerTokenProvider::SSOBearerTokenProvider(const Aws::String& awsProfile) + : m_profileToUse(awsProfile), + m_lastUpdateAttempt((int64_t) 0) +{ + AWS_LOGSTREAM_INFO(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Setting sso bearerToken provider to read config from " << m_profileToUse); +} + +AWSBearerToken SSOBearerTokenProvider::GetAWSBearerToken() +{ + Aws::Utils::Threading::ReaderLockGuard guard(m_reloadLock); + if(m_token.IsEmpty()) + { + Reload(); + } + if(!m_token.IsEmpty()) + { + const Aws::Utils::DateTime now = Aws::Utils::DateTime::Now(); + if (now >= m_token.GetExpiration() - std::chrono::seconds(REFRESH_WINDOW_BEFORE_EXPIRATION_S) && + m_lastUpdateAttempt + std::chrono::seconds(REFRESH_ATTEMPT_INTERVAL_S) < now) + { + guard.UpgradeToWriterLock(); + RefreshFromSso(); + } + } + + if(m_token.IsExpiredOrEmpty()) + { + /* If a loaded token has expired and has insufficient metadata to perform a refresh the SSO token + provider must raise an exception that the token has expired and cannot be refreshed. + Error logging and returning an empty object instead because of disabled exceptions and poor legacy API design. */ + AWS_LOGSTREAM_ERROR(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "SSOBearerTokenProvider is unable to provide a token"); + return Aws::Auth::AWSBearerToken("", Aws::Utils::DateTime(0.0)); + } + return m_token; +} + +void SSOBearerTokenProvider::Reload() +{ + CachedSsoToken cachedSsoToken = LoadAccessTokenFile(); + if(cachedSsoToken.accessToken.empty()) { + AWS_LOGSTREAM_TRACE(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Access token for SSO not available"); + return; + } + const Aws::Utils::DateTime now = Aws::Utils::DateTime::Now(); + if(cachedSsoToken.expiresAt < now) { + AWS_LOGSTREAM_ERROR(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Cached Token is already expired at " << cachedSsoToken.expiresAt.ToGmtString(Aws::Utils::DateFormat::ISO_8601)); + return; + } + + m_token.SetToken(cachedSsoToken.accessToken); + m_token.SetExpiration(cachedSsoToken.expiresAt); +} + +void SSOBearerTokenProvider::RefreshFromSso() +{ + CachedSsoToken cachedSsoToken = LoadAccessTokenFile(); + + if(!m_client) + { + Aws::Client::ClientConfiguration config; + config.scheme = Aws::Http::Scheme::HTTPS; + /* The SSO token provider must not resolve if any SSO configuration values are present directly on the profile + * instead of an `sso-session` section. The SSO token provider must ignore these configuration values if these + * values are present directly on the profile instead of an `sso-session` section. */ + // config.region = m_profile.GetSsoRegion(); // <- intentionally not used per comment above + config.region = cachedSsoToken.region; + m_client = Aws::MakeUnique<Aws::Internal::SSOCredentialsClient>(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, config); + } + + Aws::Internal::SSOCredentialsClient::SSOCreateTokenRequest ssoCreateTokenRequest; + ssoCreateTokenRequest.clientId = cachedSsoToken.clientId; + ssoCreateTokenRequest.clientSecret = cachedSsoToken.clientSecret; + ssoCreateTokenRequest.grantType = SSO_GRANT_TYPE; + ssoCreateTokenRequest.refreshToken = cachedSsoToken.refreshToken; + + if(!m_client) { + AWS_LOGSTREAM_FATAL(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Unexpected nullptr in SSOBearerTokenProvider::m_client"); + return; + } + Aws::Internal::SSOCredentialsClient::SSOCreateTokenResult result = m_client->CreateToken(ssoCreateTokenRequest); + if(!result.accessToken.empty()) + { + cachedSsoToken.accessToken = result.accessToken; + cachedSsoToken.expiresAt = Aws::Utils::DateTime::Now() + std::chrono::seconds(result.expiresIn); + if(!result.refreshToken.empty()) { + cachedSsoToken.refreshToken = result.refreshToken; + } + if(!result.clientId.empty()) { + cachedSsoToken.clientId = result.clientId; + } + } + + if(WriteAccessTokenFile(cachedSsoToken)) + { + m_token.SetToken(cachedSsoToken.accessToken); + m_token.SetExpiration(cachedSsoToken.expiresAt); + } + +} + +SSOBearerTokenProvider::CachedSsoToken SSOBearerTokenProvider::LoadAccessTokenFile() const +{ + SSOBearerTokenProvider::CachedSsoToken retValue; + + const Aws::Config::Profile& profile = Aws::Config::GetCachedConfigProfile(m_profileToUse); + if(!profile.IsSsoSessionSet()) { + AWS_LOGSTREAM_ERROR(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "SSOBearerTokenProvider set to use a profile " << m_profileToUse << " without a sso_session. Unable to load cached token."); + return retValue; + } + + Aws::String hashedStartUrl = Aws::Utils::HashingUtils::HexEncode(Aws::Utils::HashingUtils::CalculateSHA1(profile.GetSsoSession().GetName())); + Aws::String profileDirectory = ProfileConfigFileAWSCredentialsProvider::GetProfileDirectory(); + Aws::StringStream ssToken; + ssToken << profileDirectory; + ssToken << Aws::FileSystem::PATH_DELIM << "sso" << Aws::FileSystem::PATH_DELIM << "cache" << Aws::FileSystem::PATH_DELIM << hashedStartUrl << ".json"; + auto ssoAccessTokenPath = ssToken.str(); + AWS_LOGSTREAM_DEBUG(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Preparing to load token from: " << ssoAccessTokenPath); + + Aws::IFStream inputFile(ssoAccessTokenPath.c_str()); + if(inputFile) + { + AWS_LOGSTREAM_DEBUG(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Reading content from token file: " << ssoAccessTokenPath); + + Aws::Utils::Json::JsonValue tokenDoc(inputFile); + if (!tokenDoc.WasParseSuccessful()) + { + AWS_LOGSTREAM_ERROR(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Failed to parse token file: " << ssoAccessTokenPath); + return retValue; + } + Utils::Json::JsonView tokenView(tokenDoc); + + retValue.accessToken = tokenView.GetString("accessToken"); + retValue.expiresAt = Aws::Utils::DateTime(tokenView.GetString("expiresAt"), Aws::Utils::DateFormat::ISO_8601); + retValue.refreshToken = tokenView.GetString("refreshToken"); + retValue.clientId = tokenView.GetString("clientId"); + retValue.clientSecret = tokenView.GetString("clientSecret"); + retValue.registrationExpiresAt = Aws::Utils::DateTime(tokenView.GetString("registrationExpiresAt"), Aws::Utils::DateFormat::ISO_8601); + retValue.region = tokenView.GetString("region"); + retValue.startUrl = tokenView.GetString("startUrl"); + + return retValue; + } + else + { + AWS_LOGSTREAM_INFO(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Unable to open token file on path: " << ssoAccessTokenPath); + return retValue; + } +} + +bool SSOBearerTokenProvider::WriteAccessTokenFile(const CachedSsoToken& token) const +{ + const Aws::Config::Profile& profile = Aws::Config::GetCachedConfigProfile(m_profileToUse); + if(!profile.IsSsoSessionSet()) { + AWS_LOGSTREAM_ERROR(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "SSOBearerTokenProvider set to use a profile " + << m_profileToUse << " without a sso_session. Unable to write a cached token."); + return false; + } + + Aws::String hashedStartUrl = Aws::Utils::HashingUtils::HexEncode(Aws::Utils::HashingUtils::CalculateSHA1(profile.GetSsoSession().GetName())); + Aws::String profileDirectory = ProfileConfigFileAWSCredentialsProvider::GetProfileDirectory(); + Aws::StringStream ssToken; + ssToken << profileDirectory; + ssToken << Aws::FileSystem::PATH_DELIM << "sso" << Aws::FileSystem::PATH_DELIM << "cache" << Aws::FileSystem::PATH_DELIM << hashedStartUrl << ".json"; + auto ssoAccessTokenPath = ssToken.str(); + AWS_LOGSTREAM_DEBUG(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Preparing to write token to: " << ssoAccessTokenPath); + + Aws::OFStream outputFileStream(ssoAccessTokenPath.c_str(), std::ios_base::out | std::ios_base::trunc); + if(outputFileStream && outputFileStream.good()) + { + AWS_LOGSTREAM_DEBUG(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Writing content to token file: " << ssoAccessTokenPath); + + Aws::Utils::Json::JsonValue cachedTokenDoc; + if(!token.accessToken.empty()) { + cachedTokenDoc.WithString("accessToken", token.accessToken); + } + if(token.expiresAt != 0.0) { + cachedTokenDoc.WithString("expiresAt", token.expiresAt.ToGmtString(Aws::Utils::DateFormat::ISO_8601)); + } + if(!token.refreshToken.empty()) { + cachedTokenDoc.WithString("refreshToken", token.refreshToken); + } + if(!token.clientId.empty()) { + cachedTokenDoc.WithString("clientId", token.clientId); + } + if(!token.clientSecret.empty()) { + cachedTokenDoc.WithString("clientSecret", token.clientSecret); + } + if(token.registrationExpiresAt != 0.0) { + cachedTokenDoc.WithString("registrationExpiresAt", token.registrationExpiresAt.ToGmtString(Aws::Utils::DateFormat::ISO_8601)); + } + if(!token.region.empty()) { + cachedTokenDoc.WithString("region", token.region); + } + if(!token.startUrl.empty()) { + cachedTokenDoc.WithString("startUrl", token.startUrl); + } + + const Aws::String& resultingJsonStr = cachedTokenDoc.View().WriteReadable();; + outputFileStream << resultingJsonStr; + + return outputFileStream.good(); + } + else + { + AWS_LOGSTREAM_INFO(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Unable to open token file on path for writing: " << ssoAccessTokenPath); + return false; + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/BearerTokenAuthSignerProvider.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/BearerTokenAuthSignerProvider.cpp new file mode 100644 index 00000000000..9bb9c5edae7 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/BearerTokenAuthSignerProvider.cpp @@ -0,0 +1,46 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/auth/signer-provider/BearerTokenAuthSignerProvider.h> + +#include <aws/core/auth/signer/AWSNullSigner.h> + +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/auth/AWSCredentialsProvider.h> +#include <aws/core/utils/memory/stl/AWSAllocator.h> + +const char BEARER_TOKEN_AUTH_SIGNER_PROVIDER_ALLOC_TAG[] = "BearerTokenAuthSignerProvider"; + +using namespace Aws::Auth; + +BearerTokenAuthSignerProvider::BearerTokenAuthSignerProvider(const std::shared_ptr<Aws::Auth::AWSBearerTokenProviderBase> bearerTokenProvider) +{ + m_signers.emplace_back(Aws::MakeShared<Aws::Client::AWSAuthBearerSigner>(BEARER_TOKEN_AUTH_SIGNER_PROVIDER_ALLOC_TAG, bearerTokenProvider)); + m_signers.emplace_back(Aws::MakeShared<Aws::Client::AWSNullSigner>(BEARER_TOKEN_AUTH_SIGNER_PROVIDER_ALLOC_TAG)); +} + +std::shared_ptr<Aws::Client::AWSAuthSigner> BearerTokenAuthSignerProvider::GetSigner(const Aws::String& signerName) const +{ + for(const auto& signer : m_signers) + { + if(!signer) { + AWS_LOGSTREAM_FATAL(BEARER_TOKEN_AUTH_SIGNER_PROVIDER_ALLOC_TAG, "Unexpected nullptr in BearerTokenAuthSignerProvider::m_signers"); + break; + } + if(signer->GetName() == signerName) + { + return signer; + } + } + AWS_LOGSTREAM_ERROR(BEARER_TOKEN_AUTH_SIGNER_PROVIDER_ALLOC_TAG, "Request's signer: '" << signerName << "' is not found in the signer's map."); + assert(false); + return nullptr; +} + +void BearerTokenAuthSignerProvider::AddSigner(std::shared_ptr<Aws::Client::AWSAuthSigner>& signer) +{ + assert(signer); + m_signers.emplace_back(signer); +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSignerProvider.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/DefaultAuthSignerProvider.cpp index 31fd6c006ba..fb7e0cfa406 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSignerProvider.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/DefaultAuthSignerProvider.cpp @@ -2,10 +2,14 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ + +#include <aws/core/auth/signer-provider/DefaultAuthSignerProvider.h> + +#include <aws/core/auth/signer/AWSAuthEventStreamV4Signer.h> +#include <aws/core/auth/signer/AWSNullSigner.h> + #include <aws/core/utils/logging/LogMacros.h> -#include <aws/core/auth/AWSAuthSignerProvider.h> -#include <aws/core/auth/AWSAuthSigner.h> #include <aws/core/auth/AWSCredentialsProvider.h> #include <aws/core/utils/memory/stl/AWSAllocator.h> @@ -14,9 +18,10 @@ const char CLASS_TAG[] = "AuthSignerProvider"; using namespace Aws::Auth; DefaultAuthSignerProvider::DefaultAuthSignerProvider(const std::shared_ptr<AWSCredentialsProvider>& credentialsProvider, - const Aws::String& serviceName, const Aws::String& region) + const Aws::String& serviceName, const Aws::String& region, Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy signingPolicy, bool urlEscapePath) { - m_signers.emplace_back(Aws::MakeShared<Aws::Client::AWSAuthV4Signer>(CLASS_TAG, credentialsProvider, serviceName.c_str(), region)); + m_signers.emplace_back(Aws::MakeShared<Aws::Client::AWSAuthV4Signer>(CLASS_TAG, credentialsProvider, serviceName.c_str(), region, signingPolicy, urlEscapePath, AWSSigningAlgorithm::SIGV4)); + m_signers.emplace_back(Aws::MakeShared<Aws::Client::AWSAuthV4Signer>(CLASS_TAG, credentialsProvider, serviceName.c_str(), region, signingPolicy, urlEscapePath, AWSSigningAlgorithm::ASYMMETRIC_SIGV4)); m_signers.emplace_back(Aws::MakeShared<Aws::Client::AWSAuthEventStreamV4Signer>(CLASS_TAG, credentialsProvider, serviceName.c_str(), region)); m_signers.emplace_back(Aws::MakeShared<Aws::Client::AWSNullSigner>(CLASS_TAG)); } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthBearerSigner.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthBearerSigner.cpp new file mode 100644 index 00000000000..ff14c8a3712 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthBearerSigner.cpp @@ -0,0 +1,50 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/auth/signer/AWSAuthBearerSigner.h> +#include <aws/core/auth/bearer-token-provider/AWSBearerTokenProviderBase.h> + +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/http/HttpRequest.h> + +namespace Aws +{ + namespace Auth + { + const char BEARER_SIGNER[] = "Bearer"; + } + + namespace Client + { + static const char LOGGING_TAG[] = "AWSAuthBearerSigner"; + static const char AUTHORIZATION_HEADER[] = "authorization"; + + bool AWSAuthBearerSigner::SignRequest(Aws::Http::HttpRequest& ioRequest) const + { + if(Aws::Http::Scheme::HTTPS != ioRequest.GetUri().GetScheme()) + { + // Clients MUST always use TLS (https) or equivalent transport security + // when making requests with bearer tokens. + // https://datatracker.ietf.org/doc/html/rfc6750 + AWS_LOGSTREAM_ERROR(LOGGING_TAG, "HTTPS scheme must be used with a bearer token authorization"); + return false; + } + if(!m_bearerTokenProvider) + { + AWS_LOGSTREAM_FATAL(LOGGING_TAG, "Unexpected nullptr AWSAuthBearerSigner::m_bearerTokenProvider"); + return false; + } + const Aws::Auth::AWSBearerToken& token = m_bearerTokenProvider->GetAWSBearerToken(); + if(token.IsExpiredOrEmpty()) + { + AWS_LOGSTREAM_ERROR(LOGGING_TAG, "Invalid bearer token to use: expired or empty"); + return false; + } + + ioRequest.SetHeaderValue(AUTHORIZATION_HEADER, "Bearer " + token.GetToken()); + return true; + } + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthEventStreamV4Signer.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthEventStreamV4Signer.cpp new file mode 100644 index 00000000000..195e83a751a --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthEventStreamV4Signer.cpp @@ -0,0 +1,320 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/auth/signer/AWSAuthEventStreamV4Signer.h> +#include <aws/core/auth/signer/AWSAuthSignerCommon.h> +#include <aws/core/auth/signer/AWSAuthSignerHelper.h> + +#include <aws/core/auth/AWSCredentialsProvider.h> +#include <aws/core/http/HttpRequest.h> +#include <aws/core/utils/DateTime.h> +#include <aws/core/utils/HashingUtils.h> +#include <aws/core/utils/Outcome.h> +#include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/utils/memory/AWSMemory.h> +#include <aws/core/utils/crypto/Sha256HMAC.h> +#include <aws/core/utils/stream/PreallocatedStreamBuf.h> +#include <aws/core/utils/event/EventMessage.h> +#include <aws/core/utils/event/EventHeader.h> + +#include <aws/crt/auth/Credentials.h> +#include <aws/crt/http/HttpRequestResponse.h> + +#include <iomanip> +#include <cstring> + +using namespace Aws; +using namespace Aws::Client; +using namespace Aws::Auth; +using namespace Aws::Http; +using namespace Aws::Utils; +using namespace Aws::Utils::Logging; + +static const char* EVENT_STREAM_CONTENT_SHA256 = "STREAMING-AWS4-HMAC-SHA256-EVENTS"; +static const char* EVENT_STREAM_PAYLOAD = "AWS4-HMAC-SHA256-PAYLOAD"; +static const char* v4StreamingLogTag = "AWSAuthEventStreamV4Signer"; + +namespace Aws +{ + namespace Auth + { + const char EVENTSTREAM_SIGV4_SIGNER[] = "EventStreamSignatureV4"; + const char EVENTSTREAM_SIGNATURE_HEADER[] = ":chunk-signature"; + const char EVENTSTREAM_DATE_HEADER[] = ":date"; + } +} + +AWSAuthEventStreamV4Signer::AWSAuthEventStreamV4Signer(const std::shared_ptr<Auth::AWSCredentialsProvider>& + credentialsProvider, const char* serviceName, const Aws::String& region) : + m_serviceName(serviceName), + m_region(region), + m_credentialsProvider(credentialsProvider) +{ + + m_unsignedHeaders.emplace_back(Aws::Auth::AWSAuthHelper::X_AMZN_TRACE_ID); + m_unsignedHeaders.emplace_back(USER_AGENT_HEADER); +} + +bool AWSAuthEventStreamV4Signer::SignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, bool /* signBody */) const +{ + AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials(); + + //don't sign anonymous requests + if (credentials.GetAWSAccessKeyId().empty() || credentials.GetAWSSecretKey().empty()) + { + return true; + } + + if (!credentials.GetSessionToken().empty()) + { + request.SetAwsSessionToken(credentials.GetSessionToken()); + } + + request.SetHeaderValue(Aws::Auth::AWSAuthHelper::X_AMZ_CONTENT_SHA256, EVENT_STREAM_CONTENT_SHA256); + + //calculate date header to use in internal signature (this also goes into date header). + DateTime now = GetSigningTimestamp(); + Aws::String dateHeaderValue = now.ToGmtString(DateFormat::ISO_8601_BASIC); + request.SetHeaderValue(AWS_DATE_HEADER, dateHeaderValue); + + Aws::StringStream headersStream; + Aws::StringStream signedHeadersStream; + + for (const auto& header : Aws::Auth::AWSAuthHelper::CanonicalizeHeaders(request.GetHeaders())) + { + if(ShouldSignHeader(header.first)) + { + headersStream << header.first.c_str() << ":" << header.second.c_str() << Aws::Auth::AWSAuthHelper::NEWLINE; + signedHeadersStream << header.first.c_str() << ";"; + } + } + + Aws::String canonicalHeadersString = headersStream.str(); + AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Canonical Header String: " << canonicalHeadersString); + + //calculate signed headers parameter + Aws::String signedHeadersValue = signedHeadersStream.str(); + //remove that last semi-colon + if (!signedHeadersValue.empty()) + { + signedHeadersValue.pop_back(); + } + + AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Signed Headers value:" << signedHeadersValue); + + //generate generalized canonicalized request string. + Aws::String canonicalRequestString = Aws::Auth::AWSAuthHelper::CanonicalizeRequestSigningString(request, true/* m_urlEscapePath */); + + //append v4 stuff to the canonical request string. + canonicalRequestString.append(canonicalHeadersString); + canonicalRequestString.append(Aws::Auth::AWSAuthHelper::NEWLINE); + canonicalRequestString.append(signedHeadersValue); + canonicalRequestString.append(Aws::Auth::AWSAuthHelper::NEWLINE); + canonicalRequestString.append(EVENT_STREAM_CONTENT_SHA256); + + AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Canonical Request String: " << canonicalRequestString); + + //now compute sha256 on that request string + auto hashResult = m_hash.Calculate(canonicalRequestString); + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to hash (sha256) request string"); + AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "The request string is: \"" << canonicalRequestString << "\""); + return false; + } + + auto sha256Digest = hashResult.GetResult(); + Aws::String canonicalRequestHash = HashingUtils::HexEncode(sha256Digest); + Aws::String simpleDate = now.ToGmtString(Aws::Auth::AWSAuthHelper::SIMPLE_DATE_FORMAT_STR); + + Aws::String signingRegion = region ? region : m_region; + Aws::String signingServiceName = serviceName ? serviceName : m_serviceName; + Aws::String stringToSign = GenerateStringToSign(dateHeaderValue, simpleDate, canonicalRequestHash, signingRegion, signingServiceName); + auto finalSignature = GenerateSignature(credentials, stringToSign, simpleDate, signingRegion, signingServiceName); + + Aws::StringStream ss; + ss << Aws::Auth::AWSAuthHelper::AWS_HMAC_SHA256 << " " << Aws::Auth::AWSAuthHelper::CREDENTIAL << Aws::Auth::AWSAuthHelper::EQ << credentials.GetAWSAccessKeyId() << "/" << simpleDate + << "/" << signingRegion << "/" << signingServiceName << "/" << Aws::Auth::AWSAuthHelper::AWS4_REQUEST << ", " << Aws::Auth::AWSAuthHelper::SIGNED_HEADERS << Aws::Auth::AWSAuthHelper::EQ + << signedHeadersValue << ", " << SIGNATURE << Aws::Auth::AWSAuthHelper::EQ << HashingUtils::HexEncode(finalSignature); + + auto awsAuthString = ss.str(); + AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Signing request with: " << awsAuthString); + request.SetAwsAuthorization(awsAuthString); + request.SetSigningAccessKey(credentials.GetAWSAccessKeyId()); + request.SetSigningRegion(signingRegion); + return true; +} + +// this works regardless if the current machine is Big/Little Endian +static void WriteBigEndian(Aws::String& str, uint64_t n) +{ + int shift = 56; + while(shift >= 0) + { + str.push_back((n >> shift) & 0xFF); + shift -= 8; + } +} + +bool AWSAuthEventStreamV4Signer::SignEventMessage(Event::Message& message, Aws::String& priorSignature) const +{ + using Event::EventHeaderValue; + + Aws::StringStream stringToSign; + stringToSign << EVENT_STREAM_PAYLOAD << Aws::Auth::AWSAuthHelper::NEWLINE; + const DateTime now = GetSigningTimestamp(); + const auto simpleDate = now.ToGmtString(Aws::Auth::AWSAuthHelper::SIMPLE_DATE_FORMAT_STR); + stringToSign << now.ToGmtString(DateFormat::ISO_8601_BASIC) << Aws::Auth::AWSAuthHelper::NEWLINE + << simpleDate << "/" << m_region << "/" + << m_serviceName << "/aws4_request" << Aws::Auth::AWSAuthHelper::NEWLINE << priorSignature << Aws::Auth::AWSAuthHelper::NEWLINE; + + + Aws::String nonSignatureHeaders; + nonSignatureHeaders.push_back(char(sizeof(EVENTSTREAM_DATE_HEADER) - 1)); // length of the string + nonSignatureHeaders += EVENTSTREAM_DATE_HEADER; + nonSignatureHeaders.push_back(static_cast<char>(EventHeaderValue::EventHeaderType::TIMESTAMP)); // type of the value + WriteBigEndian(nonSignatureHeaders, static_cast<uint64_t>(now.Millis())); // the value of the timestamp in big-endian + + auto hashOutcome = m_hash.Calculate(nonSignatureHeaders); + if (!hashOutcome.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to hash (sha256) non-signature headers."); + return false; + } + + const auto nonSignatureHeadersHash = hashOutcome.GetResult(); + stringToSign << HashingUtils::HexEncode(nonSignatureHeadersHash) << Aws::Auth::AWSAuthHelper::NEWLINE; + + if (message.GetEventPayload().empty()) + { + AWS_LOGSTREAM_WARN(v4StreamingLogTag, "Attempting to sign an empty message (no payload and no headers). " + "It is unlikely that this is the intended behavior."); + } + else + { + // use a preallocatedStreamBuf to avoid making a copy. + // The Hashing API requires either Aws::String or IStream as input. + // TODO: the hashing API should be accept 'unsigned char*' as input. + Utils::Stream::PreallocatedStreamBuf streamBuf(message.GetEventPayload().data(), message.GetEventPayload().size()); + Aws::IOStream payload(&streamBuf); + hashOutcome = m_hash.Calculate(payload); + + if (!hashOutcome.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to hash (sha256) non-signature headers."); + return false; + } + const auto payloadHash = hashOutcome.GetResult(); + stringToSign << HashingUtils::HexEncode(payloadHash); + AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Payload hash - " << HashingUtils::HexEncode(payloadHash)); + } + + Aws::Utils::ByteBuffer finalSignatureDigest = GenerateSignature(m_credentialsProvider->GetAWSCredentials(), stringToSign.str(), simpleDate, m_region, m_serviceName); + const auto finalSignature = HashingUtils::HexEncode(finalSignatureDigest); + AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Final computed signing hash: " << finalSignature); + priorSignature = finalSignature; + + message.InsertEventHeader(EVENTSTREAM_DATE_HEADER, EventHeaderValue(now.Millis(), EventHeaderValue::EventHeaderType::TIMESTAMP)); + message.InsertEventHeader(EVENTSTREAM_SIGNATURE_HEADER, std::move(finalSignatureDigest)); + + AWS_LOGSTREAM_INFO(v4StreamingLogTag, "Event chunk final signature - " << finalSignature); + return true; +} + +bool AWSAuthEventStreamV4Signer::ShouldSignHeader(const Aws::String& header) const +{ + return std::find(m_unsignedHeaders.cbegin(), m_unsignedHeaders.cend(), Aws::Utils::StringUtils::ToLower(header.c_str())) == m_unsignedHeaders.cend(); +} + +Aws::Utils::ByteBuffer AWSAuthEventStreamV4Signer::GenerateSignature(const AWSCredentials& credentials, const Aws::String& stringToSign, + const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const +{ + Utils::Threading::ReaderLockGuard guard(m_derivedKeyLock); + const auto& secretKey = credentials.GetAWSSecretKey(); + if (secretKey != m_currentSecretKey || simpleDate != m_currentDateStr) + { + guard.UpgradeToWriterLock(); + // double-checked lock to prevent updating twice + if (m_currentDateStr != simpleDate || m_currentSecretKey != secretKey) + { + m_currentSecretKey = secretKey; + m_currentDateStr = simpleDate; + m_derivedKey = ComputeHash(m_currentSecretKey, m_currentDateStr, region, serviceName); + } + + } + return GenerateSignature(stringToSign, m_derivedKey); +} + +Aws::Utils::ByteBuffer AWSAuthEventStreamV4Signer::GenerateSignature(const Aws::String& stringToSign, const ByteBuffer& key) const +{ + AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Final String to sign: " << stringToSign); + + Aws::StringStream ss; + + auto hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)stringToSign.c_str(), stringToSign.length()), key); + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Unable to hmac (sha256) final string"); + AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "The final string is: \"" << stringToSign << "\""); + return {}; + } + + return hashResult.GetResult(); +} + +Aws::String AWSAuthEventStreamV4Signer::GenerateStringToSign(const Aws::String& dateValue, const Aws::String& simpleDate, + const Aws::String& canonicalRequestHash, const Aws::String& region, const Aws::String& serviceName) const +{ + //generate the actual string we will use in signing the final request. + Aws::StringStream ss; + + ss << Aws::Auth::AWSAuthHelper::AWS_HMAC_SHA256 << Aws::Auth::AWSAuthHelper::NEWLINE << dateValue << Aws::Auth::AWSAuthHelper::NEWLINE << simpleDate << "/" << region << "/" + << serviceName << "/" << Aws::Auth::AWSAuthHelper::AWS4_REQUEST << Aws::Auth::AWSAuthHelper::NEWLINE << canonicalRequestHash; + + return ss.str(); +} + +Aws::Utils::ByteBuffer AWSAuthEventStreamV4Signer::ComputeHash(const Aws::String& secretKey, + const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const +{ + Aws::String signingKey(Aws::Auth::AWSAuthHelper::SIGNING_KEY); + signingKey.append(secretKey); + auto hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)simpleDate.c_str(), simpleDate.length()), + ByteBuffer((unsigned char*)signingKey.c_str(), signingKey.length())); + + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to HMAC (SHA256) date string \"" << simpleDate << "\""); + return {}; + } + + auto kDate = hashResult.GetResult(); + hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)region.c_str(), region.length()), kDate); + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to HMAC (SHA256) region string \"" << region << "\""); + return {}; + } + + auto kRegion = hashResult.GetResult(); + hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)serviceName.c_str(), serviceName.length()), kRegion); + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to HMAC (SHA256) service string \"" << m_serviceName << "\""); + return {}; + } + + auto kService = hashResult.GetResult(); + hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)Aws::Auth::AWSAuthHelper::AWS4_REQUEST, strlen(Aws::Auth::AWSAuthHelper::AWS4_REQUEST)), kService); + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Unable to HMAC (SHA256) request string"); + AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "The request string is: \"" << Aws::Auth::AWSAuthHelper::AWS4_REQUEST << "\""); + return {}; + } + return hashResult.GetResult(); +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerCommon.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerCommon.cpp new file mode 100644 index 00000000000..d26f41e6b30 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerCommon.cpp @@ -0,0 +1,14 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/auth/signer/AWSAuthSignerCommon.h> + +namespace Aws +{ +namespace Auth +{ +const char SIGNATURE[] = "Signature"; +} // namespace Auth +} // namespace Aws
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerHelper.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerHelper.cpp new file mode 100644 index 00000000000..5f7005d1da2 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerHelper.cpp @@ -0,0 +1,103 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/auth/signer/AWSAuthSignerHelper.h> +#include <aws/core/http/HttpTypes.h> + +#include <aws/core/http/HttpRequest.h> +#include <aws/core/http/URI.h> +#include <aws/core/utils/StringUtils.h> + +namespace Aws +{ +namespace Auth +{ + +const char* AWSAuthHelper::EQ = "="; +const char* AWSAuthHelper::AWS_HMAC_SHA256 = "AWS4-HMAC-SHA256"; +const char* AWSAuthHelper::AWS4_REQUEST = "aws4_request"; +const char* AWSAuthHelper::SIGNED_HEADERS = "SignedHeaders"; +const char* AWSAuthHelper::CREDENTIAL = "Credential"; +const char* AWSAuthHelper::NEWLINE = "\n"; +const char* AWSAuthHelper::X_AMZN_TRACE_ID = "x-amzn-trace-id"; +const char* AWSAuthHelper::X_AMZ_CONTENT_SHA256 = "x-amz-content-sha256"; +const char* AWSAuthHelper::SIGNING_KEY = "AWS4"; +const char* AWSAuthHelper::SIMPLE_DATE_FORMAT_STR = "%Y%m%d"; + +Aws::String Aws::Auth::AWSAuthHelper::CanonicalizeRequestSigningString(Aws::Http::HttpRequest& request, bool urlEscapePath) +{ + request.CanonicalizeRequest(); + Aws::StringStream signingStringStream; + signingStringStream << Aws::Http::HttpMethodMapper::GetNameForHttpMethod(request.GetMethod()); + + Aws::Http::URI uriCpy = request.GetUri(); + // Many AWS services do not decode the URL before calculating SignatureV4 on their end. + // This results in the signature getting calculated with a double encoded URL. + // That means we have to double encode it here for the signature to match on the service side. + if(urlEscapePath) + { + // RFC3986 is how we encode the URL before sending it on the wire. + uriCpy.SetPath(uriCpy.GetURLEncodedPathRFC3986()); + // However, SignatureV4 uses this URL encoding scheme + signingStringStream << AWSAuthHelper::NEWLINE << uriCpy.GetURLEncodedPath() << AWSAuthHelper::NEWLINE; + } + else + { + // For the services that DO decode the URL first; we don't need to double encode it. + signingStringStream << AWSAuthHelper::NEWLINE << uriCpy.GetURLEncodedPath() << AWSAuthHelper::NEWLINE; + } + + if (request.GetQueryString().find('=') != std::string::npos) + { + signingStringStream << request.GetQueryString().substr(1) << AWSAuthHelper::NEWLINE; + } + else if (request.GetQueryString().size() > 1) + { + signingStringStream << request.GetQueryString().substr(1) << "=" << AWSAuthHelper::NEWLINE; + } + else + { + signingStringStream << AWSAuthHelper::NEWLINE; + } + + return signingStringStream.str(); +} + +Aws::Http::HeaderValueCollection Aws::Auth::AWSAuthHelper::CanonicalizeHeaders(Aws::Http::HeaderValueCollection&& headers) +{ + Aws::Http::HeaderValueCollection canonicalHeaders; + for (const auto& header : headers) + { + auto trimmedHeaderName = Aws::Utils::StringUtils::Trim(header.first.c_str()); + auto trimmedHeaderValue = Aws::Utils::StringUtils::Trim(header.second.c_str()); + + //multiline gets converted to line1,line2,etc... + auto headerMultiLine = Aws::Utils::StringUtils::SplitOnLine(trimmedHeaderValue); + Aws::String headerValue = headerMultiLine.size() == 0 ? "" : headerMultiLine[0]; + + if (headerMultiLine.size() > 1) + { + for(size_t i = 1; i < headerMultiLine.size(); ++i) + { + headerValue += " "; + headerValue += Aws::Utils::StringUtils::Trim(headerMultiLine[i].c_str()); + } + } + + //duplicate spaces need to be converted to one. + Aws::String::iterator new_end = + std::unique(headerValue.begin(), headerValue.end(), + [=](char lhs, char rhs) { return (lhs == rhs) && (lhs == ' '); } + ); + headerValue.erase(new_end, headerValue.end()); + + canonicalHeaders[trimmedHeaderName] = headerValue; + } + + return canonicalHeaders; +} + +} // namespace Auth +} // namespace Aws
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthV4Signer.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthV4Signer.cpp new file mode 100644 index 00000000000..f8bfdbf8671 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthV4Signer.cpp @@ -0,0 +1,580 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/auth/signer/AWSAuthV4Signer.h> +#include <aws/core/auth/signer/AWSAuthSignerCommon.h> +#include <aws/core/auth/signer/AWSAuthSignerHelper.h> + +#include <aws/core/auth/AWSCredentialsProvider.h> +#include <aws/core/http/HttpRequest.h> +#include <aws/core/http/URI.h> +#include <aws/core/utils/DateTime.h> +#include <aws/core/utils/HashingUtils.h> +#include <aws/core/utils/Outcome.h> +#include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/utils/memory/AWSMemory.h> +#include <aws/core/utils/crypto/Sha256.h> +#include <aws/core/utils/crypto/Sha256HMAC.h> + +#include <aws/crt/auth/Credentials.h> +#include <aws/crt/http/HttpRequestResponse.h> + +#include <iomanip> +#include <cstring> + +using namespace Aws; +using namespace Aws::Client; +using namespace Aws::Auth; +using namespace Aws::Http; +using namespace Aws::Utils; +using namespace Aws::Utils::Logging; + +static const char* X_AMZ_SIGNED_HEADERS = "X-Amz-SignedHeaders"; +static const char* X_AMZ_ALGORITHM = "X-Amz-Algorithm"; +static const char* X_AMZ_CREDENTIAL = "X-Amz-Credential"; +static const char* UNSIGNED_PAYLOAD = "UNSIGNED-PAYLOAD"; +static const char* STREAMING_UNSIGNED_PAYLOAD_TRAILER = "STREAMING-UNSIGNED-PAYLOAD-TRAILER"; +static const char* X_AMZ_SIGNATURE = "X-Amz-Signature"; +static const char* USER_AGENT = "user-agent"; +static const char* EMPTY_STRING_SHA256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"; + +static const char v4LogTag[] = "AWSAuthV4Signer"; +static const char v4AsymmetricLogTag[] = "AWSAuthSymmetricV4Signer"; + +namespace Aws +{ + namespace Auth + { + const char SIGV4_SIGNER[] = "SignatureV4"; + const char ASYMMETRIC_SIGV4_SIGNER[] = "AsymmetricSignatureV4"; + } +} + +AWSAuthV4Signer::AWSAuthV4Signer(const std::shared_ptr<Auth::AWSCredentialsProvider>& credentialsProvider, const char* serviceName, + const Aws::String& region, PayloadSigningPolicy signingPolicy, bool urlEscapePath, AWSSigningAlgorithm signingAlgorithm) : + m_includeSha256HashHeader(true), + m_signingAlgorithm(signingAlgorithm), + m_credentialsProvider(credentialsProvider), + m_serviceName(serviceName), + m_region(region), + m_hash(Aws::MakeUnique<Aws::Utils::Crypto::Sha256>(v4LogTag)), + m_HMAC(Aws::MakeUnique<Aws::Utils::Crypto::Sha256HMAC>(v4LogTag)), + m_unsignedHeaders({USER_AGENT, Aws::Auth::AWSAuthHelper::X_AMZN_TRACE_ID}), + m_payloadSigningPolicy(signingPolicy), + m_urlEscapePath(urlEscapePath) +{ + //go ahead and warm up the signing cache. + ComputeHash(credentialsProvider->GetAWSCredentials().GetAWSSecretKey(), DateTime::CalculateGmtTimestampAsString(Aws::Auth::AWSAuthHelper::SIMPLE_DATE_FORMAT_STR), region, m_serviceName); +} + +AWSAuthV4Signer::~AWSAuthV4Signer() +{ + // empty destructor in .cpp file to keep from needing the implementation of (AWSCredentialsProvider, Sha256, Sha256HMAC) in the header file +} + +bool AWSAuthV4Signer::SignRequestWithSigV4a(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, + bool signBody, long long expirationTimeInSeconds, Aws::Crt::Auth::SignatureType signatureType) const +{ + AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials(); + auto crtCredentials = Aws::MakeShared<Aws::Crt::Auth::Credentials>(v4AsymmetricLogTag, + Aws::Crt::ByteCursorFromCString(credentials.GetAWSAccessKeyId().c_str()), + Aws::Crt::ByteCursorFromCString(credentials.GetAWSSecretKey().c_str()), + Aws::Crt::ByteCursorFromCString(credentials.GetSessionToken().c_str()), + credentials.GetExpiration().Seconds()); + + Aws::Crt::Auth::AwsSigningConfig awsSigningConfig; + awsSigningConfig.SetSigningAlgorithm(static_cast<Aws::Crt::Auth::SigningAlgorithm>(AWSSigningAlgorithm::ASYMMETRIC_SIGV4)); + awsSigningConfig.SetSignatureType(signatureType); + awsSigningConfig.SetRegion(region); + awsSigningConfig.SetService(serviceName); + awsSigningConfig.SetSigningTimepoint(GetSigningTimestamp().UnderlyingTimestamp()); + awsSigningConfig.SetUseDoubleUriEncode(m_urlEscapePath); + awsSigningConfig.SetShouldNormalizeUriPath(true); + awsSigningConfig.SetOmitSessionToken(false); + awsSigningConfig.SetShouldSignHeaderUserData(reinterpret_cast<void*>(const_cast<Aws::Set<Aws::String>*>(&m_unsignedHeaders))); + awsSigningConfig.SetShouldSignHeaderCallback([](const Aws::Crt::ByteCursor *name, void *user_data) { + Aws::Set<Aws::String>* unsignedHeaders = static_cast<Aws::Set<Aws::String>*>(user_data); + Aws::String headerKey(reinterpret_cast<const char*>(name->ptr), name->len); + return unsignedHeaders->find(Aws::Utils::StringUtils::ToLower(headerKey.c_str())) == unsignedHeaders->cend(); + }); + if (signatureType == Aws::Crt::Auth::SignatureType::HttpRequestViaHeaders) + { + Aws::String payloadHash(UNSIGNED_PAYLOAD); + if(signBody || request.GetUri().GetScheme() != Http::Scheme::HTTPS) + { + if (!request.GetContentBody()) + { + AWS_LOGSTREAM_DEBUG(v4AsymmetricLogTag, "Using cached empty string sha256 " << EMPTY_STRING_SHA256 << " because payload is empty."); + payloadHash = EMPTY_STRING_SHA256; + } + else + { + // The hash will be calculated from the payload during signing. + payloadHash = {}; + } + } + else + { + AWS_LOGSTREAM_DEBUG(v4AsymmetricLogTag, "Note: Http payloads are not being signed. signPayloads=" << signBody + << " http scheme=" << Http::SchemeMapper::ToString(request.GetUri().GetScheme())); + } + awsSigningConfig.SetSignedBodyValue(payloadHash.c_str()); + awsSigningConfig.SetSignedBodyHeader(m_includeSha256HashHeader ? Aws::Crt::Auth::SignedBodyHeaderType::XAmzContentSha256 : Aws::Crt::Auth::SignedBodyHeaderType::None); + } + else if (signatureType == Aws::Crt::Auth::SignatureType::HttpRequestViaQueryParams) + { + if (ServiceRequireUnsignedPayload(serviceName)) + { + awsSigningConfig.SetSignedBodyValue(UNSIGNED_PAYLOAD); + } + else + { + awsSigningConfig.SetSignedBodyValue(EMPTY_STRING_SHA256); + } + } + else + { + AWS_LOGSTREAM_ERROR(v4AsymmetricLogTag, "The signature type should be either \"HttpRequestViaHeaders\" or \"HttpRequestViaQueryParams\""); + return false; + } + awsSigningConfig.SetExpirationInSeconds(static_cast<uint64_t>(expirationTimeInSeconds)); + awsSigningConfig.SetCredentials(crtCredentials); + + std::shared_ptr<Aws::Crt::Http::HttpRequest> crtHttpRequest = request.ToCrtHttpRequest(); + + auto sigv4HttpRequestSigner = Aws::MakeShared<Aws::Crt::Auth::Sigv4HttpRequestSigner>(v4AsymmetricLogTag); + bool success = true; + sigv4HttpRequestSigner->SignRequest(crtHttpRequest, awsSigningConfig, + [&request, &success, signatureType](const std::shared_ptr<Aws::Crt::Http::HttpRequest>& signedCrtHttpRequest, int errorCode) { + success = (errorCode == AWS_ERROR_SUCCESS); + if (success) + { + if (signatureType == Aws::Crt::Auth::SignatureType::HttpRequestViaHeaders) + { + for (size_t i = 0; i < signedCrtHttpRequest->GetHeaderCount(); i++) + { + Aws::Crt::Optional<Aws::Crt::Http::HttpHeader> httpHeader = signedCrtHttpRequest->GetHeader(i); + request.SetHeaderValue(Aws::String(reinterpret_cast<const char*>(httpHeader->name.ptr), httpHeader->name.len), + Aws::String(reinterpret_cast<const char*>(httpHeader->value.ptr), httpHeader->value.len)); + } + } + else if (signatureType == Aws::Crt::Auth::SignatureType::HttpRequestViaQueryParams) + { + Aws::Http::URI newPath(reinterpret_cast<const char*>(signedCrtHttpRequest->GetPath()->ptr)); + request.GetUri().SetQueryString(newPath.GetQueryString()); + } + else + { + AWS_LOGSTREAM_ERROR(v4AsymmetricLogTag, "No action to take when signature type is neither \"HttpRequestViaHeaders\" nor \"HttpRequestViaQueryParams\""); + success = false; + } + } + else + { + AWS_LOGSTREAM_ERROR(v4AsymmetricLogTag, "Encountered internal error during signing process with AWS signature version 4 (Asymmetric):" << aws_error_str(errorCode)); + } + } + ); + return success; +} + +bool AWSAuthV4Signer::ShouldSignHeader(const Aws::String& header) const +{ + return m_unsignedHeaders.find(Aws::Utils::StringUtils::ToLower(header.c_str())) == m_unsignedHeaders.cend(); +} + +bool AWSAuthV4Signer::SignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, bool signBody) const +{ + Aws::String signingRegion = region ? region : m_region; + Aws::String signingServiceName = serviceName ? serviceName : m_serviceName; + AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials(); + + //don't sign anonymous requests + if (credentials.GetAWSAccessKeyId().empty() || credentials.GetAWSSecretKey().empty()) + { + return true; + } + + request.SetSigningAccessKey(credentials.GetAWSAccessKeyId()); + request.SetSigningRegion(signingRegion); + + Aws::String payloadHash(UNSIGNED_PAYLOAD); + switch(m_payloadSigningPolicy) + { + case PayloadSigningPolicy::Always: + signBody = true; + break; + case PayloadSigningPolicy::Never: + signBody = false; + break; + case PayloadSigningPolicy::RequestDependent: + // respect the request setting + default: + break; + } + + if (m_signingAlgorithm == AWSSigningAlgorithm::ASYMMETRIC_SIGV4) + { + // Replace m_serviceName with signingServiceName after rebasing on S3 outposts. + return SignRequestWithSigV4a(request, signingRegion.c_str(), m_serviceName.c_str(), signBody, + 0 /* expirationTimeInSeconds doesn't matter for HttpRequestViaHeaders */, Aws::Crt::Auth::SignatureType::HttpRequestViaHeaders); + } + + if (!credentials.GetSessionToken().empty()) + { + request.SetAwsSessionToken(credentials.GetSessionToken()); + } + + if(signBody || request.GetUri().GetScheme() != Http::Scheme::HTTPS) + { + payloadHash = ComputePayloadHash(request); + if (payloadHash.empty()) + { + return false; + } + if (request.GetRequestHash().second != nullptr) + { + Aws::String checksumHeaderKey = Aws::String("x-amz-checksum-") + request.GetRequestHash().first; + Aws::String checksumHeaderValue = HashingUtils::Base64Encode(request.GetRequestHash().second->Calculate(*(request.GetContentBody())).GetResult()); + request.SetHeaderValue(checksumHeaderKey, checksumHeaderValue); + request.SetRequestHash("", nullptr); + } + } + else + { + AWS_LOGSTREAM_DEBUG(v4LogTag, "Note: Http payloads are not being signed. signPayloads=" << signBody + << " http scheme=" << Http::SchemeMapper::ToString(request.GetUri().GetScheme())); + if (request.GetRequestHash().second != nullptr) + { + payloadHash = STREAMING_UNSIGNED_PAYLOAD_TRAILER; + Aws::String trailerHeaderValue = Aws::String("x-amz-checksum-") + request.GetRequestHash().first; + request.SetHeaderValue(Http::AWS_TRAILER_HEADER, trailerHeaderValue); + request.SetTransferEncoding(CHUNKED_VALUE); + request.SetHeaderValue(Http::CONTENT_ENCODING_HEADER, Http::AWS_CHUNKED_VALUE); + request.SetHeaderValue(Http::DECODED_CONTENT_LENGTH_HEADER, request.GetHeaderValue(Http::CONTENT_LENGTH_HEADER)); + request.DeleteHeader(Http::CONTENT_LENGTH_HEADER); + } + } + + if(m_includeSha256HashHeader) + { + request.SetHeaderValue(Aws::Auth::AWSAuthHelper::X_AMZ_CONTENT_SHA256, payloadHash); + } + + //calculate date header to use in internal signature (this also goes into date header). + DateTime now = GetSigningTimestamp(); + Aws::String dateHeaderValue = now.ToGmtString(DateFormat::ISO_8601_BASIC); + request.SetHeaderValue(AWS_DATE_HEADER, dateHeaderValue); + + Aws::StringStream headersStream; + Aws::StringStream signedHeadersStream; + + for (const auto& header : Aws::Auth::AWSAuthHelper::CanonicalizeHeaders(request.GetHeaders())) + { + if(ShouldSignHeader(header.first)) + { + headersStream << header.first.c_str() << ":" << header.second.c_str() << Aws::Auth::AWSAuthHelper::NEWLINE; + signedHeadersStream << header.first.c_str() << ";"; + } + } + + Aws::String canonicalHeadersString = headersStream.str(); + AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Header String: " << canonicalHeadersString); + + //calculate signed headers parameter + Aws::String signedHeadersValue = signedHeadersStream.str(); + //remove that last semi-colon + if (!signedHeadersValue.empty()) + { + signedHeadersValue.pop_back(); + } + + AWS_LOGSTREAM_DEBUG(v4LogTag, "Signed Headers value:" << signedHeadersValue); + + //generate generalized canonicalized request string. + Aws::String canonicalRequestString = Aws::Auth::AWSAuthHelper::CanonicalizeRequestSigningString(request, m_urlEscapePath); + + //append v4 stuff to the canonical request string. + canonicalRequestString.append(canonicalHeadersString); + canonicalRequestString.append(Aws::Auth::AWSAuthHelper::NEWLINE); + canonicalRequestString.append(signedHeadersValue); + canonicalRequestString.append(Aws::Auth::AWSAuthHelper::NEWLINE); + canonicalRequestString.append(payloadHash); + + AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Request String: " << canonicalRequestString); + + //now compute sha256 on that request string + auto hashResult = m_hash->Calculate(canonicalRequestString); + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to hash (sha256) request string"); + AWS_LOGSTREAM_DEBUG(v4LogTag, "The request string is: \"" << canonicalRequestString << "\""); + return false; + } + + auto sha256Digest = hashResult.GetResult(); + Aws::String canonicalRequestHash = HashingUtils::HexEncode(sha256Digest); + Aws::String simpleDate = now.ToGmtString(Aws::Auth::AWSAuthHelper::SIMPLE_DATE_FORMAT_STR); + + Aws::String stringToSign = GenerateStringToSign(dateHeaderValue, simpleDate, canonicalRequestHash, signingRegion, signingServiceName); + auto finalSignature = GenerateSignature(credentials, stringToSign, simpleDate, signingRegion, signingServiceName); + + Aws::StringStream ss; + ss << Aws::Auth::AWSAuthHelper::AWS_HMAC_SHA256 << " " << Aws::Auth::AWSAuthHelper::CREDENTIAL << Aws::Auth::AWSAuthHelper::EQ << credentials.GetAWSAccessKeyId() << "/" << simpleDate + << "/" << signingRegion << "/" << signingServiceName << "/" << Aws::Auth::AWSAuthHelper::AWS4_REQUEST << ", " << Aws::Auth::AWSAuthHelper::SIGNED_HEADERS << Aws::Auth::AWSAuthHelper::EQ + << signedHeadersValue << ", " << SIGNATURE << Aws::Auth::AWSAuthHelper::EQ << finalSignature; + + auto awsAuthString = ss.str(); + AWS_LOGSTREAM_DEBUG(v4LogTag, "Signing request with: " << awsAuthString); + request.SetAwsAuthorization(awsAuthString); + return true; +} + +bool AWSAuthV4Signer::PresignRequest(Aws::Http::HttpRequest& request, long long expirationTimeInSeconds) const +{ + return PresignRequest(request, m_region.c_str(), expirationTimeInSeconds); +} + +bool AWSAuthV4Signer::PresignRequest(Aws::Http::HttpRequest& request, const char* region, long long expirationInSeconds) const +{ + return PresignRequest(request, region, m_serviceName.c_str(), expirationInSeconds); +} + +bool AWSAuthV4Signer::PresignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, long long expirationTimeInSeconds) const +{ + Aws::String signingRegion = region ? region : m_region; + Aws::String signingServiceName = serviceName ? serviceName : m_serviceName; + AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials(); + + //don't sign anonymous requests + if (credentials.GetAWSAccessKeyId().empty() || credentials.GetAWSSecretKey().empty()) + { + return true; + } + + if (m_signingAlgorithm == AWSSigningAlgorithm::ASYMMETRIC_SIGV4) + { + return SignRequestWithSigV4a(request, signingRegion.c_str(), signingServiceName.c_str(), false /* signBody doesn't matter for HttpRequestViaHeaders */, + expirationTimeInSeconds, Aws::Crt::Auth::SignatureType::HttpRequestViaQueryParams); + } + + Aws::StringStream intConversionStream; + intConversionStream << expirationTimeInSeconds; + request.AddQueryStringParameter(Http::X_AMZ_EXPIRES_HEADER, intConversionStream.str()); + + if (!credentials.GetSessionToken().empty()) + { + request.AddQueryStringParameter(Http::AWS_SECURITY_TOKEN, credentials.GetSessionToken()); + } + + //calculate date header to use in internal signature (this also goes into date header). + DateTime now = GetSigningTimestamp(); + Aws::String dateQueryValue = now.ToGmtString(DateFormat::ISO_8601_BASIC); + request.AddQueryStringParameter(Http::AWS_DATE_HEADER, dateQueryValue); + + Aws::StringStream headersStream; + Aws::StringStream signedHeadersStream; + for (const auto& header : Aws::Auth::AWSAuthHelper::CanonicalizeHeaders(request.GetHeaders())) + { + if(ShouldSignHeader(header.first)) + { + headersStream << header.first.c_str() << ":" << header.second.c_str() << Aws::Auth::AWSAuthHelper::NEWLINE; + signedHeadersStream << header.first.c_str() << ";"; + } + } + + Aws::String canonicalHeadersString = headersStream.str(); + AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Header String: " << canonicalHeadersString); + + //calculate signed headers parameter + Aws::String signedHeadersValue(signedHeadersStream.str()); + //remove that last semi-colon + if (!signedHeadersValue.empty()) + { + signedHeadersValue.pop_back(); + } + + request.AddQueryStringParameter(X_AMZ_SIGNED_HEADERS, signedHeadersValue); + AWS_LOGSTREAM_DEBUG(v4LogTag, "Signed Headers value: " << signedHeadersValue); + + Aws::StringStream ss; + Aws::String simpleDate = now.ToGmtString(Aws::Auth::AWSAuthHelper::SIMPLE_DATE_FORMAT_STR); + ss << credentials.GetAWSAccessKeyId() << "/" << simpleDate + << "/" << signingRegion << "/" << signingServiceName << "/" << Aws::Auth::AWSAuthHelper::AWS4_REQUEST; + + request.AddQueryStringParameter(X_AMZ_ALGORITHM, Aws::Auth::AWSAuthHelper::AWS_HMAC_SHA256); + request.AddQueryStringParameter(X_AMZ_CREDENTIAL, ss.str()); + ss.str(""); + + request.SetSigningAccessKey(credentials.GetAWSAccessKeyId()); + request.SetSigningRegion(signingRegion); + + //generate generalized canonicalized request string. + Aws::String canonicalRequestString = Aws::Auth::AWSAuthHelper::CanonicalizeRequestSigningString(request, m_urlEscapePath); + + //append v4 stuff to the canonical request string. + canonicalRequestString.append(canonicalHeadersString); + canonicalRequestString.append(Aws::Auth::AWSAuthHelper::NEWLINE); + canonicalRequestString.append(signedHeadersValue); + canonicalRequestString.append(Aws::Auth::AWSAuthHelper::NEWLINE); + if (ServiceRequireUnsignedPayload(signingServiceName)) + { + canonicalRequestString.append(UNSIGNED_PAYLOAD); + } + else + { + canonicalRequestString.append(EMPTY_STRING_SHA256); + } + AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Request String: " << canonicalRequestString); + + //now compute sha256 on that request string + auto hashResult = m_hash->Calculate(canonicalRequestString); + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to hash (sha256) request string"); + AWS_LOGSTREAM_DEBUG(v4LogTag, "The request string is: \"" << canonicalRequestString << "\""); + return false; + } + + auto sha256Digest = hashResult.GetResult(); + auto canonicalRequestHash = HashingUtils::HexEncode(sha256Digest); + + auto stringToSign = GenerateStringToSign(dateQueryValue, simpleDate, canonicalRequestHash, signingRegion, signingServiceName); + auto finalSigningHash = GenerateSignature(credentials, stringToSign, simpleDate, signingRegion, signingServiceName); + if (finalSigningHash.empty()) + { + return false; + } + + //add that the signature to the query string + request.AddQueryStringParameter(X_AMZ_SIGNATURE, finalSigningHash); + + return true; +} + +bool AWSAuthV4Signer::ServiceRequireUnsignedPayload(const Aws::String& serviceName) const +{ + // S3 uses a magic string (instead of the empty string) for its body hash for presigned URLs as outlined here: + // https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html + // this is true for PUT, POST, GET, DELETE and HEAD operations. + // However, other services (for example RDS) implement the specification as outlined here: + // https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html + // which states that body-less requests should use the empty-string SHA256 hash. + return "s3" == serviceName || "s3-object-lambda" == serviceName; +} + +Aws::String AWSAuthV4Signer::GenerateSignature(const AWSCredentials& credentials, const Aws::String& stringToSign, + const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const +{ + auto key = ComputeHash(credentials.GetAWSSecretKey(), simpleDate, region, serviceName); + return GenerateSignature(stringToSign, key); +} + +Aws::String AWSAuthV4Signer::GenerateSignature(const Aws::String& stringToSign, const ByteBuffer& key) const +{ + AWS_LOGSTREAM_DEBUG(v4LogTag, "Final String to sign: " << stringToSign); + + Aws::StringStream ss; + + auto hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)stringToSign.c_str(), stringToSign.length()), key); + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to hmac (sha256) final string"); + AWS_LOGSTREAM_DEBUG(v4LogTag, "The final string is: \"" << stringToSign << "\""); + return {}; + } + + //now we finally sign our request string with our hex encoded derived hash. + auto finalSigningDigest = hashResult.GetResult(); + + auto finalSigningHash = HashingUtils::HexEncode(finalSigningDigest); + AWS_LOGSTREAM_DEBUG(v4LogTag, "Final computed signing hash: " << finalSigningHash); + + return finalSigningHash; +} + +Aws::String AWSAuthV4Signer::ComputePayloadHash(Aws::Http::HttpRequest& request) const +{ + if (!request.GetContentBody()) + { + AWS_LOGSTREAM_DEBUG(v4LogTag, "Using cached empty string sha256 " << EMPTY_STRING_SHA256 << " because payload is empty."); + return EMPTY_STRING_SHA256; + } + + //compute hash on payload if it exists. + auto hashResult = m_hash->Calculate(*request.GetContentBody()); + + if(request.GetContentBody()) + { + request.GetContentBody()->clear(); + request.GetContentBody()->seekg(0); + } + + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to hash (sha256) request body"); + return {}; + } + + auto sha256Digest = hashResult.GetResult(); + + Aws::String payloadHash(HashingUtils::HexEncode(sha256Digest)); + AWS_LOGSTREAM_DEBUG(v4LogTag, "Calculated sha256 " << payloadHash << " for payload."); + return payloadHash; +} + +Aws::String AWSAuthV4Signer::GenerateStringToSign(const Aws::String& dateValue, const Aws::String& simpleDate, + const Aws::String& canonicalRequestHash, const Aws::String& region, const Aws::String& serviceName) const +{ + //generate the actual string we will use in signing the final request. + Aws::StringStream ss; + + ss << Aws::Auth::AWSAuthHelper::AWS_HMAC_SHA256 << Aws::Auth::AWSAuthHelper::NEWLINE << dateValue << Aws::Auth::AWSAuthHelper::NEWLINE << simpleDate << "/" << region << "/" + << serviceName << "/" << Aws::Auth::AWSAuthHelper::AWS4_REQUEST << Aws::Auth::AWSAuthHelper::NEWLINE << canonicalRequestHash; + + return ss.str(); +} + +Aws::Utils::ByteBuffer AWSAuthV4Signer::ComputeHash(const Aws::String& secretKey, + const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const +{ + Aws::String signingKey(Aws::Auth::AWSAuthHelper::SIGNING_KEY); + signingKey.append(secretKey); + auto hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)simpleDate.c_str(), simpleDate.length()), + ByteBuffer((unsigned char*)signingKey.c_str(), signingKey.length())); + + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to HMAC (SHA256) date string \"" << simpleDate << "\""); + return {}; + } + + auto kDate = hashResult.GetResult(); + hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)region.c_str(), region.length()), kDate); + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to HMAC (SHA256) region string \"" << region << "\""); + return {}; + } + + auto kRegion = hashResult.GetResult(); + hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)serviceName.c_str(), serviceName.length()), kRegion); + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to HMAC (SHA256) service string \"" << m_serviceName << "\""); + return {}; + } + + auto kService = hashResult.GetResult(); + hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)Aws::Auth::AWSAuthHelper::AWS4_REQUEST, strlen(Aws::Auth::AWSAuthHelper::AWS4_REQUEST)), kService); + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to HMAC (SHA256) request string"); + AWS_LOGSTREAM_DEBUG(v4LogTag, "The request string is: \"" << Aws::Auth::AWSAuthHelper::AWS4_REQUEST << "\""); + return {}; + } + return hashResult.GetResult(); +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSNullSigner.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSNullSigner.cpp new file mode 100644 index 00000000000..d94cb421f2b --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSNullSigner.cpp @@ -0,0 +1,14 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/auth/signer/AWSNullSigner.h> + +namespace Aws +{ + namespace Auth + { + const char NULL_SIGNER[] = "NullSigner"; + } +} 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 4b2a38b4e68..d1a6f262c9d 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 f5fa676f986..a905dddb5cf 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 00000000000..b3e19d99778 --- /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 00000000000..a0bc8088384 --- /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 00000000000..129595b9179 --- /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 00000000000..0907b81137e --- /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 e517379a779..647c6e3f49a 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 8c2c288dcd4..50a7f9308d8 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 7e57c79ffc4..405d7566cfb 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 00000000000..f0a4e91d5ba --- /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 00000000000..e51a49049b7 --- /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 b439b7ca995..77b6f5abbbd 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 +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSConfigFileProfileConfigLoader.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSConfigFileProfileConfigLoader.cpp new file mode 100644 index 00000000000..ba0079bb5e8 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSConfigFileProfileConfigLoader.cpp @@ -0,0 +1,629 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/config/AWSProfileConfigLoader.h> +#include <aws/core/utils/memory/stl/AWSSet.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> +#include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <fstream> + +namespace Aws +{ + namespace Config + { + using namespace Aws::Utils; + using namespace Aws::Auth; + + static const char REGION_KEY[] = "region"; + static const char ACCESS_KEY_ID_KEY[] = "aws_access_key_id"; + static const char SECRET_KEY_KEY[] = "aws_secret_access_key"; + static const char SESSION_TOKEN_KEY[] = "aws_session_token"; + static const char SSO_START_URL_KEY[] = "sso_start_url"; + static const char SSO_REGION_KEY[] = "sso_region"; + static const char SSO_ACCOUNT_ID_KEY[] = "sso_account_id"; + static const char SSO_ROLE_NAME_KEY[] = "sso_role_name"; + static const char SSO_SESSION_KEY[] = "sso_session"; + static const char ROLE_ARN_KEY[] = "role_arn"; + static const char EXTERNAL_ID_KEY[] = "external_id"; + static const char CREDENTIAL_PROCESS_COMMAND[] = "credential_process"; + static const char SOURCE_PROFILE_KEY[] = "source_profile"; + static const char PROFILE_SECTION[] = "profile"; + static const char DEFAULT[] = "default"; + static const char SSO_SESSION_SECTION[] = "sso-session"; + static const char DEFAULTS_MODE_KEY[] = "defaults_mode"; + static const char EQ = '='; + static const char LEFT_BRACKET = '['; + static const char RIGHT_BRACKET = ']'; + static const char PARSER_TAG[] = "Aws::Config::ConfigFileProfileFSM"; + + // generated by python from identifier regex pattern from the spec: R"([A-Za-z0-9_\-/.%@:\+]+)": + // #py: ''.join(chr(i) for i in range(128) if re.match("[A-Za-z0-9_\-\/.%@:\+]", chr(i))) + const char IDENTIFIER_ALLOWED_CHARACTERS[] = R"(%+-./0123456789:@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz)"; + static const size_t IDENTIFIER_ALLOWED_CHARACTERS_SZ = sizeof(IDENTIFIER_ALLOWED_CHARACTERS) - 1; + const char WHITESPACE_CHARACTERS[] = "\t "; + static const size_t WHITESPACE_CHARACTERS_SZ = sizeof(WHITESPACE_CHARACTERS) - 1; + const char COMMENT_START[] = "#;"; + static const size_t COMMENT_START_SZ = sizeof(COMMENT_START) - 1; + + struct ProfilePropertyAccessFunctions + { + const char* PropertyKey; + std::function<void(Profile&, const Aws::String&)> Setter; + std::function<const Aws::String&(const Profile&)> Getter; + }; + + static const ProfilePropertyAccessFunctions PROFILE_PROPERTY_FUNCS[] = + {{REGION_KEY, &Profile::SetRegion, &Profile::GetRegion}, + //ACCESS_KEY_ID_KEY, - AwsCredentials require special handling + //SECRET_KEY_KEY, + //SESSION_TOKEN_KEY, + {SSO_START_URL_KEY, &Profile::SetSsoStartUrl, &Profile::GetSsoStartUrl}, + {SSO_REGION_KEY, &Profile::SetSsoRegion, &Profile::GetSsoRegion}, + {SSO_ACCOUNT_ID_KEY, &Profile::SetSsoAccountId, &Profile::GetSsoAccountId}, + {SSO_ROLE_NAME_KEY, &Profile::SetSsoRoleName, &Profile::GetSsoRoleName}, + //SSO_SESSION_KEY - SsoSession requires special handling + {ROLE_ARN_KEY, &Profile::SetRoleArn, &Profile::GetRoleArn}, + {EXTERNAL_ID_KEY, &Profile::SetExternalId, &Profile::GetExternalId}, + {CREDENTIAL_PROCESS_COMMAND, &Profile::SetCredentialProcess, &Profile::GetCredentialProcess}, + {SOURCE_PROFILE_KEY, &Profile::SetSourceProfile, &Profile::GetSourceProfile}, + {DEFAULTS_MODE_KEY, &Profile::SetDefaultsMode, &Profile::GetDefaultsMode}}; + + template<typename EntryT, size_t N> + const EntryT* FindInStaticArray(const EntryT (&array)[N], const Aws::String& searchKey) + { + const EntryT* found = std::find_if(array, array + N, + [&searchKey](const EntryT& entry) + { + return searchKey == entry.PropertyKey; + }); + + if(!!found && found != array + N) + return found; + + return nullptr; + } + + static const char* PROFILE_KEY_SPECIAL_HANDLING[] = + {ACCESS_KEY_ID_KEY, SECRET_KEY_KEY, SESSION_TOKEN_KEY, SSO_SESSION_KEY}; + static const size_t PROFILE_KEY_SPECIAL_HANDLING_SZ = sizeof(PROFILE_KEY_SPECIAL_HANDLING) / sizeof(PROFILE_KEY_SPECIAL_HANDLING[0]); + + struct SsoSessionPropertyAccessFunctions + { + const char* PropertyKey; + std::function<void(Profile::SsoSession&, const Aws::String&)> Setter; + std::function<const Aws::String&(const Profile::SsoSession&)> Getter; + }; + static const SsoSessionPropertyAccessFunctions SSO_SESSION_PROPERTY_FUNCS[] = + {{SSO_REGION_KEY, &Profile::SsoSession::SetSsoRegion, &Profile::SsoSession::GetSsoRegion}, + {SSO_START_URL_KEY, &Profile::SsoSession::SetSsoStartUrl, &Profile::SsoSession::GetSsoStartUrl}}; + + class ConfigFileProfileFSM + { + public: + ConfigFileProfileFSM(bool useProfilePrefix) + : m_useProfilePrefix(useProfilePrefix) + {} + + const Aws::Map<String, Profile>& GetProfiles() const { return m_foundProfiles; } + + void ParseStream(Aws::IStream& stream) + { + static const size_t ASSUME_EMPTY_LEN = 3; + State currentState = START; + Aws::String currentSectionName; + Aws::Map<Aws::String, Aws::String> currentKeyValues; + + Aws::String rawLine; + while(std::getline(stream, rawLine) && currentState != FAILURE) + { + Aws::String line = rawLine.substr(0, rawLine.find_first_of(COMMENT_START)); // ignore comments + if (line.empty() || line.length() < ASSUME_EMPTY_LEN || line.find_first_not_of(WHITESPACE_CHARACTERS) == Aws::String::npos) + { + continue; + } + + auto openPos = line.find(LEFT_BRACKET); + auto closePos = line.find(RIGHT_BRACKET); + + if(openPos != std::string::npos && closePos != std::string::npos) + { + FlushSection(currentState, currentSectionName, currentKeyValues); + currentKeyValues.clear(); + ParseSectionDeclaration(line, currentSectionName, currentState); + continue; + } + + if(PROFILE_FOUND == currentState || SSO_SESSION_FOUND == currentState) + { + auto equalsPos = line.find(EQ); + if (equalsPos != std::string::npos) + { + auto key = StringUtils::Trim(line.substr(0, equalsPos).c_str()); + auto value = StringUtils::Trim(line.substr(equalsPos + 1).c_str()); + currentKeyValues[key] = value; + continue; + } + } + + if(UNKNOWN_SECTION_FOUND == currentState) + { + // skip any unknown sections + continue; + } + + AWS_LOGSTREAM_ERROR(PARSER_TAG, "Unexpected line in the aws shared profile: " << rawLine); + currentState = FAILURE; + break; + } + + FlushSection(currentState, currentSectionName, currentKeyValues); + + // Put sso-sessions into profiles + for(auto& profile : m_foundProfiles) + { + const Aws::String& profileSsoSessionName = profile.second.GetValue(SSO_SESSION_KEY); + if(!profileSsoSessionName.empty()) + { + auto ssoSessionIt = m_foundSsoSessions.find(profileSsoSessionName); + if(ssoSessionIt == m_foundSsoSessions.end()) + { + AWS_LOGSTREAM_ERROR(PARSER_TAG, "AWS profile has reference to a missing sso_session: " << profileSsoSessionName); + currentState = FAILURE; + continue; + } + auto ssoSession = ssoSessionIt->second; + auto prof = profile.second; + // If sso session and profile have conflicting start url or region, fail to parse + // the session/sso specific profile properties + auto hasConflictingStartUrls = !ssoSession.GetSsoStartUrl().empty() + && !prof.GetSsoStartUrl().empty() + && ssoSession.GetSsoStartUrl() != prof.GetSsoStartUrl(); + auto hasConflictingRegions = !ssoSession.GetSsoRegion().empty() + && !prof.GetSsoRegion().empty() + && ssoSession.GetSsoRegion() != prof.GetSsoRegion(); + if (hasConflictingStartUrls || hasConflictingRegions) { + AWS_LOGSTREAM_ERROR(PARSER_TAG, + "SSO profile has a start url or region conflict with sso session"); + prof.SetSsoStartUrl(""); + prof.SetSsoRegion(""); + prof.SetSsoAccountId(""); + prof.SetSsoRoleName(""); + continue; + } + profile.second.SetSsoSession(ssoSessionIt->second); + } + } + + if(FAILURE == currentState) + { + AWS_LOGSTREAM_ERROR(PARSER_TAG, "AWS shared profile config parsing failed"); + } + } + + private: + // true means Shared Config parsing, false means Shared Credentials parsing + bool m_useProfilePrefix = false; + + enum State + { + START = 0, + PROFILE_FOUND, + SSO_SESSION_FOUND, + UNKNOWN_SECTION_FOUND, + FAILURE + }; + + /** + * Helper function to parse a single word (aka section identifier) containing allowed characters from a line and a pos + * i.e. line="[ profile default ]";identifierBegin=10 will return "default" + * @param line, a section definition line being parsed + * @param identifierBegin, an Aws::String position to start parsing + * @param oErrorMsg, a reference to Aws::String to store error message in case of a parsing error. + * @return Aws::String, e.g. "default" + */ + Aws::String ParseIdentifier(const Aws::String& line, Aws::String::size_type identifierBegin, Aws::String& oErrorMsg) + { + // pos at the beginning of section Identifier (or sso_session section keyword) + Aws::String::size_type identifierLength = 0; + Aws::String::size_type pos = identifierBegin; + while(pos < line.length()) + { + if(std::find(IDENTIFIER_ALLOWED_CHARACTERS, + IDENTIFIER_ALLOWED_CHARACTERS + IDENTIFIER_ALLOWED_CHARACTERS_SZ, + line[pos]) != IDENTIFIER_ALLOWED_CHARACTERS + IDENTIFIER_ALLOWED_CHARACTERS_SZ) + { + identifierLength++; + pos++; + } + else + { + break; + } + } + const Aws::String SECTION_END_CHARS_TO_SKIP = Aws::String(WHITESPACE_CHARACTERS) + RIGHT_BRACKET; + + if(identifierLength == 0) + { + oErrorMsg = "identifier is missing"; + return ""; + } + if(pos >= line.size() || SECTION_END_CHARS_TO_SKIP.find(line[pos]) == Aws::String::npos) { + oErrorMsg = "a blank space character or closing bracket is expected after Identifier"; + return ""; + } + Aws::String sectionIdentifier = line.substr(identifierBegin, identifierLength); + + return sectionIdentifier; + } + + /** + * A helper function to parse config section declaration line + * @param line, an input line, e.g. "[profile default]" + * @param ioSectionName, a return argument representing parsed section Identifier, e.g. "default" + * @param ioState, a return argument representing parser state, e.g. PROFILE_FOUND + */ + void ParseSectionDeclaration(const Aws::String& line, + Aws::String& ioSectionName, + State& ioState) + { + do { // goto in a form of "do { break; } while(0);" + Aws::String::size_type pos = 0; + pos = line.find_first_not_of(WHITESPACE_CHARACTERS, pos); + if(pos != Aws::String::npos && LEFT_BRACKET != line[pos]) + { + AWS_LOGSTREAM_ERROR(PARSER_TAG, "First non-blank space character of a section definition must be [, line:" << line); + break; + } + pos++; + pos = line.find_first_not_of(WHITESPACE_CHARACTERS, pos); + if(pos == Aws::String::npos || pos >= line.size()) + { + AWS_LOGSTREAM_ERROR(PARSER_TAG, "Unknown section found in the aws config file: " << line); + break; + } + bool defaultProfileOrSsoSectionRequired = false; + if (m_useProfilePrefix) + { + // in configuration files, the profile name must start with profile. (eg. [profile profile-name]), + // except where the profile name is default. When the profile name is default it may start with profile + static const size_t PROFILE_KEYWORD_LENGTH = 7; + if(line.rfind(PROFILE_SECTION, pos + PROFILE_KEYWORD_LENGTH) != Aws::String::npos) + { + // skipping required (optional for default) profile keyword + pos += PROFILE_KEYWORD_LENGTH; + if(pos >= line.size() || + std::find(WHITESPACE_CHARACTERS, + WHITESPACE_CHARACTERS + WHITESPACE_CHARACTERS_SZ, + line[pos]) == WHITESPACE_CHARACTERS + WHITESPACE_CHARACTERS_SZ) + { + AWS_LOGSTREAM_ERROR(PARSER_TAG, "Expected a blank space after \"profile\" keyword: " << line); + break; + } + pos = line.find_first_not_of(WHITESPACE_CHARACTERS, pos); + } + else + { + defaultProfileOrSsoSectionRequired = true; + } + } + + Aws::String errorMsg; + Aws::String sectionIdentifier = ParseIdentifier(line, pos, errorMsg); + if (!errorMsg.empty()) + { + AWS_LOGSTREAM_ERROR(PARSER_TAG, "Failed to parse section identifier: " << errorMsg << " " << line); + break; + } + pos += sectionIdentifier.length(); + + if(defaultProfileOrSsoSectionRequired) + { + if (sectionIdentifier != DEFAULT && sectionIdentifier != SSO_SESSION_SECTION) + { + AWS_LOGSTREAM_ERROR(PARSER_TAG, "In configuration files, the profile name must start with " + "profile keyword (except default profile): " << line); + break; + } + if (sectionIdentifier != SSO_SESSION_SECTION) + { + // profile found, still pending check for closing bracket + ioState = PROFILE_FOUND; + ioSectionName = sectionIdentifier; + } + } + + if(!m_useProfilePrefix || sectionIdentifier != SSO_SESSION_SECTION) + { + // profile found, still pending check for closing bracket + ioState = PROFILE_FOUND; + ioSectionName = sectionIdentifier; + } + + if(m_useProfilePrefix && sectionIdentifier == SSO_SESSION_SECTION) + { + // "[sso_session..." found, continue parsing for sso_session identifier + pos = line.find_first_not_of(WHITESPACE_CHARACTERS, pos); + if(pos == Aws::String::npos) + { + AWS_LOGSTREAM_ERROR(PARSER_TAG, "Expected a blank space after \"sso_session\" keyword: " << line); + break; + } + + sectionIdentifier = ParseIdentifier(line, pos, errorMsg); + if (!errorMsg.empty()) + { + AWS_LOGSTREAM_ERROR(PARSER_TAG, "Failed to parse section identifier: " << errorMsg << " " << line); + break; + } + pos += sectionIdentifier.length(); + // sso_session found, still pending check for closing bracket + ioState = SSO_SESSION_FOUND; + ioSectionName = sectionIdentifier; + } + + pos = line.find_first_not_of(WHITESPACE_CHARACTERS, pos); + if(pos == Aws::String::npos) + { + AWS_LOGSTREAM_ERROR(PARSER_TAG, "Expected a non-blank space after section identifier (i.e. missing \"]\"): " << line); + break; + } + if(line[pos] != RIGHT_BRACKET) + { + AWS_LOGSTREAM_ERROR(PARSER_TAG, "Missing closing bracket after Section Identifier " + "(i.e. missing \"]\" or extra non-blank characters before \"]\"): " << line); + break; + } + pos++; + pos = line.find_first_not_of(WHITESPACE_CHARACTERS, pos); + if(pos != Aws::String::npos && + std::find(COMMENT_START, COMMENT_START + COMMENT_START_SZ, line[pos]) == COMMENT_START + COMMENT_START_SZ) + { + AWS_LOGSTREAM_ERROR(PARSER_TAG, "Found unexpected characters after closing bracket of Section Identifier " << line); + break; + } + // the rest is a comment, and we don't care about it. + if ((ioState != SSO_SESSION_FOUND && ioState != PROFILE_FOUND) || ioSectionName.empty()) + { + AWS_LOGSTREAM_FATAL(PARSER_TAG, "Unexpected parser state after attempting to parse section " << line); + break; + } + return; + } while(0); // end of goto in a form of "do { break; } while(0);" + + ioSectionName.erase(); + ioState = UNKNOWN_SECTION_FOUND; + return; + } + + /** + * A helper function to store currently being parsed section along with its properties + * (i.e. [profile default] and its key1=val1 under). + * @param currentState, a current parser State, e.g. PROFILE_FOUND + * @param currentSectionName, a current section identifier, e.g. "default" + * @param currentKeyValues, a map of parsed key-value properties of a section definition being recorded + */ + void FlushSection(const State currentState, const Aws::String& currentSectionName, Aws::Map<Aws::String, Aws::String>& currentKeyValues) + { + if(START == currentState || currentSectionName.empty()) + { + return; //nothing to flush + } + + if(PROFILE_FOUND == currentState) + { + Profile& profile = m_foundProfiles[currentSectionName]; + + for(const auto& keyVal : currentKeyValues) + { + auto setterFuncPtr = FindInStaticArray(PROFILE_PROPERTY_FUNCS, keyVal.first); + if(setterFuncPtr) + { + AWS_LOGSTREAM_DEBUG(PARSER_TAG, "Found " << setterFuncPtr->PropertyKey << " " << keyVal.second); + setterFuncPtr->Setter(profile, keyVal.second); + } + else + { + auto specialPropertyKey = std::find_if(PROFILE_KEY_SPECIAL_HANDLING, PROFILE_KEY_SPECIAL_HANDLING + PROFILE_KEY_SPECIAL_HANDLING_SZ, + [&keyVal](const char* entry) + { + return !!entry && keyVal.first == entry; + }); + + if (specialPropertyKey && specialPropertyKey != PROFILE_KEY_SPECIAL_HANDLING + PROFILE_KEY_SPECIAL_HANDLING_SZ) + { + AWS_LOGSTREAM_INFO(PARSER_TAG, "Unknown property: " << keyVal.first << " in the profile: " << currentSectionName); + } + } + } + + auto accessKeyIdIter = currentKeyValues.find(ACCESS_KEY_ID_KEY); + Aws::String accessKey, secretKey, sessionToken; + if (accessKeyIdIter != currentKeyValues.end()) + { + accessKey = accessKeyIdIter->second; + AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found access key " << accessKey); + + auto secretAccessKeyIter = currentKeyValues.find(SECRET_KEY_KEY); + auto sessionTokenIter = currentKeyValues.find(SESSION_TOKEN_KEY); + if (secretAccessKeyIter != currentKeyValues.end()) + { + secretKey = secretAccessKeyIter->second; + } + else + { + AWS_LOGSTREAM_ERROR(PARSER_TAG, "No secret access key found even though an access key was specified. This will cause all signed AWS calls to fail."); + } + + if (sessionTokenIter != currentKeyValues.end()) + { + sessionToken = sessionTokenIter->second; + } + + profile.SetCredentials(Aws::Auth::AWSCredentials(accessKey, secretKey, sessionToken)); + } + + if (!profile.GetSsoStartUrl().empty() || !profile.GetSsoRegion().empty() + || !profile.GetSsoAccountId().empty() || !profile.GetSsoRoleName().empty()) + { + // If there is no sso session, all fields are required. If an SSO session is present, + // then only account id and sso role name are required. + auto hasSession = currentKeyValues.find(SSO_SESSION_KEY) != currentKeyValues.end(); + auto hasInvalidProfileWithoutSession = !hasSession && + (profile.GetSsoStartUrl().empty() + || profile.GetSsoRegion().empty() + || profile.GetSsoAccountId().empty() + || profile.GetSsoRoleName().empty()); + auto hasInvalidProfileWithSession = hasSession && + (profile.GetSsoAccountId().empty() + || profile.GetSsoRoleName().empty()); + if (hasInvalidProfileWithoutSession || hasInvalidProfileWithSession) { + profile.SetSsoStartUrl(""); + profile.SetSsoRegion(""); + profile.SetSsoAccountId(""); + profile.SetSsoRoleName(""); + AWS_LOGSTREAM_ERROR(PARSER_TAG, "invalid SSO configuration for aws profile " << currentSectionName); + } + } + + profile.SetName(currentSectionName); + profile.SetAllKeyValPairs(std::move(currentKeyValues)); + } + else if (SSO_SESSION_FOUND == currentState) { + Profile::SsoSession& ssoSession = m_foundSsoSessions[currentSectionName]; + for(const auto& keyVal : currentKeyValues) + { + auto setterFuncPtr = FindInStaticArray(SSO_SESSION_PROPERTY_FUNCS, keyVal.first); + if(setterFuncPtr) + { + AWS_LOGSTREAM_DEBUG(PARSER_TAG, "Found sso-session property " << setterFuncPtr->PropertyKey << " " << keyVal.second); + setterFuncPtr->Setter(ssoSession, keyVal.second); + } + else + { + AWS_LOGSTREAM_INFO(PARSER_TAG, "Unknown property: " << keyVal.first << " in the sso-session: " << currentSectionName); + } + } + ssoSession.SetName(currentSectionName); + ssoSession.SetAllKeyValPairs(std::move(currentKeyValues)); + } + else + { + AWS_LOGSTREAM_FATAL(PARSER_TAG, "Unknown parser error: unexpected state " << currentState); + } + } + + Aws::Map<String, Profile> m_foundProfiles; + Aws::Map<String, Profile::SsoSession> m_foundSsoSessions; + }; + + static const char* const CONFIG_FILE_LOADER = "Aws::Config::AWSConfigFileProfileConfigLoader"; + + AWSConfigFileProfileConfigLoader::AWSConfigFileProfileConfigLoader(const Aws::String& fileName, bool useProfilePrefix) : + m_fileName(fileName), m_useProfilePrefix(useProfilePrefix) + { + AWS_LOGSTREAM_INFO(CONFIG_FILE_LOADER, "Initializing config loader against fileName " + << fileName << " and using profilePrefix = " << useProfilePrefix); + } + + bool AWSConfigFileProfileConfigLoader::LoadInternal() + { + m_profiles.clear(); + + Aws::IFStream inputFile(m_fileName.c_str()); + if(inputFile) + { + ConfigFileProfileFSM parser(m_useProfilePrefix); + parser.ParseStream(inputFile); + m_profiles = parser.GetProfiles(); + return m_profiles.size() > 0; + } + + AWS_LOGSTREAM_INFO(CONFIG_FILE_LOADER, "Unable to open config file " << m_fileName << " for reading."); + + return false; + } + + bool AWSConfigFileProfileConfigLoader::PersistInternal(const Aws::Map<Aws::String, Profile>& profiles) + { + Aws::OFStream outputFile(m_fileName.c_str(), std::ios_base::out | std::ios_base::trunc); + if(outputFile) + { + Aws::UnorderedMap<Aws::String, std::reference_wrapper<const Profile::SsoSession>> ssoSessionsToDump; + + for(const auto& profile : profiles) + { + Aws::String prefix = m_useProfilePrefix ? PROFILE_SECTION : ""; + + AWS_LOGSTREAM_DEBUG(CONFIG_FILE_LOADER, "Writing profile " << profile.first << " to disk."); + + outputFile << LEFT_BRACKET << prefix << " " << profile.second.GetName() << RIGHT_BRACKET << std::endl; + const Aws::Auth::AWSCredentials& credentials = profile.second.GetCredentials(); + if (!credentials.GetAWSAccessKeyId().empty()) { + outputFile << ACCESS_KEY_ID_KEY << EQ << credentials.GetAWSAccessKeyId() << std::endl; + } + if (!credentials.GetAWSSecretKey().empty()) { + outputFile << SECRET_KEY_KEY << EQ << credentials.GetAWSSecretKey() << std::endl; + } + if(!credentials.GetSessionToken().empty()) { + outputFile << SESSION_TOKEN_KEY << EQ << credentials.GetSessionToken() << std::endl; + } + // credentials.GetExpiration().Millis() <- is not present in a config. + + for(const auto& profilePropertyPair : PROFILE_PROPERTY_FUNCS) + { + const auto& profilePropertyValue = profilePropertyPair.Getter(profile.second); + if(!profilePropertyValue.empty()) + { + outputFile << profilePropertyPair.PropertyKey << EQ << profilePropertyValue << std::endl; + } + } + + if(profile.second.IsSsoSessionSet()) + { + const auto& ssoSession = profile.second.GetSsoSession(); + const auto alreadyScheduledForDumpIt = ssoSessionsToDump.find(ssoSession.GetName()); + if (alreadyScheduledForDumpIt != ssoSessionsToDump.end() && + alreadyScheduledForDumpIt->second.get() != ssoSession) + { + AWS_LOGSTREAM_WARN(CONFIG_FILE_LOADER, "2 or more profiles reference 'sso-session' section " + "with the same name but different properties: " << ssoSession.GetName()); + } + else + { + ssoSessionsToDump.insert({ssoSession.GetName(), std::cref(ssoSession)}); + } + outputFile << SSO_SESSION_KEY << EQ << ssoSession.GetName() << std::endl; + } + outputFile << std::endl; + } + + for(const auto& ssoSessionPair : ssoSessionsToDump) + { + AWS_LOGSTREAM_DEBUG(CONFIG_FILE_LOADER, "Writing sso-session " << ssoSessionPair.first << " to disk."); + const Profile::SsoSession& ssoSession = ssoSessionPair.second.get(); + outputFile << LEFT_BRACKET << SSO_SESSION_SECTION << " " << ssoSession.GetName() << RIGHT_BRACKET << std::endl; + for(const auto& ssoSessionPropertyPair : SSO_SESSION_PROPERTY_FUNCS) + { + const auto& profilePropertyValue = ssoSessionPropertyPair.Getter(ssoSession); + if(!profilePropertyValue.empty()) + { + outputFile << ssoSessionPropertyPair.PropertyKey << EQ << profilePropertyValue << std::endl; + } + } + outputFile << std::endl; + } + + AWS_LOGSTREAM_INFO(CONFIG_FILE_LOADER, "Profiles written to config file " << m_fileName); + + return true; + } + + AWS_LOGSTREAM_WARN(CONFIG_FILE_LOADER, "Unable to open config file " << m_fileName << " for writing."); + + return false; + } + } // Config namespace +} // Aws namespace diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp deleted file mode 100644 index bb6acd0b3a0..00000000000 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp +++ /dev/null @@ -1,571 +0,0 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ - -#include <aws/core/config/AWSProfileConfigLoader.h> -#include <aws/core/internal/AWSHttpResourceClient.h> -#include <aws/core/auth/AWSCredentialsProvider.h> -#include <aws/core/utils/memory/stl/AWSList.h> -#include <aws/core/utils/memory/stl/AWSStreamFwd.h> -#include <aws/core/utils/StringUtils.h> -#include <aws/core/utils/logging/LogMacros.h> -#include <aws/core/utils/json/JsonSerializer.h> -#include <fstream> - -namespace Aws -{ - namespace Config - { - using namespace Aws::Utils; - using namespace Aws::Auth; - - static const char* const CONFIG_LOADER_TAG = "Aws::Config::AWSProfileConfigLoader"; - #ifdef _MSC_VER - // VS2015 compiler's bug, warning s_CoreErrorsMapper: symbol will be dynamically initialized (implementation limitation) - AWS_SUPPRESS_WARNING(4592, - static Aws::UniquePtr<ConfigAndCredentialsCacheManager> s_configManager(nullptr); - ) - #else - static Aws::UniquePtr<ConfigAndCredentialsCacheManager> s_configManager(nullptr); - #endif - - static const char CONFIG_CREDENTIALS_CACHE_MANAGER_TAG[] = "ConfigAndCredentialsCacheManager"; - - bool AWSProfileConfigLoader::Load() - { - if(LoadInternal()) - { - AWS_LOGSTREAM_INFO(CONFIG_LOADER_TAG, "Successfully reloaded configuration."); - m_lastLoadTime = DateTime::Now(); - AWS_LOGSTREAM_TRACE(CONFIG_LOADER_TAG, "reloaded config at " - << m_lastLoadTime.ToGmtString(DateFormat::ISO_8601)); - return true; - } - - AWS_LOGSTREAM_INFO(CONFIG_LOADER_TAG, "Failed to reload configuration."); - return false; - } - - bool AWSProfileConfigLoader::PersistProfiles(const Aws::Map<Aws::String, Profile>& profiles) - { - if(PersistInternal(profiles)) - { - AWS_LOGSTREAM_INFO(CONFIG_LOADER_TAG, "Successfully persisted configuration."); - m_profiles = profiles; - m_lastLoadTime = DateTime::Now(); - AWS_LOGSTREAM_TRACE(CONFIG_LOADER_TAG, "persisted config at " - << m_lastLoadTime.ToGmtString(DateFormat::ISO_8601)); - return true; - } - - AWS_LOGSTREAM_WARN(CONFIG_LOADER_TAG, "Failed to persist configuration."); - return false; - } - - static const char REGION_KEY[] = "region"; - static const char ACCESS_KEY_ID_KEY[] = "aws_access_key_id"; - static const char SECRET_KEY_KEY[] = "aws_secret_access_key"; - static const char SESSION_TOKEN_KEY[] = "aws_session_token"; - static const char SSO_START_URL_KEY[] = "sso_start_url"; - static const char SSO_REGION_KEY[] = "sso_region"; - static const char SSO_ACCOUNT_ID_KEY[] = "sso_account_id"; - static const char SSO_ROLE_NAME_KEY[] = "sso_role_name"; - static const char ROLE_ARN_KEY[] = "role_arn"; - static const char EXTERNAL_ID_KEY[] = "external_id"; - static const char CREDENTIAL_PROCESS_COMMAND[] = "credential_process"; - static const char SOURCE_PROFILE_KEY[] = "source_profile"; - static const char PROFILE_PREFIX[] = "profile "; - static const char EQ = '='; - static const char LEFT_BRACKET = '['; - static const char RIGHT_BRACKET = ']'; - static const char PARSER_TAG[] = "Aws::Config::ConfigFileProfileFSM"; - - class ConfigFileProfileFSM - { - public: - ConfigFileProfileFSM() : m_parserState(START) {} - - const Aws::Map<String, Profile>& GetProfiles() const { return m_foundProfiles; } - - void ParseStream(Aws::IStream& stream) - { - static const size_t ASSUME_EMPTY_LEN = 3; - - Aws::String line; - while(std::getline(stream, line) && m_parserState != FAILURE) - { - if (line.empty() || line.length() < ASSUME_EMPTY_LEN) - { - continue; - } - - auto openPos = line.find(LEFT_BRACKET); - auto closePos = line.find(RIGHT_BRACKET); - - switch(m_parserState) - { - - case START: - if(openPos != std::string::npos && closePos != std::string::npos) - { - FlushProfileAndReset(line, openPos, closePos); - m_parserState = PROFILE_FOUND; - } - break; - - //fallthrough here is intentional to reduce duplicate logic - case PROFILE_KEY_VALUE_FOUND: - if(openPos != std::string::npos && closePos != std::string::npos) - { - m_parserState = PROFILE_FOUND; - FlushProfileAndReset(line, openPos, closePos); - break; - } - // fall through - case PROFILE_FOUND: - { - auto equalsPos = line.find(EQ); - if (equalsPos != std::string::npos) - { - auto key = line.substr(0, equalsPos); - auto value = line.substr(equalsPos + 1); - m_profileKeyValuePairs[StringUtils::Trim(key.c_str())] = - StringUtils::Trim(value.c_str()); - m_parserState = PROFILE_KEY_VALUE_FOUND; - } - - break; - } - default: - m_parserState = FAILURE; - break; - } - } - - FlushProfileAndReset(line, std::string::npos, std::string::npos); - } - - private: - - void FlushProfileAndReset(Aws::String& line, size_t openPos, size_t closePos) - { - if(!m_currentWorkingProfile.empty() && !m_profileKeyValuePairs.empty()) - { - Profile profile; - profile.SetName(m_currentWorkingProfile); - - auto regionIter = m_profileKeyValuePairs.find(REGION_KEY); - if (regionIter != m_profileKeyValuePairs.end()) - { - AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found region " << regionIter->second); - profile.SetRegion(regionIter->second); - } - - auto accessKeyIdIter = m_profileKeyValuePairs.find(ACCESS_KEY_ID_KEY); - Aws::String accessKey, secretKey, sessionToken; - if (accessKeyIdIter != m_profileKeyValuePairs.end()) - { - accessKey = accessKeyIdIter->second; - AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found access key " << accessKey); - - auto secretAccessKeyIter = m_profileKeyValuePairs.find(SECRET_KEY_KEY); - auto sessionTokenIter = m_profileKeyValuePairs.find(SESSION_TOKEN_KEY); - if (secretAccessKeyIter != m_profileKeyValuePairs.end()) - { - secretKey = secretAccessKeyIter->second; - } - else - { - AWS_LOGSTREAM_ERROR(PARSER_TAG, "No secret access key found even though an access key was specified. This will cause all signed AWS calls to fail."); - } - - if (sessionTokenIter != m_profileKeyValuePairs.end()) - { - sessionToken = sessionTokenIter->second; - } - - profile.SetCredentials(Aws::Auth::AWSCredentials(accessKey, secretKey, sessionToken)); - } - - auto ssoStartUrlIter = m_profileKeyValuePairs.find(SSO_START_URL_KEY); - auto ssoRegionIter = m_profileKeyValuePairs.find(SSO_REGION_KEY); - auto ssoRoleNameIter = m_profileKeyValuePairs.find(SSO_ROLE_NAME_KEY); - auto ssoAccountIdIter = m_profileKeyValuePairs.find(SSO_ACCOUNT_ID_KEY); - if (ssoStartUrlIter != m_profileKeyValuePairs.end() - || ssoRegionIter != m_profileKeyValuePairs.end() - || ssoRoleNameIter != m_profileKeyValuePairs.end() - || ssoAccountIdIter != m_profileKeyValuePairs.end()) - { - if (ssoStartUrlIter != m_profileKeyValuePairs.end() - && ssoRegionIter != m_profileKeyValuePairs.end() - && ssoRoleNameIter != m_profileKeyValuePairs.end() - && ssoAccountIdIter != m_profileKeyValuePairs.end()) - { - AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found sso_start_url " << ssoStartUrlIter->second); - profile.SetSsoStartUrl(ssoStartUrlIter->second); - AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found sso_region " << ssoRegionIter->second); - profile.SetSsoRegion(ssoRegionIter->second); - AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found sso_account_id " << ssoAccountIdIter->second); - profile.SetSsoAccountId(ssoAccountIdIter->second); - AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found sso_role_name " << ssoRoleNameIter->second); - profile.SetSsoRoleName(ssoRoleNameIter->second); - } else { - AWS_LOGSTREAM_ERROR(PARSER_TAG, "invalid configuration for sso profile " << profile.GetName()); - } - } - - auto assumeRoleArnIter = m_profileKeyValuePairs.find(ROLE_ARN_KEY); - if (assumeRoleArnIter != m_profileKeyValuePairs.end()) - { - AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found role arn " << assumeRoleArnIter->second); - profile.SetRoleArn(assumeRoleArnIter->second); - } - - auto externalIdIter = m_profileKeyValuePairs.find(EXTERNAL_ID_KEY); - if (externalIdIter != m_profileKeyValuePairs.end()) - { - AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found external id " << externalIdIter->second); - profile.SetExternalId(externalIdIter->second); - } - - auto sourceProfileIter = m_profileKeyValuePairs.find(SOURCE_PROFILE_KEY); - if (sourceProfileIter != m_profileKeyValuePairs.end()) - { - AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found source profile " << sourceProfileIter->second); - profile.SetSourceProfile(sourceProfileIter->second); - } - - auto credentialProcessIter = m_profileKeyValuePairs.find(CREDENTIAL_PROCESS_COMMAND); - if (credentialProcessIter != m_profileKeyValuePairs.end()) - { - AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found credential process " << credentialProcessIter->second); - profile.SetCredentialProcess(credentialProcessIter->second); - } - profile.SetAllKeyValPairs(m_profileKeyValuePairs); - - m_foundProfiles[profile.GetName()] = std::move(profile); - m_currentWorkingProfile.clear(); - m_profileKeyValuePairs.clear(); - } - - if(!line.empty() && openPos != std::string::npos && closePos != std::string::npos) - { - m_currentWorkingProfile = StringUtils::Trim(line.substr(openPos + 1, closePos - openPos - 1).c_str()); - StringUtils::Replace(m_currentWorkingProfile, PROFILE_PREFIX, ""); - AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found profile " << m_currentWorkingProfile); - } - } - - enum State - { - START = 0, - PROFILE_FOUND, - PROFILE_KEY_VALUE_FOUND, - FAILURE - }; - - Aws::String m_currentWorkingProfile; - Aws::Map<String, String> m_profileKeyValuePairs; - State m_parserState; - Aws::Map<String, Profile> m_foundProfiles; - }; - - static const char* const CONFIG_FILE_LOADER = "Aws::Config::AWSConfigFileProfileConfigLoader"; - - AWSConfigFileProfileConfigLoader::AWSConfigFileProfileConfigLoader(const Aws::String& fileName, bool useProfilePrefix) : - m_fileName(fileName), m_useProfilePrefix(useProfilePrefix) - { - AWS_LOGSTREAM_INFO(CONFIG_FILE_LOADER, "Initializing config loader against fileName " - << fileName << " and using profilePrefix = " << useProfilePrefix); - } - - bool AWSConfigFileProfileConfigLoader::LoadInternal() - { - m_profiles.clear(); - - Aws::IFStream inputFile(m_fileName.c_str()); - if(inputFile) - { - ConfigFileProfileFSM parser; - parser.ParseStream(inputFile); - m_profiles = parser.GetProfiles(); - return m_profiles.size() > 0; - } - - AWS_LOGSTREAM_INFO(CONFIG_FILE_LOADER, "Unable to open config file " << m_fileName << " for reading."); - - return false; - } - - bool AWSConfigFileProfileConfigLoader::PersistInternal(const Aws::Map<Aws::String, Profile>& profiles) - { - Aws::OFStream outputFile(m_fileName.c_str(), std::ios_base::out | std::ios_base::trunc); - if(outputFile) - { - for(auto& profile : profiles) - { - Aws::String prefix = m_useProfilePrefix ? PROFILE_PREFIX : ""; - - AWS_LOGSTREAM_DEBUG(CONFIG_FILE_LOADER, "Writing profile " << profile.first << " to disk."); - - outputFile << LEFT_BRACKET << prefix << profile.second.GetName() << RIGHT_BRACKET << std::endl; - const Aws::Auth::AWSCredentials& credentials = profile.second.GetCredentials(); - outputFile << ACCESS_KEY_ID_KEY << EQ << credentials.GetAWSAccessKeyId() << std::endl; - outputFile << SECRET_KEY_KEY << EQ << credentials.GetAWSSecretKey() << std::endl; - - if(!credentials.GetSessionToken().empty()) - { - outputFile << SESSION_TOKEN_KEY << EQ << credentials.GetSessionToken() << std::endl; - } - - if(!profile.second.GetRegion().empty()) - { - outputFile << REGION_KEY << EQ << profile.second.GetRegion() << std::endl; - } - - if(!profile.second.GetRoleArn().empty()) - { - outputFile << ROLE_ARN_KEY << EQ << profile.second.GetRoleArn() << std::endl; - } - - if(!profile.second.GetSourceProfile().empty()) - { - outputFile << SOURCE_PROFILE_KEY << EQ << profile.second.GetSourceProfile() << std::endl; - } - - outputFile << std::endl; - } - - AWS_LOGSTREAM_INFO(CONFIG_FILE_LOADER, "Profiles written to config file " << m_fileName); - - return true; - } - - AWS_LOGSTREAM_WARN(CONFIG_FILE_LOADER, "Unable to open config file " << m_fileName << " for writing."); - - return false; - } - - static const char* const EC2_INSTANCE_PROFILE_LOG_TAG = "Aws::Config::EC2InstanceProfileConfigLoader"; - - EC2InstanceProfileConfigLoader::EC2InstanceProfileConfigLoader(const std::shared_ptr<Aws::Internal::EC2MetadataClient>& client) - : m_ec2metadataClient(client == nullptr ? Aws::MakeShared<Aws::Internal::EC2MetadataClient>(EC2_INSTANCE_PROFILE_LOG_TAG) : client) - { - } - - bool EC2InstanceProfileConfigLoader::LoadInternal() - { - auto credentialsStr = m_ec2metadataClient->GetDefaultCredentialsSecurely(); - if(credentialsStr.empty()) return false; - - Json::JsonValue credentialsDoc(credentialsStr); - if (!credentialsDoc.WasParseSuccessful()) - { - AWS_LOGSTREAM_ERROR(EC2_INSTANCE_PROFILE_LOG_TAG, - "Failed to parse output from EC2MetadataService."); - return false; - } - const char* accessKeyId = "AccessKeyId"; - const char* secretAccessKey = "SecretAccessKey"; - Aws::String accessKey, secretKey, token; - - auto credentialsView = credentialsDoc.View(); - accessKey = credentialsView.GetString(accessKeyId); - AWS_LOGSTREAM_INFO(EC2_INSTANCE_PROFILE_LOG_TAG, - "Successfully pulled credentials from metadata service with access key " << accessKey); - - secretKey = credentialsView.GetString(secretAccessKey); - token = credentialsView.GetString("Token"); - - auto region = m_ec2metadataClient->GetCurrentRegion(); - - Profile profile; - profile.SetCredentials(AWSCredentials(accessKey, secretKey, token)); - profile.SetRegion(region); - profile.SetName(INSTANCE_PROFILE_KEY); - - m_profiles[INSTANCE_PROFILE_KEY] = profile; - - return true; - } - - ConfigAndCredentialsCacheManager::ConfigAndCredentialsCacheManager() : - m_credentialsFileLoader(Aws::Auth::ProfileConfigFileAWSCredentialsProvider::GetCredentialsProfileFilename()), - m_configFileLoader(Aws::Auth::GetConfigProfileFilename(), true/*use profile prefix*/) - { - ReloadCredentialsFile(); - ReloadConfigFile(); - } - - void ConfigAndCredentialsCacheManager::ReloadConfigFile() - { - Aws::Utils::Threading::WriterLockGuard guard(m_configLock); - m_configFileLoader.SetFileName(Aws::Auth::GetConfigProfileFilename()); - m_configFileLoader.Load(); - } - - void ConfigAndCredentialsCacheManager::ReloadCredentialsFile() - { - Aws::Utils::Threading::WriterLockGuard guard(m_credentialsLock); - m_credentialsFileLoader.SetFileName(Aws::Auth::ProfileConfigFileAWSCredentialsProvider::GetCredentialsProfileFilename()); - m_credentialsFileLoader.Load(); - } - - bool ConfigAndCredentialsCacheManager::HasConfigProfile(const Aws::String& profileName) const - { - Aws::Utils::Threading::ReaderLockGuard guard(m_configLock); - return (m_configFileLoader.GetProfiles().count(profileName) == 1); - } - - Aws::Config::Profile ConfigAndCredentialsCacheManager::GetConfigProfile(const Aws::String& profileName) const - { - Aws::Utils::Threading::ReaderLockGuard guard(m_configLock); - const auto& profiles = m_configFileLoader.GetProfiles(); - const auto &iter = profiles.find(profileName); - if (iter == profiles.end()) - { - return {}; - } - return iter->second; - } - - Aws::Map<Aws::String, Aws::Config::Profile> ConfigAndCredentialsCacheManager::GetConfigProfiles() const - { - Aws::Utils::Threading::ReaderLockGuard guard(m_configLock); - return m_configFileLoader.GetProfiles(); - } - - Aws::String ConfigAndCredentialsCacheManager::GetConfig(const Aws::String& profileName, const Aws::String& key) const - { - Aws::Utils::Threading::ReaderLockGuard guard(m_configLock); - const auto& profiles = m_configFileLoader.GetProfiles(); - const auto &iter = profiles.find(profileName); - if (iter == profiles.end()) - { - return {}; - } - return iter->second.GetValue(key); - } - - bool ConfigAndCredentialsCacheManager::HasCredentialsProfile(const Aws::String& profileName) const - { - Aws::Utils::Threading::ReaderLockGuard guard(m_credentialsLock); - return (m_credentialsFileLoader.GetProfiles().count(profileName) == 1); - } - - Aws::Config::Profile ConfigAndCredentialsCacheManager::GetCredentialsProfile(const Aws::String& profileName) const - { - Aws::Utils::Threading::ReaderLockGuard guard(m_credentialsLock); - const auto &profiles = m_credentialsFileLoader.GetProfiles(); - const auto &iter = profiles.find(profileName); - if (iter == profiles.end()) - { - return {}; - } - return iter->second; - } - - Aws::Map<Aws::String, Aws::Config::Profile> ConfigAndCredentialsCacheManager::GetCredentialsProfiles() const - { - Aws::Utils::Threading::ReaderLockGuard guard(m_credentialsLock); - return m_credentialsFileLoader.GetProfiles(); - } - - Aws::Auth::AWSCredentials ConfigAndCredentialsCacheManager::GetCredentials(const Aws::String& profileName) const - { - Aws::Utils::Threading::ReaderLockGuard guard(m_credentialsLock); - const auto& profiles = m_credentialsFileLoader.GetProfiles(); - const auto &iter = profiles.find(profileName); - if (iter == profiles.end()) - { - return {}; - } - return iter->second.GetCredentials(); - } - - void InitConfigAndCredentialsCacheManager() - { - if (s_configManager) - { - return; - } - s_configManager = Aws::MakeUnique<ConfigAndCredentialsCacheManager>(CONFIG_CREDENTIALS_CACHE_MANAGER_TAG); - } - - void CleanupConfigAndCredentialsCacheManager() - { - if (!s_configManager) - { - return; - } - s_configManager = nullptr; - } - - void ReloadCachedConfigFile() - { - assert(s_configManager); - s_configManager->ReloadConfigFile(); - } - - void ReloadCachedCredentialsFile() - { - assert(s_configManager); - s_configManager->ReloadCredentialsFile(); - } - - bool HasCachedConfigProfile(const Aws::String& profileName) - { - assert(s_configManager); - return s_configManager->HasConfigProfile(profileName); - } - - Aws::Config::Profile GetCachedConfigProfile(const Aws::String& profileName) - { - assert(s_configManager); - return s_configManager->GetConfigProfile(profileName); - } - - Aws::Map<Aws::String, Aws::Config::Profile> GetCachedConfigProfiles() - { - assert(s_configManager); - return s_configManager->GetConfigProfiles(); - } - - Aws::String GetCachedConfigValue(const Aws::String &profileName, const Aws::String &key) - { - assert(s_configManager); - return s_configManager->GetConfig(profileName, key); - } - - Aws::String GetCachedConfigValue(const Aws::String &key) - { - assert(s_configManager); - return s_configManager->GetConfig(Aws::Auth::GetConfigProfileName(), key); - } - - bool HasCachedCredentialsProfile(const Aws::String& profileName) - { - assert(s_configManager); - return s_configManager->HasCredentialsProfile(profileName); - } - - Aws::Config::Profile GetCachedCredentialsProfile(const Aws::String &profileName) - { - assert(s_configManager); - return s_configManager->GetCredentialsProfile(profileName); - } - - Aws::Map<Aws::String, Aws::Config::Profile> GetCachedCredentialsProfiles() - { - assert(s_configManager); - return s_configManager->GetCredentialsProfiles(); - } - - Aws::Auth::AWSCredentials GetCachedCredentials(const Aws::String &profileName) - { - assert(s_configManager); - return s_configManager->GetCredentials(profileName); - } - } // Config namespace -} // Aws namespace diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoaderBase.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoaderBase.cpp new file mode 100644 index 00000000000..cb7b19d0ceb --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoaderBase.cpp @@ -0,0 +1,50 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/config/AWSProfileConfigLoaderBase.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <fstream> + +namespace Aws +{ + namespace Config + { + using namespace Aws::Utils; + using namespace Aws::Auth; + + static const char* const CONFIG_LOADER_BASE_TAG = "Aws::Config::AWSProfileConfigLoaderBase"; + + bool AWSProfileConfigLoader::Load() + { + if(LoadInternal()) + { + AWS_LOGSTREAM_INFO(CONFIG_LOADER_BASE_TAG, "Successfully reloaded configuration."); + m_lastLoadTime = DateTime::Now(); + AWS_LOGSTREAM_TRACE(CONFIG_LOADER_BASE_TAG, "reloaded config at " + << m_lastLoadTime.ToGmtString(DateFormat::ISO_8601)); + return true; + } + + AWS_LOGSTREAM_INFO(CONFIG_LOADER_BASE_TAG, "Failed to reload configuration."); + return false; + } + + bool AWSProfileConfigLoader::PersistProfiles(const Aws::Map<Aws::String, Profile>& profiles) + { + if(PersistInternal(profiles)) + { + AWS_LOGSTREAM_INFO(CONFIG_LOADER_BASE_TAG, "Successfully persisted configuration."); + m_profiles = profiles; + m_lastLoadTime = DateTime::Now(); + AWS_LOGSTREAM_TRACE(CONFIG_LOADER_BASE_TAG, "persisted config at " + << m_lastLoadTime.ToGmtString(DateFormat::ISO_8601)); + return true; + } + + AWS_LOGSTREAM_WARN(CONFIG_LOADER_BASE_TAG, "Failed to persist configuration."); + return false; + } + } // Config namespace +} // Aws namespace diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/ConfigAndCredentialsCacheManager.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/ConfigAndCredentialsCacheManager.cpp new file mode 100644 index 00000000000..b47fe72a0a2 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/ConfigAndCredentialsCacheManager.cpp @@ -0,0 +1,206 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/config/ConfigAndCredentialsCacheManager.h> +#include <aws/core/auth/AWSCredentialsProvider.h> +#include <aws/core/utils/memory/stl/AWSList.h> +#include <aws/core/utils/json/JsonSerializer.h> +#include <fstream> + +namespace Aws +{ + namespace Config + { + using namespace Aws::Utils; + using namespace Aws::Auth; + + #ifdef _MSC_VER + // VS2015 compiler's bug, warning s_CoreErrorsMapper: symbol will be dynamically initialized (implementation limitation) + AWS_SUPPRESS_WARNING(4592, + static ConfigAndCredentialsCacheManager* s_configManager(nullptr); + ) + #else + static ConfigAndCredentialsCacheManager* s_configManager(nullptr); + #endif + + static const char CONFIG_CREDENTIALS_CACHE_MANAGER_TAG[] = "ConfigAndCredentialsCacheManager"; + + + ConfigAndCredentialsCacheManager::ConfigAndCredentialsCacheManager() : + m_credentialsFileLoader(Aws::Auth::ProfileConfigFileAWSCredentialsProvider::GetCredentialsProfileFilename()), + m_configFileLoader(Aws::Auth::GetConfigProfileFilename(), true/*use profile prefix*/) + { + ReloadCredentialsFile(); + ReloadConfigFile(); + } + + void ConfigAndCredentialsCacheManager::ReloadConfigFile() + { + Aws::Utils::Threading::WriterLockGuard guard(m_configLock); + m_configFileLoader.SetFileName(Aws::Auth::GetConfigProfileFilename()); + m_configFileLoader.Load(); + } + + void ConfigAndCredentialsCacheManager::ReloadCredentialsFile() + { + Aws::Utils::Threading::WriterLockGuard guard(m_credentialsLock); + m_credentialsFileLoader.SetFileName(Aws::Auth::ProfileConfigFileAWSCredentialsProvider::GetCredentialsProfileFilename()); + m_credentialsFileLoader.Load(); + } + + bool ConfigAndCredentialsCacheManager::HasConfigProfile(const Aws::String& profileName) const + { + Aws::Utils::Threading::ReaderLockGuard guard(m_configLock); + return (m_configFileLoader.GetProfiles().count(profileName) == 1); + } + + Aws::Config::Profile ConfigAndCredentialsCacheManager::GetConfigProfile(const Aws::String& profileName) const + { + Aws::Utils::Threading::ReaderLockGuard guard(m_configLock); + const auto& profiles = m_configFileLoader.GetProfiles(); + const auto &iter = profiles.find(profileName); + if (iter == profiles.end()) + { + return {}; + } + return iter->second; + } + + Aws::Map<Aws::String, Aws::Config::Profile> ConfigAndCredentialsCacheManager::GetConfigProfiles() const + { + Aws::Utils::Threading::ReaderLockGuard guard(m_configLock); + return m_configFileLoader.GetProfiles(); + } + + Aws::String ConfigAndCredentialsCacheManager::GetConfig(const Aws::String& profileName, const Aws::String& key) const + { + Aws::Utils::Threading::ReaderLockGuard guard(m_configLock); + const auto& profiles = m_configFileLoader.GetProfiles(); + const auto &iter = profiles.find(profileName); + if (iter == profiles.end()) + { + return {}; + } + return iter->second.GetValue(key); + } + + bool ConfigAndCredentialsCacheManager::HasCredentialsProfile(const Aws::String& profileName) const + { + Aws::Utils::Threading::ReaderLockGuard guard(m_credentialsLock); + return (m_credentialsFileLoader.GetProfiles().count(profileName) == 1); + } + + Aws::Config::Profile ConfigAndCredentialsCacheManager::GetCredentialsProfile(const Aws::String& profileName) const + { + Aws::Utils::Threading::ReaderLockGuard guard(m_credentialsLock); + const auto &profiles = m_credentialsFileLoader.GetProfiles(); + const auto &iter = profiles.find(profileName); + if (iter == profiles.end()) + { + return {}; + } + return iter->second; + } + + Aws::Map<Aws::String, Aws::Config::Profile> ConfigAndCredentialsCacheManager::GetCredentialsProfiles() const + { + Aws::Utils::Threading::ReaderLockGuard guard(m_credentialsLock); + return m_credentialsFileLoader.GetProfiles(); + } + + Aws::Auth::AWSCredentials ConfigAndCredentialsCacheManager::GetCredentials(const Aws::String& profileName) const + { + Aws::Utils::Threading::ReaderLockGuard guard(m_credentialsLock); + const auto& profiles = m_credentialsFileLoader.GetProfiles(); + const auto &iter = profiles.find(profileName); + if (iter == profiles.end()) + { + return {}; + } + return iter->second.GetCredentials(); + } + + void InitConfigAndCredentialsCacheManager() + { + if (s_configManager) + { + return; + } + s_configManager = Aws::New<ConfigAndCredentialsCacheManager>(CONFIG_CREDENTIALS_CACHE_MANAGER_TAG); + } + + void CleanupConfigAndCredentialsCacheManager() + { + Aws::Delete(s_configManager); + s_configManager = nullptr; + } + + void ReloadCachedConfigFile() + { + assert(s_configManager); + s_configManager->ReloadConfigFile(); + } + + void ReloadCachedCredentialsFile() + { + assert(s_configManager); + s_configManager->ReloadCredentialsFile(); + } + + bool HasCachedConfigProfile(const Aws::String& profileName) + { + assert(s_configManager); + return s_configManager->HasConfigProfile(profileName); + } + + Aws::Config::Profile GetCachedConfigProfile(const Aws::String& profileName) + { + assert(s_configManager); + return s_configManager->GetConfigProfile(profileName); + } + + Aws::Map<Aws::String, Aws::Config::Profile> GetCachedConfigProfiles() + { + assert(s_configManager); + return s_configManager->GetConfigProfiles(); + } + + Aws::String GetCachedConfigValue(const Aws::String &profileName, const Aws::String &key) + { + assert(s_configManager); + return s_configManager->GetConfig(profileName, key); + } + + Aws::String GetCachedConfigValue(const Aws::String &key) + { + assert(s_configManager); + return s_configManager->GetConfig(Aws::Auth::GetConfigProfileName(), key); + } + + bool HasCachedCredentialsProfile(const Aws::String& profileName) + { + assert(s_configManager); + return s_configManager->HasCredentialsProfile(profileName); + } + + Aws::Config::Profile GetCachedCredentialsProfile(const Aws::String &profileName) + { + assert(s_configManager); + return s_configManager->GetCredentialsProfile(profileName); + } + + Aws::Map<Aws::String, Aws::Config::Profile> GetCachedCredentialsProfiles() + { + assert(s_configManager); + return s_configManager->GetCredentialsProfiles(); + } + + Aws::Auth::AWSCredentials GetCachedCredentials(const Aws::String &profileName) + { + assert(s_configManager); + return s_configManager->GetCredentials(profileName); + } + } // Config namespace +} // Aws namespace diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/EC2InstanceProfileConfigLoader.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/EC2InstanceProfileConfigLoader.cpp new file mode 100644 index 00000000000..0b505b2c003 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/EC2InstanceProfileConfigLoader.cpp @@ -0,0 +1,112 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/config/AWSProfileConfigLoader.h> +#include <aws/core/internal/AWSHttpResourceClient.h> +#include <aws/core/auth/AWSCredentialsProvider.h> +#include <aws/core/utils/memory/stl/AWSList.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/utils/json/JsonSerializer.h> +#include <fstream> +#include <random> + +namespace Aws +{ + namespace Config + { + using namespace Aws::Utils; + using namespace Aws::Auth; + + static const char* const INTERNAL_EXCEPTION_PHRASE = "InternalServiceException"; + static const int64_t FIVE_MINUTE_MILLIS = 60000 * 5; + static const int64_t TEN_MINUTE_MILLIS = 60000 * 10; + + static const char* const EC2_INSTANCE_PROFILE_LOG_TAG = "Aws::Config::EC2InstanceProfileConfigLoader"; + + EC2InstanceProfileConfigLoader::EC2InstanceProfileConfigLoader(const std::shared_ptr<Aws::Internal::EC2MetadataClient>& client) + { + if(client == nullptr) + { + Aws::Internal::InitEC2MetadataClient(); + m_ec2metadataClient = Aws::Internal::GetEC2MetadataClient(); + } + else + { + m_ec2metadataClient = client; + } + } + + bool EC2InstanceProfileConfigLoader::LoadInternal() + { + // re-use old credentials until we need to call IMDS again. + if (DateTime::Now().Millis() < this->credentialsValidUntilMillis) { + AWS_LOGSTREAM_ERROR(EC2_INSTANCE_PROFILE_LOG_TAG, + "Skipping IMDS call until " << this->credentialsValidUntilMillis); + return true; + } + this->credentialsValidUntilMillis = DateTime::Now().Millis(); + + if (!m_ec2metadataClient) { + AWS_LOGSTREAM_FATAL(EC2_INSTANCE_PROFILE_LOG_TAG, "EC2MetadataClient is a nullptr!") + return false; + } + auto credentialsStr = m_ec2metadataClient->GetDefaultCredentialsSecurely(); + if(credentialsStr.empty()) return false; + + Json::JsonValue credentialsDoc(credentialsStr); + if (!credentialsDoc.WasParseSuccessful()) + { + AWS_LOGSTREAM_ERROR(EC2_INSTANCE_PROFILE_LOG_TAG, + "Failed to parse output from EC2MetadataService."); + return false; + } + + const char* accessKeyId = "AccessKeyId"; + const char* secretAccessKey = "SecretAccessKey"; + const char* expiration = "Expiration"; + const char* code = "Code"; + Aws::String accessKey, secretKey, token; + + auto credentialsView = credentialsDoc.View(); + DateTime expirationTime(credentialsView.GetString(expiration), Aws::Utils::DateFormat::ISO_8601); + // re-use old credentials and not block if the IMDS call failed or if the latest credential is in the past + if (expirationTime.WasParseSuccessful() && DateTime::Now() > expirationTime) { + AWS_LOGSTREAM_ERROR(EC2_INSTANCE_PROFILE_LOG_TAG, + "Expiration Time of Credentials in the past, refusing to update credentials"); + this->credentialsValidUntilMillis = DateTime::Now().Millis() + calculateRetryTime(); + return true; + } else if (credentialsView.GetString(code) == INTERNAL_EXCEPTION_PHRASE) { + AWS_LOGSTREAM_ERROR(EC2_INSTANCE_PROFILE_LOG_TAG, + "IMDS call failed, refusing to update credentials"); + this->credentialsValidUntilMillis = DateTime::Now().Millis() + calculateRetryTime(); + return true; + } + accessKey = credentialsView.GetString(accessKeyId); + AWS_LOGSTREAM_INFO(EC2_INSTANCE_PROFILE_LOG_TAG, + "Successfully pulled credentials from metadata service with access key " << accessKey); + + secretKey = credentialsView.GetString(secretAccessKey); + token = credentialsView.GetString("Token"); + + auto region = m_ec2metadataClient->GetCurrentRegion(); + + Profile profile; + profile.SetCredentials(AWSCredentials(accessKey, secretKey, token)); + profile.SetRegion(region); + profile.SetName(INSTANCE_PROFILE_KEY); + + m_profiles[INSTANCE_PROFILE_KEY] = profile; + + return true; + } + + int64_t EC2InstanceProfileConfigLoader::calculateRetryTime() const { + std::random_device rd; + std::mt19937_64 gen(rd()); + std::uniform_int_distribution<int64_t> dist(FIVE_MINUTE_MILLIS, TEN_MINUTE_MILLIS); + return dist(gen); + } + } // Config namespace +} // Aws namespace diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/defaults/ClientConfigurationDefaults.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/defaults/ClientConfigurationDefaults.cpp new file mode 100644 index 00000000000..7b54066fb3f --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/defaults/ClientConfigurationDefaults.cpp @@ -0,0 +1,197 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +/** + * Please note that this file is autogenerated. + * The backwards compatibility of the default values provided by new client configuration defaults is not guaranteed; + * the values might change over time. + */ + +#include <aws/common/platform.h> // for AWS_OS_IOS macro +#include <aws/core/config/defaults/ClientConfigurationDefaults.h> +#include <aws/core/config/AWSProfileConfigLoader.h> +#include <aws/core/client/ClientConfiguration.h> +#include <aws/core/internal/AWSHttpResourceClient.h> +#include <aws/core/platform/Environment.h> +#include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/logging/LogMacros.h> + +namespace Aws +{ + namespace Config + { + namespace Defaults + { + static const char* CLIENT_CONFIG_DEFAULTS_TAG = "ClientConfigurationDefaults"; + + void SetSmartDefaultsConfigurationParameters(Aws::Client::ClientConfiguration& clientConfig, + const Aws::String& defaultMode, + bool hasEc2MetadataRegion, + const Aws::String& ec2MetadataRegion) + { + const Aws::String caseInsensitiveMode = ResolveDefaultModeName(clientConfig, + defaultMode, + Aws::Config::GetCachedConfigValue("defaults_mode"), + hasEc2MetadataRegion, + ec2MetadataRegion); + + if(caseInsensitiveMode == "legacy") + { + return SetLegacyClientConfiguration(clientConfig); + } + + if(caseInsensitiveMode == "standard") + { + return SetStandardClientConfiguration(clientConfig); + } + + if(caseInsensitiveMode == "in-region") + { + return SetInRegionClientConfiguration(clientConfig); + } + + if(caseInsensitiveMode == "cross-region") + { + return SetCrossRegionClientConfiguration(clientConfig); + } + + if(caseInsensitiveMode == "mobile") + { + return SetMobileClientConfiguration(clientConfig); + } + return SetLegacyClientConfiguration(clientConfig); + } + + bool isMobile() + { +#if defined(AWS_OS_IOS) || defined (__ANDROID__) + return true; +#else + return false; +#endif + } + + const char* ResolveAutoClientConfiguration(const Aws::Client::ClientConfiguration& clientConfig, + const Aws::String& ec2MetadataRegion) + { + // Check if we're on mobile, CPP SDK is statically built, so we can check how we were built + if(isMobile()) + { + return "mobile"; + } + // We're not on mobile (best we can tell). See if we can determine whether we're an in-region or + // cross-region client. + Aws::String current_region; + Aws::String env_region = Aws::Environment::GetEnv("AWS_DEFAULT_REGION"); + if(!Aws::Environment::GetEnv("AWS_EXECUTION_ENV").empty()) + { + // We're running in an AWS service environment, so we can trust the region environment variables + // to be the current region, if they're set + current_region = Aws::Environment::GetEnv("AWS_REGION"); + if(current_region.empty()) + { + current_region = Aws::Environment::GetEnv("AWS_DEFAULT_REGION"); + } + } + if(current_region.empty()) + { + current_region = ec2MetadataRegion; + } + if(!current_region.empty() && !clientConfig.region.empty()) + { + if(current_region == clientConfig.region) + { + return "in-region"; + } + else + { + return "cross-region"; + } + } + // We don't seem to be mobile, and we couldn't determine whether we're running within an AWS region. + // Fall back to standard. + return "standard"; + } + + void SetLegacyClientConfiguration(Aws::Client::ClientConfiguration& clientConfig) + { + clientConfig.retryStrategy = Aws::Client::InitRetryStrategy("default"); + } + + void SetStandardClientConfiguration(Aws::Client::ClientConfiguration& clientConfig) + { + clientConfig.connectTimeoutMs = 3100; + clientConfig.retryStrategy = Aws::Client::InitRetryStrategy("standard"); + } + + void SetInRegionClientConfiguration(Aws::Client::ClientConfiguration& clientConfig) + { + clientConfig.connectTimeoutMs = 1100; + clientConfig.retryStrategy = Aws::Client::InitRetryStrategy("standard"); + } + + void SetCrossRegionClientConfiguration(Aws::Client::ClientConfiguration& clientConfig) + { + clientConfig.connectTimeoutMs = 3100; + clientConfig.retryStrategy = Aws::Client::InitRetryStrategy("standard"); + } + + void SetMobileClientConfiguration(Aws::Client::ClientConfiguration& clientConfig) + { + clientConfig.connectTimeoutMs = 30000; + clientConfig.retryStrategy = Aws::Client::InitRetryStrategy("standard"); + } + + Aws::String ResolveDefaultModeName(const Aws::Client::ClientConfiguration& clientConfig, + Aws::String requestedDefaultMode, + const Aws::String& configFileDefaultMode, + bool hasEc2MetadataRegion, + Aws::String ec2MetadataRegion) + { + if (requestedDefaultMode.empty()) + { + requestedDefaultMode = Aws::Environment::GetEnv("AWS_DEFAULTS_MODE"); + } + if (requestedDefaultMode.empty()) + { + requestedDefaultMode = configFileDefaultMode; + } + if (Aws::Utils::StringUtils::ToLower(requestedDefaultMode.c_str()) == "auto") + { + if (!hasEc2MetadataRegion && + Aws::Utils::StringUtils::ToLower(Aws::Environment::GetEnv("AWS_EC2_METADATA_DISABLED").c_str()) != "true") + { + auto client = Aws::Internal::GetEC2MetadataClient(); + if (client) + { + ec2MetadataRegion = client->GetCurrentRegion(); + } + } + requestedDefaultMode = ResolveAutoClientConfiguration(clientConfig, ec2MetadataRegion); + return requestedDefaultMode; + } + if (requestedDefaultMode.empty()) + { + requestedDefaultMode = "legacy"; + return requestedDefaultMode; + } + + requestedDefaultMode = Aws::Utils::StringUtils::ToLower(requestedDefaultMode.c_str()); + if (requestedDefaultMode != "legacy" && + requestedDefaultMode != "standard" && + requestedDefaultMode != "in-region" && + requestedDefaultMode != "cross-region" && + requestedDefaultMode != "mobile") + { + AWS_LOGSTREAM_WARN(CLIENT_CONFIG_DEFAULTS_TAG, "User specified client configuration: [" + << requestedDefaultMode + << "] is not found, will use the SDK default legacy one."); + requestedDefaultMode = "legacy"; + } + return requestedDefaultMode; + } + } //namespace Defaults + } //namespace Config +} //namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/AWSEndpoint.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/AWSEndpoint.cpp new file mode 100644 index 00000000000..4990faff243 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/AWSEndpoint.cpp @@ -0,0 +1,86 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/endpoint/AWSEndpoint.h> +#include <aws/core/utils/DNS.h> + +namespace Aws +{ +namespace Endpoint +{ + +Aws::String AWSEndpoint::GetURL() const +{ + return m_uri.GetURIString(); +} + +void AWSEndpoint::SetURL(Aws::String url) +{ + m_uri = std::move(url); +} + +const Aws::Http::URI& AWSEndpoint::GetURI() const +{ + return m_uri; +} + +void AWSEndpoint::SetURI(Aws::Http::URI uri) +{ + m_uri = std::move(uri); +} + +AWSEndpoint::OptionalError AWSEndpoint::AddPrefixIfMissing(const Aws::String& prefix) +{ + if (m_uri.GetAuthority().rfind(prefix, 0) == 0) + { + // uri already starts with a prefix + return OptionalError(); + } + + if (Aws::Utils::IsValidHost(prefix + m_uri.GetAuthority())) + { + m_uri.SetAuthority(prefix + m_uri.GetAuthority()); + return OptionalError(); + } + + return OptionalError( + Aws::Client::AWSError<Aws::Client::CoreErrors>( + Aws::Client::CoreErrors::ENDPOINT_RESOLUTION_FAILURE, "", + Aws::String("Failed to add host prefix, resulting uri is an invalid hostname: ") + prefix + m_uri.GetAuthority(), + false/*retryable*/)); +} + +void AWSEndpoint::SetQueryString(const Aws::String& queryString) +{ + m_uri.SetQueryString(queryString); +} + +const Crt::Optional<AWSEndpoint::EndpointAttributes>& AWSEndpoint::GetAttributes() const +{ + return m_attributes; +} + +Crt::Optional<AWSEndpoint::EndpointAttributes>& AWSEndpoint::AccessAttributes() +{ + return m_attributes; +} + +void AWSEndpoint::SetAttributes(AWSEndpoint::EndpointAttributes&& attributes) +{ + m_attributes = std::move(attributes); +} + +const Aws::UnorderedMap<Aws::String, Aws::String>& AWSEndpoint::GetHeaders() const +{ + return m_headers; +} + +void AWSEndpoint::SetHeaders(Aws::UnorderedMap<Aws::String, Aws::String> headers) +{ + m_headers = std::move(headers); +} + +} // namespace Endpoint +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/AWSPartitions.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/AWSPartitions.cpp new file mode 100644 index 00000000000..bfe3cf6147b --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/AWSPartitions.cpp @@ -0,0 +1,153 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/endpoint/AWSPartitions.h> +#include <aws/core/utils/memory/stl/AWSArray.h> + +namespace Aws +{ +namespace Endpoint +{ +const size_t AWSPartitions::PartitionsBlobStrLen = 3166; +const size_t AWSPartitions::PartitionsBlobSize = 3167; + +using PartitionsBlobT = Aws::Array<const char, AWSPartitions::PartitionsBlobSize>; +static constexpr PartitionsBlobT PartitionsBlob = {{ +'{','"','p','a','r','t','i','t','i','o','n','s','"',':','[','{','"','i','d','"',':','"','a','w','s', +'"',',','"','o','u','t','p','u','t','s','"',':','{','"','d','n','s','S','u','f','f','i','x','"',':', +'"','a','m','a','z','o','n','a','w','s','.','c','o','m','"',',','"','d','u','a','l','S','t','a','c', +'k','D','n','s','S','u','f','f','i','x','"',':','"','a','p','i','.','a','w','s','"',',','"','n','a', +'m','e','"',':','"','a','w','s','"',',','"','s','u','p','p','o','r','t','s','D','u','a','l','S','t', +'a','c','k','"',':','t','r','u','e',',','"','s','u','p','p','o','r','t','s','F','I','P','S','"',':', +'t','r','u','e','}',',','"','r','e','g','i','o','n','R','e','g','e','x','"',':','"','^','(','u','s', +'|','e','u','|','a','p','|','s','a','|','c','a','|','m','e','|','a','f',')','\\','\\','-','\\','\\','w', +'+','\\','\\','-','\\','\\','d','+','$','"',',','"','r','e','g','i','o','n','s','"',':','{','"','a','f', +'-','s','o','u','t','h','-','1','"',':','{','"','d','e','s','c','r','i','p','t','i','o','n','"',':', +'"','A','f','r','i','c','a',' ','(','C','a','p','e',' ','T','o','w','n',')','"','}',',','"','a','p', +'-','e','a','s','t','-','1','"',':','{','"','d','e','s','c','r','i','p','t','i','o','n','"',':','"', +'A','s','i','a',' ','P','a','c','i','f','i','c',' ','(','H','o','n','g',' ','K','o','n','g',')','"', +'}',',','"','a','p','-','n','o','r','t','h','e','a','s','t','-','1','"',':','{','"','d','e','s','c', +'r','i','p','t','i','o','n','"',':','"','A','s','i','a',' ','P','a','c','i','f','i','c',' ','(','T', +'o','k','y','o',')','"','}',',','"','a','p','-','n','o','r','t','h','e','a','s','t','-','2','"',':', +'{','"','d','e','s','c','r','i','p','t','i','o','n','"',':','"','A','s','i','a',' ','P','a','c','i', +'f','i','c',' ','(','S','e','o','u','l',')','"','}',',','"','a','p','-','n','o','r','t','h','e','a', +'s','t','-','3','"',':','{','"','d','e','s','c','r','i','p','t','i','o','n','"',':','"','A','s','i', +'a',' ','P','a','c','i','f','i','c',' ','(','O','s','a','k','a',')','"','}',',','"','a','p','-','s', +'o','u','t','h','-','1','"',':','{','"','d','e','s','c','r','i','p','t','i','o','n','"',':','"','A', +'s','i','a',' ','P','a','c','i','f','i','c',' ','(','M','u','m','b','a','i',')','"','}',',','"','a', +'p','-','s','o','u','t','h','-','2','"',':','{','"','d','e','s','c','r','i','p','t','i','o','n','"', +':','"','A','s','i','a',' ','P','a','c','i','f','i','c',' ','(','H','y','d','e','r','a','b','a','d', +')','"','}',',','"','a','p','-','s','o','u','t','h','e','a','s','t','-','1','"',':','{','"','d','e', +'s','c','r','i','p','t','i','o','n','"',':','"','A','s','i','a',' ','P','a','c','i','f','i','c',' ', +'(','S','i','n','g','a','p','o','r','e',')','"','}',',','"','a','p','-','s','o','u','t','h','e','a', +'s','t','-','2','"',':','{','"','d','e','s','c','r','i','p','t','i','o','n','"',':','"','A','s','i', +'a',' ','P','a','c','i','f','i','c',' ','(','S','y','d','n','e','y',')','"','}',',','"','a','p','-', +'s','o','u','t','h','e','a','s','t','-','3','"',':','{','"','d','e','s','c','r','i','p','t','i','o', +'n','"',':','"','A','s','i','a',' ','P','a','c','i','f','i','c',' ','(','J','a','k','a','r','t','a', +')','"','}',',','"','a','p','-','s','o','u','t','h','e','a','s','t','-','4','"',':','{','"','d','e', +'s','c','r','i','p','t','i','o','n','"',':','"','A','s','i','a',' ','P','a','c','i','f','i','c',' ', +'(','M','e','l','b','o','u','r','n','e',')','"','}',',','"','a','w','s','-','g','l','o','b','a','l', +'"',':','{','"','d','e','s','c','r','i','p','t','i','o','n','"',':','"','A','W','S',' ','S','t','a', +'n','d','a','r','d',' ','g','l','o','b','a','l',' ','r','e','g','i','o','n','"','}',',','"','c','a', +'-','c','e','n','t','r','a','l','-','1','"',':','{','"','d','e','s','c','r','i','p','t','i','o','n', +'"',':','"','C','a','n','a','d','a',' ','(','C','e','n','t','r','a','l',')','"','}',',','"','e','u', +'-','c','e','n','t','r','a','l','-','1','"',':','{','"','d','e','s','c','r','i','p','t','i','o','n', +'"',':','"','E','u','r','o','p','e',' ','(','F','r','a','n','k','f','u','r','t',')','"','}',',','"', +'e','u','-','c','e','n','t','r','a','l','-','2','"',':','{','"','d','e','s','c','r','i','p','t','i', +'o','n','"',':','"','E','u','r','o','p','e',' ','(','Z','u','r','i','c','h',')','"','}',',','"','e', +'u','-','n','o','r','t','h','-','1','"',':','{','"','d','e','s','c','r','i','p','t','i','o','n','"', +':','"','E','u','r','o','p','e',' ','(','S','t','o','c','k','h','o','l','m',')','"','}',',','"','e', +'u','-','s','o','u','t','h','-','1','"',':','{','"','d','e','s','c','r','i','p','t','i','o','n','"', +':','"','E','u','r','o','p','e',' ','(','M','i','l','a','n',')','"','}',',','"','e','u','-','s','o', +'u','t','h','-','2','"',':','{','"','d','e','s','c','r','i','p','t','i','o','n','"',':','"','E','u', +'r','o','p','e',' ','(','S','p','a','i','n',')','"','}',',','"','e','u','-','w','e','s','t','-','1', +'"',':','{','"','d','e','s','c','r','i','p','t','i','o','n','"',':','"','E','u','r','o','p','e',' ', +'(','I','r','e','l','a','n','d',')','"','}',',','"','e','u','-','w','e','s','t','-','2','"',':','{', +'"','d','e','s','c','r','i','p','t','i','o','n','"',':','"','E','u','r','o','p','e',' ','(','L','o', +'n','d','o','n',')','"','}',',','"','e','u','-','w','e','s','t','-','3','"',':','{','"','d','e','s', +'c','r','i','p','t','i','o','n','"',':','"','E','u','r','o','p','e',' ','(','P','a','r','i','s',')', +'"','}',',','"','m','e','-','c','e','n','t','r','a','l','-','1','"',':','{','"','d','e','s','c','r', +'i','p','t','i','o','n','"',':','"','M','i','d','d','l','e',' ','E','a','s','t',' ','(','U','A','E', +')','"','}',',','"','m','e','-','s','o','u','t','h','-','1','"',':','{','"','d','e','s','c','r','i', +'p','t','i','o','n','"',':','"','M','i','d','d','l','e',' ','E','a','s','t',' ','(','B','a','h','r', +'a','i','n',')','"','}',',','"','s','a','-','e','a','s','t','-','1','"',':','{','"','d','e','s','c', +'r','i','p','t','i','o','n','"',':','"','S','o','u','t','h',' ','A','m','e','r','i','c','a',' ','(', +'S','a','o',' ','P','a','u','l','o',')','"','}',',','"','u','s','-','e','a','s','t','-','1','"',':', +'{','"','d','e','s','c','r','i','p','t','i','o','n','"',':','"','U','S',' ','E','a','s','t',' ','(', +'N','.',' ','V','i','r','g','i','n','i','a',')','"','}',',','"','u','s','-','e','a','s','t','-','2', +'"',':','{','"','d','e','s','c','r','i','p','t','i','o','n','"',':','"','U','S',' ','E','a','s','t', +' ','(','O','h','i','o',')','"','}',',','"','u','s','-','w','e','s','t','-','1','"',':','{','"','d', +'e','s','c','r','i','p','t','i','o','n','"',':','"','U','S',' ','W','e','s','t',' ','(','N','.',' ', +'C','a','l','i','f','o','r','n','i','a',')','"','}',',','"','u','s','-','w','e','s','t','-','2','"', +':','{','"','d','e','s','c','r','i','p','t','i','o','n','"',':','"','U','S',' ','W','e','s','t',' ', +'(','O','r','e','g','o','n',')','"','}','}','}',',','{','"','i','d','"',':','"','a','w','s','-','c', +'n','"',',','"','o','u','t','p','u','t','s','"',':','{','"','d','n','s','S','u','f','f','i','x','"', +':','"','a','m','a','z','o','n','a','w','s','.','c','o','m','.','c','n','"',',','"','d','u','a','l', +'S','t','a','c','k','D','n','s','S','u','f','f','i','x','"',':','"','a','p','i','.','a','m','a','z', +'o','n','w','e','b','s','e','r','v','i','c','e','s','.','c','o','m','.','c','n','"',',','"','n','a', +'m','e','"',':','"','a','w','s','-','c','n','"',',','"','s','u','p','p','o','r','t','s','D','u','a', +'l','S','t','a','c','k','"',':','t','r','u','e',',','"','s','u','p','p','o','r','t','s','F','I','P', +'S','"',':','t','r','u','e','}',',','"','r','e','g','i','o','n','R','e','g','e','x','"',':','"','^', +'c','n','\\','\\','-','\\','\\','w','+','\\','\\','-','\\','\\','d','+','$','"',',','"','r','e','g','i','o', +'n','s','"',':','{','"','a','w','s','-','c','n','-','g','l','o','b','a','l','"',':','{','"','d','e', +'s','c','r','i','p','t','i','o','n','"',':','"','A','W','S',' ','C','h','i','n','a',' ','g','l','o', +'b','a','l',' ','r','e','g','i','o','n','"','}',',','"','c','n','-','n','o','r','t','h','-','1','"', +':','{','"','d','e','s','c','r','i','p','t','i','o','n','"',':','"','C','h','i','n','a',' ','(','B', +'e','i','j','i','n','g',')','"','}',',','"','c','n','-','n','o','r','t','h','w','e','s','t','-','1', +'"',':','{','"','d','e','s','c','r','i','p','t','i','o','n','"',':','"','C','h','i','n','a',' ','(', +'N','i','n','g','x','i','a',')','"','}','}','}',',','{','"','i','d','"',':','"','a','w','s','-','u', +'s','-','g','o','v','"',',','"','o','u','t','p','u','t','s','"',':','{','"','d','n','s','S','u','f', +'f','i','x','"',':','"','a','m','a','z','o','n','a','w','s','.','c','o','m','"',',','"','d','u','a', +'l','S','t','a','c','k','D','n','s','S','u','f','f','i','x','"',':','"','a','p','i','.','a','w','s', +'"',',','"','n','a','m','e','"',':','"','a','w','s','-','u','s','-','g','o','v','"',',','"','s','u', +'p','p','o','r','t','s','D','u','a','l','S','t','a','c','k','"',':','t','r','u','e',',','"','s','u', +'p','p','o','r','t','s','F','I','P','S','"',':','t','r','u','e','}',',','"','r','e','g','i','o','n', +'R','e','g','e','x','"',':','"','^','u','s','\\','\\','-','g','o','v','\\','\\','-','\\','\\','w','+','\\', +'\\','-','\\','\\','d','+','$','"',',','"','r','e','g','i','o','n','s','"',':','{','"','a','w','s','-', +'u','s','-','g','o','v','-','g','l','o','b','a','l','"',':','{','"','d','e','s','c','r','i','p','t', +'i','o','n','"',':','"','A','W','S',' ','G','o','v','C','l','o','u','d',' ','(','U','S',')',' ','g', +'l','o','b','a','l',' ','r','e','g','i','o','n','"','}',',','"','u','s','-','g','o','v','-','e','a', +'s','t','-','1','"',':','{','"','d','e','s','c','r','i','p','t','i','o','n','"',':','"','A','W','S', +' ','G','o','v','C','l','o','u','d',' ','(','U','S','-','E','a','s','t',')','"','}',',','"','u','s', +'-','g','o','v','-','w','e','s','t','-','1','"',':','{','"','d','e','s','c','r','i','p','t','i','o', +'n','"',':','"','A','W','S',' ','G','o','v','C','l','o','u','d',' ','(','U','S','-','W','e','s','t', +')','"','}','}','}',',','{','"','i','d','"',':','"','a','w','s','-','i','s','o','"',',','"','o','u', +'t','p','u','t','s','"',':','{','"','d','n','s','S','u','f','f','i','x','"',':','"','c','2','s','.', +'i','c','.','g','o','v','"',',','"','d','u','a','l','S','t','a','c','k','D','n','s','S','u','f','f', +'i','x','"',':','"','c','2','s','.','i','c','.','g','o','v','"',',','"','n','a','m','e','"',':','"', +'a','w','s','-','i','s','o','"',',','"','s','u','p','p','o','r','t','s','D','u','a','l','S','t','a', +'c','k','"',':','f','a','l','s','e',',','"','s','u','p','p','o','r','t','s','F','I','P','S','"',':', +'t','r','u','e','}',',','"','r','e','g','i','o','n','R','e','g','e','x','"',':','"','^','u','s','\\', +'\\','-','i','s','o','\\','\\','-','\\','\\','w','+','\\','\\','-','\\','\\','d','+','$','"',',','"','r','e', +'g','i','o','n','s','"',':','{','"','a','w','s','-','i','s','o','-','g','l','o','b','a','l','"',':', +'{','"','d','e','s','c','r','i','p','t','i','o','n','"',':','"','A','W','S',' ','I','S','O',' ','(', +'U','S',')',' ','g','l','o','b','a','l',' ','r','e','g','i','o','n','"','}',',','"','u','s','-','i', +'s','o','-','e','a','s','t','-','1','"',':','{','"','d','e','s','c','r','i','p','t','i','o','n','"', +':','"','U','S',' ','I','S','O',' ','E','a','s','t','"','}',',','"','u','s','-','i','s','o','-','w', +'e','s','t','-','1','"',':','{','"','d','e','s','c','r','i','p','t','i','o','n','"',':','"','U','S', +' ','I','S','O',' ','W','E','S','T','"','}','}','}',',','{','"','i','d','"',':','"','a','w','s','-', +'i','s','o','-','b','"',',','"','o','u','t','p','u','t','s','"',':','{','"','d','n','s','S','u','f', +'f','i','x','"',':','"','s','c','2','s','.','s','g','o','v','.','g','o','v','"',',','"','d','u','a', +'l','S','t','a','c','k','D','n','s','S','u','f','f','i','x','"',':','"','s','c','2','s','.','s','g', +'o','v','.','g','o','v','"',',','"','n','a','m','e','"',':','"','a','w','s','-','i','s','o','-','b', +'"',',','"','s','u','p','p','o','r','t','s','D','u','a','l','S','t','a','c','k','"',':','f','a','l', +'s','e',',','"','s','u','p','p','o','r','t','s','F','I','P','S','"',':','t','r','u','e','}',',','"', +'r','e','g','i','o','n','R','e','g','e','x','"',':','"','^','u','s','\\','\\','-','i','s','o','b','\\', +'\\','-','\\','\\','w','+','\\','\\','-','\\','\\','d','+','$','"',',','"','r','e','g','i','o','n','s','"', +':','{','"','a','w','s','-','i','s','o','-','b','-','g','l','o','b','a','l','"',':','{','"','d','e', +'s','c','r','i','p','t','i','o','n','"',':','"','A','W','S',' ','I','S','O','B',' ','(','U','S',')', +' ','g','l','o','b','a','l',' ','r','e','g','i','o','n','"','}',',','"','u','s','-','i','s','o','b', +'-','e','a','s','t','-','1','"',':','{','"','d','e','s','c','r','i','p','t','i','o','n','"',':','"', +'U','S',' ','I','S','O','B',' ','E','a','s','t',' ','(','O','h','i','o',')','"','}','}','}',']',',', +'"','v','e','r','s','i','o','n','"',':','"','1','.','1','"','}','\0' +}}; + +const char* AWSPartitions::GetPartitionsBlob() +{ + return PartitionsBlob.data(); +} + +} // namespace Endpoint +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/BuiltInParameters.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/BuiltInParameters.cpp new file mode 100644 index 00000000000..43c3e2f0f94 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/BuiltInParameters.cpp @@ -0,0 +1,135 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/endpoint/BuiltInParameters.h> +#include <aws/core/utils/logging/LogMacros.h> + +static const char ENDPOINT_BUILTIN_LOG_TAG[] = "EndpointBuiltInParameters"; + +namespace Aws +{ +namespace Endpoint +{ + void BuiltInParameters::OverrideEndpoint(const Aws::String& endpoint, const Aws::Http::Scheme& scheme) + { + static const char* SDK_ENDPOINT = "Endpoint"; + + if (endpoint.compare(0, 7, "http://") == 0 || endpoint.compare(0, 8, "https://") == 0) + { + SetStringParameter(SDK_ENDPOINT, endpoint); + } + else + { + SetStringParameter(SDK_ENDPOINT, Aws::String(Aws::Http::SchemeMapper::ToString(scheme)) + "://" + endpoint); + } + } + + bool StringEndsWith(const Aws::String& str, const Aws::String& suffix) + { + if (suffix.size() > str.size()) + return false; + return std::equal(suffix.rbegin(), suffix.rend(), str.rbegin()); + } + + void BuiltInParameters::SetFromClientConfiguration(const Client::ClientConfiguration& config) + { + bool forceFIPS = false; + static const char* AWS_REGION = "Region"; + if (!config.region.empty()) { + static const char* FIPS_PREFIX = "fips-"; + static const char* FIPS_SUFFIX = "-fips"; + if (config.region.rfind(FIPS_PREFIX, 0) == 0) { + // Backward compatibility layer for code hacking previous SDK version + Aws::String regionOverride = config.region.substr(sizeof(FIPS_PREFIX) - 1); + forceFIPS = true; + SetStringParameter(AWS_REGION, regionOverride); + } else if (StringEndsWith(config.region, FIPS_SUFFIX)) { + Aws::String regionOverride = config.region.substr(0, config.region.size() - sizeof(FIPS_SUFFIX) - 1); + forceFIPS = true; + SetStringParameter(AWS_REGION, regionOverride); + } else { + SetStringParameter(AWS_REGION, config.region); + } + } + + static const char* AWS_USE_FIPS = "UseFIPS"; + SetBooleanParameter(AWS_USE_FIPS, config.useFIPS || forceFIPS); + + static const char* AWS_USE_DUAL_STACK = "UseDualStack"; + SetBooleanParameter(AWS_USE_DUAL_STACK, config.useDualStack); + + if (!config.endpointOverride.empty()) { + OverrideEndpoint(config.endpointOverride, config.scheme); + + if (config.region.empty()) { + AWS_LOGSTREAM_WARN(ENDPOINT_BUILTIN_LOG_TAG, + "Endpoint is overridden but region is not set. " + "Region is required my many endpoint rule sets to resolve the endpoint. " + "And it is required to compute an aws signature."); + SetStringParameter(AWS_REGION, "region-not-set"); // dummy endpoint resolution parameter + } + } + } + + void BuiltInParameters::SetFromClientConfiguration(const Client::GenericClientConfiguration<false>& config) + { + return SetFromClientConfiguration(static_cast<const Client::ClientConfiguration&>(config)); + } + + void BuiltInParameters::SetFromClientConfiguration(const Client::GenericClientConfiguration<true>& config) + { + SetFromClientConfiguration(static_cast<const Client::ClientConfiguration&>(config)); + } + + const BuiltInParameters::EndpointParameter& BuiltInParameters::GetParameter(const Aws::String& name) const + { + const auto foundIt = std::find_if(m_params.begin(), m_params.end(), + [name](const BuiltInParameters::EndpointParameter& item) + { + return item.GetName() == name; + }); + + if (foundIt != m_params.end()) + { + return *foundIt; + } + else + { + static const BuiltInParameters::EndpointParameter BUILTIN_NOT_FOUND_PARAMETER("PARAMETER_NOT_SET", false, EndpointParameter::ParameterOrigin::CLIENT_CONTEXT); + return BUILTIN_NOT_FOUND_PARAMETER; + } + } + + void BuiltInParameters::SetParameter(EndpointParameter param) + { + const auto foundIt = std::find_if(m_params.begin(), m_params.end(), + [param](const BuiltInParameters::EndpointParameter& item) + { + return item.GetName() == param.GetName(); + }); + + if (foundIt != m_params.end()) + { + m_params.erase(foundIt); + } + m_params.emplace_back(std::move(param)); + } + + void BuiltInParameters::SetStringParameter(Aws::String name, Aws::String value) + { + return SetParameter(EndpointParameter(std::move(name), std::move(value), EndpointParameter::ParameterOrigin::BUILT_IN)); + } + + void BuiltInParameters::SetBooleanParameter(Aws::String name, bool value) + { + return SetParameter(EndpointParameter(std::move(name), value, EndpointParameter::ParameterOrigin::BUILT_IN)); + } + + const Aws::Vector<BuiltInParameters::EndpointParameter>& BuiltInParameters::GetAllParameters() const + { + return m_params; + } +} // namespace Endpoint +} // namespace Aws
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/ClientContextParameters.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/ClientContextParameters.cpp new file mode 100644 index 00000000000..cdff71f6698 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/ClientContextParameters.cpp @@ -0,0 +1,61 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/endpoint/ClientContextParameters.h> + +namespace Aws +{ +namespace Endpoint +{ + const ClientContextParameters::EndpointParameter& ClientContextParameters::GetParameter(const Aws::String& name) const + { + const auto foundIt = std::find_if(m_params.begin(), m_params.end(), + [name](const ClientContextParameters::EndpointParameter& item) + { + return item.GetName() == name; + }); + + if (foundIt != m_params.end()) + { + return *foundIt; + } + else + { + static const ClientContextParameters::EndpointParameter CTX_NOT_FOUND_PARAMETER("PARAMETER_NOT_SET", false, EndpointParameter::ParameterOrigin::CLIENT_CONTEXT); + return CTX_NOT_FOUND_PARAMETER; + } + } + + void ClientContextParameters::SetParameter(EndpointParameter param) + { + const auto foundIt = std::find_if(m_params.begin(), m_params.end(), + [param](const ClientContextParameters::EndpointParameter& item) + { + return item.GetName() == param.GetName(); + }); + + if (foundIt != m_params.end()) + { + m_params.erase(foundIt); + } + m_params.emplace_back(std::move(param)); + } + + void ClientContextParameters::SetStringParameter(Aws::String name, Aws::String value) + { + return SetParameter(EndpointParameter(std::move(name), std::move(value), EndpointParameter::ParameterOrigin::CLIENT_CONTEXT)); + } + + void ClientContextParameters::SetBooleanParameter(Aws::String name, bool value) + { + return SetParameter(EndpointParameter(std::move(name), value, EndpointParameter::ParameterOrigin::CLIENT_CONTEXT)); + } + + const Aws::Vector<ClientContextParameters::EndpointParameter>& ClientContextParameters::GetAllParameters() const + { + return m_params; + } +} // namespace Endpoint +} // namespace Aws
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/DefaultEndpointProvider.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/DefaultEndpointProvider.cpp new file mode 100644 index 00000000000..58370cd4256 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/DefaultEndpointProvider.cpp @@ -0,0 +1,236 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/endpoint/DefaultEndpointProvider.h> +#include <aws/core/utils/memory/stl/AWSMap.h> +#include <aws/crt/Api.h> + +namespace Aws +{ +namespace Endpoint +{ + +/** + * Export endpoint provider symbols from DLL + */ +template class AWS_CORE_API DefaultEndpointProvider<Aws::Client::GenericClientConfiguration<false>, + Aws::Endpoint::BuiltInParameters, + Aws::Endpoint::ClientContextParameters>; + +char CharToDec(const char c) +{ + if(c >= '0' && c <= '9') + return c - '0'; + if(c >= 'A' && c <= 'F') + return c - 'A' + 10; + if(c >= 'a' && c <= 'f') + return c - 'a' + 10; + return 0; +} + +Aws::String PercentDecode(Aws::String inputString) +{ + if (inputString.find_first_of("%") == Aws::String::npos) + { + return inputString; + } + Aws::String result; + result.reserve(inputString.size()); + + bool percentFound = false; + char firstOctet = 0; + char secondOctet = 0; + for(size_t i = 0; i < inputString.size(); ++i) + { + const char currentChar = inputString[i]; + if ('%' == currentChar) + { + if (percentFound) + { + // not percent-encoded string + result += currentChar; + } + percentFound = true; + continue; + } + + if (percentFound) + { + if ((currentChar >= '0' && currentChar <= '9') || + (currentChar >= 'A' && currentChar <= 'F') || + (currentChar >= 'a' && currentChar <= 'f')) + { + if(!firstOctet) + { + firstOctet = currentChar; + continue; + } + if(!secondOctet) + { + secondOctet = currentChar; + char encodedChar = CharToDec(firstOctet) * 16 + CharToDec(secondOctet); + result += encodedChar; + + percentFound = false; + firstOctet = 0; + secondOctet = 0; + continue; + } + } else { + // Non-percent encoded sequence + result += '%'; + if(!firstOctet) + result += firstOctet; + result += currentChar; + percentFound = false; + firstOctet = 0; + secondOctet = 0; + continue; + } + } + + if ('+' == currentChar) + { + result += ' '; + continue; + } + result += currentChar; + } + return result; +} + +AWS_CORE_API ResolveEndpointOutcome +ResolveEndpointDefaultImpl(const Aws::Crt::Endpoints::RuleEngine& ruleEngine, + const EndpointParameters& builtInParameters, + const EndpointParameters& clientContextParameters, + const EndpointParameters& endpointParameters) +{ + if(!ruleEngine) { + AWS_LOGSTREAM_FATAL(DEFAULT_ENDPOINT_PROVIDER_TAG, "Invalid CRT Rule Engine state"); + return ResolveEndpointOutcome( + Aws::Client::AWSError<Aws::Client::CoreErrors>( + Aws::Client::CoreErrors::INTERNAL_FAILURE, + "", + "CRT Endpoint rule engine is not initialized", + false/*retryable*/)); + } + + Aws::Crt::Endpoints::RequestContext crtRequestCtx; + + const Aws::Vector<std::reference_wrapper<const EndpointParameters>> allParameters + = {std::cref(builtInParameters), std::cref(clientContextParameters), std::cref(endpointParameters)}; + + for (const auto& parameterClass : allParameters) + { + for(const auto& parameter : parameterClass.get()) + { + if(EndpointParameter::ParameterType::BOOLEAN == parameter.GetStoredType()) + { + AWS_LOGSTREAM_TRACE(DEFAULT_ENDPOINT_PROVIDER_TAG, "Endpoint bool eval parameter: " << parameter.GetName() << " = " << parameter.GetBoolValueNoCheck()); + crtRequestCtx.AddBoolean(Aws::Crt::ByteCursorFromCString(parameter.GetName().c_str()), parameter.GetBoolValueNoCheck()); + } + else if(EndpointParameter::ParameterType::STRING == parameter.GetStoredType()) + { + AWS_LOGSTREAM_TRACE(DEFAULT_ENDPOINT_PROVIDER_TAG, "Endpoint str eval parameter: " << parameter.GetName() << " = " << parameter.GetStrValueNoCheck()); + crtRequestCtx.AddString(Aws::Crt::ByteCursorFromCString(parameter.GetName().c_str()), Aws::Crt::ByteCursorFromCString(parameter.GetStrValueNoCheck().c_str())); + } + else + { + return ResolveEndpointOutcome( + Aws::Client::AWSError<Aws::Client::CoreErrors>( + Aws::Client::CoreErrors::INVALID_QUERY_PARAMETER, + "", + "Invalid endpoint parameter type for parameter " + parameter.GetName(), + false/*retryable*/)); + } + } + } + + auto resolved = ruleEngine.Resolve(crtRequestCtx); + + if(resolved.has_value()) + { + if(resolved->IsError()) + { + auto crtError = resolved->GetError(); + Aws::String sdkCrtError = crtError ? Aws::String(crtError->begin(), crtError->end()) : + "CRT Rule engine resolution resulted in an unknown error"; + return ResolveEndpointOutcome( + Aws::Client::AWSError<Aws::Client::CoreErrors>( + Aws::Client::CoreErrors::INVALID_PARAMETER_COMBINATION, + "", + sdkCrtError, + false/*retryable*/)); + } + else if(resolved->IsEndpoint() && resolved->GetUrl()) + { + Aws::Endpoint::AWSEndpoint endpoint; + const auto crtUrl = resolved->GetUrl(); + Aws::String sdkCrtUrl = Aws::String(crtUrl->begin(), crtUrl->end()); + AWS_LOGSTREAM_DEBUG(DEFAULT_ENDPOINT_PROVIDER_TAG, "Endpoint rules engine evaluated the endpoint: " << sdkCrtUrl); + endpoint.SetURL(PercentDecode(std::move(sdkCrtUrl))); + + // Transform attributes + // Each attribute consist of properties, hence converting CRT properties to SDK attributes + const auto crtProps = resolved->GetProperties(); + if (crtProps && crtProps->size() > 2) { + Aws::String sdkCrtProps = crtProps ? Aws::String(crtProps->begin(), crtProps->end()) : ""; + AWS_LOGSTREAM_TRACE(DEFAULT_ENDPOINT_PROVIDER_TAG, "Endpoint rules evaluated props: " << sdkCrtProps); + + Internal::Endpoint::EndpointAttributes epAttributes = Internal::Endpoint::EndpointAttributes::BuildEndpointAttributesFromJson( + sdkCrtProps); + + endpoint.SetAttributes(std::move(epAttributes)); + } + + // transform headers + const auto crtHeaders = resolved->GetHeaders(); + if (crtHeaders) + { + Aws::UnorderedMap<Aws::String, Aws::String> sdkHeaders; + for (const auto& header: *crtHeaders) + { + Aws::String key(header.first.begin(), header.first.end()); + Aws::String value; + for (const auto& crtHeaderValue : header.second) + { + if(!value.empty()) { + value.insert(value.end(), ';'); + } + value.insert(value.end(), crtHeaderValue.begin(), crtHeaderValue.end()); + } + sdkHeaders.emplace(std::move(key), std::move(value)); + } + + endpoint.SetHeaders(std::move(sdkHeaders)); + } + + return ResolveEndpointOutcome(std::move(endpoint)); + } + else + { + return ResolveEndpointOutcome( + Aws::Client::AWSError<Aws::Client::CoreErrors>( + Aws::Client::CoreErrors::INVALID_QUERY_PARAMETER, + "", + "Invalid AWS CRT RuleEngine state", + false/*retryable*/)); + } + } + + auto errCode = Aws::Crt::LastError(); + AWS_LOGSTREAM_DEBUG(DEFAULT_ENDPOINT_PROVIDER_TAG, "ERROR: Rule engine has failed to evaluate the endpoint: " << errCode << " " << Aws::Crt::ErrorDebugString(errCode)); + + return ResolveEndpointOutcome( + Aws::Client::AWSError<Aws::Client::CoreErrors>( + Aws::Client::CoreErrors::INVALID_QUERY_PARAMETER, + "", + "Failed to evaluate the endpoint: null output from AWS CRT RuleEngine", + false/*retryable*/)); + +} + +} // namespace Endpoint +} // namespace Aws
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/EndpointProviderBase.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/EndpointProviderBase.cpp new file mode 100644 index 00000000000..0928186839a --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/EndpointProviderBase.cpp @@ -0,0 +1,20 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/endpoint/EndpointProviderBase.h> + +namespace Aws +{ +namespace Endpoint +{ +/** + * Export endpoint provider symbols from DLL + */ +template class AWS_CORE_API EndpointProviderBase<Aws::Client::GenericClientConfiguration<false>, + Aws::Endpoint::BuiltInParameters, + Aws::Endpoint::ClientContextParameters>; + +} // namespace Endpoint +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/internal/AWSEndpointAttribute.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/internal/AWSEndpointAttribute.cpp new file mode 100644 index 00000000000..5c295bb1325 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/endpoint/internal/AWSEndpointAttribute.cpp @@ -0,0 +1,82 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/endpoint/internal/AWSEndpointAttribute.h> +#include <aws/core/utils/logging/LogMacros.h> + +static const char ENDPOINT_AUTH_SCHEME_TAG[] = "EndpointAuthScheme::BuildEndpointAuthSchemeFromJson"; + +Aws::String CrtToSdkSignerName(const Aws::String& crtSignerName) +{ + Aws::String sdkSigner = "NullSigner"; + if (crtSignerName == "sigv4") { + sdkSigner = "SignatureV4"; + } else if (crtSignerName == "sigv4a") { + sdkSigner = "AsymmetricSignatureV4"; + } else if (crtSignerName == "none") { + sdkSigner = "NullSigner"; + } else if (crtSignerName == "bearer") { + sdkSigner = "Bearer"; + } else { + AWS_LOG_WARN(ENDPOINT_AUTH_SCHEME_TAG, (Aws::String("Unknown Endpoint authSchemes signer: ") + crtSignerName).c_str()); + } + + return sdkSigner; +} + +Aws::Internal::Endpoint::EndpointAttributes +Aws::Internal::Endpoint::EndpointAttributes::BuildEndpointAttributesFromJson(const Aws::String& iJsonStr) +{ + Aws::Internal::Endpoint::EndpointAttributes attributes; + Aws::Internal::Endpoint::EndpointAuthScheme& authScheme = attributes.authScheme; + + Utils::Json::JsonValue jsonObject(iJsonStr); + if (jsonObject.WasParseSuccessful()) + { + Aws::Map<Aws::String, Utils::Json::JsonView> jsonMap = jsonObject.View().GetAllObjects(); + for (const auto& mapItemAttribute : jsonMap) + { + if (mapItemAttribute.first == "authSchemes" && mapItemAttribute.second.IsListType()) { + Aws::Utils::Array<Utils::Json::JsonView> jsonAuthSchemeArray = mapItemAttribute.second.AsArray(); + + for (size_t arrayIdx = 0; arrayIdx < jsonAuthSchemeArray.GetLength(); ++arrayIdx) + { + const Utils::Json::JsonView& property = jsonAuthSchemeArray.GetItem(arrayIdx); + for (const auto& mapItemProperty : property.GetAllObjects()) + { + if (mapItemProperty.first == "name") { + authScheme.SetName(CrtToSdkSignerName(mapItemProperty.second.AsString())); + } else if (mapItemProperty.first == "signingName") { + authScheme.SetSigningName(mapItemProperty.second.AsString()); + } else if (mapItemProperty.first == "signingRegion") { + authScheme.SetSigningRegion(mapItemProperty.second.AsString()); + } else if (mapItemProperty.first == "signingRegionSet") { + Aws::Utils::Array<Utils::Json::JsonView> signingRegionArray = mapItemProperty.second.AsArray(); + if (signingRegionArray.GetLength() != 1) { + AWS_LOG_WARN(ENDPOINT_AUTH_SCHEME_TAG, + "Signing region set size is not equal to 1"); + } + if (signingRegionArray.GetLength() > 0) { + authScheme.SetSigningRegionSet(signingRegionArray.GetItem(0).AsString()); + } + } else if (mapItemProperty.first == "disableDoubleEncoding") { + authScheme.SetDisableDoubleEncoding(mapItemProperty.second.AsBool()); + } else { + AWS_LOG_WARN(ENDPOINT_AUTH_SCHEME_TAG, Aws::String("Unknown Endpoint authSchemes attribute property: " + mapItemProperty.first).c_str()); + } + } + } + } else { + AWS_LOG_WARN(ENDPOINT_AUTH_SCHEME_TAG, Aws::String("Unknown Endpoint Attribute: " + mapItemAttribute.first).c_str()); + } + } + } + else + { + AWS_LOGSTREAM_ERROR(ENDPOINT_AUTH_SCHEME_TAG, "Json Parse failed with message: " << jsonObject.GetErrorMessage()); + } + + return attributes; +}
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/cjson/cJSON.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/cjson/cJSON.cpp index d21a2e7d86b..cdcbf103e7c 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/cjson/cJSON.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/cjson/cJSON.cpp @@ -85,12 +85,19 @@ typedef struct { const unsigned char *json; size_t position; } error; +/* + * NOTE: the use of this static global variable is not thread-safe, + * hence writing to / reading from it is disabled in this code. + * + * See https://cjson.docsforge.com/#thread-safety (concurrent reads) + * See https://github.com/aws/aws-sdk-cpp/pull/2231 (concurrent writes) static error global_error = { NULL, 0 }; CJSON_AS4CPP_PUBLIC(const char *) cJSON_AS4CPP_GetErrorPtr(void) { return (const char*) (global_error.json + global_error.position); } + */ CJSON_AS4CPP_PUBLIC(char *) cJSON_AS4CPP_GetStringValue(const cJSON * const item) { @@ -120,7 +127,7 @@ CJSON_AS4CPP_PUBLIC(double) cJSON_AS4CPP_GetNumberValue(const cJSON * const item CJSON_AS4CPP_PUBLIC(const char*) cJSON_AS4CPP_Version(void) { static char version[15]; - sprintf(version, "%i.%i.%i", CJSON_AS4CPP_VERSION_MAJOR, CJSON_AS4CPP_VERSION_MINOR, CJSON_AS4CPP_VERSION_PATCH); + snprintf(version, sizeof(version), "%i.%i.%i", CJSON_AS4CPP_VERSION_MAJOR, CJSON_AS4CPP_VERSION_MINOR, CJSON_AS4CPP_VERSION_PATCH); return version; } @@ -569,27 +576,27 @@ static cJSON_AS4CPP_bool print_number(const cJSON * const item, printbuffer * co /* For integer which is out of the range of [INT_MIN, INT_MAX], valuestring is an integer literal. */ if (item->valuestring) { - length = sprintf((char*)number_buffer, "%s", item->valuestring); + length = snprintf((char*)number_buffer, sizeof(number_buffer), "%s", item->valuestring); } /* This checks for NaN and Infinity */ else if (isnan(d) || isinf(d)) { - length = sprintf((char*)number_buffer, "null"); + length = snprintf((char*)number_buffer, sizeof(number_buffer), "null"); } else { /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */ - length = sprintf((char*)number_buffer, "%1.15g", d); + length = snprintf((char*)number_buffer, sizeof(number_buffer), "%1.15g", d); /* Check whether the original double can be recovered */ if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d)) { /* If not, print with 17 decimal places of precision */ - length = sprintf((char*)number_buffer, "%1.17g", d); + length = snprintf((char*)number_buffer, sizeof(number_buffer), "%1.17g", d); } } - /* sprintf failed or buffer overrun occurred */ + /* snprintf failed or buffer overrun occurred */ if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1))) { return false; @@ -1018,7 +1025,7 @@ static cJSON_AS4CPP_bool print_string_ptr(const unsigned char * const input, pri break; default: /* escape and print as unicode codepoint */ - sprintf((char*)output_pointer, "u%04x", *input_pointer); + snprintf((char*)output_pointer, output_buffer->length - (output_pointer - output_buffer->buffer), "u%04x", *input_pointer); output_pointer += 4; break; } @@ -1107,9 +1114,13 @@ CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_ParseWithLengthOpts(const char *value, parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } }; cJSON *item = NULL; - /* reset error position */ + /* reset error position + * + * NOTE: disabled due to thread safety (see note at the top of this file). + * global_error.json = NULL; global_error.position = 0; + */ if (value == NULL || 0 == buffer_length) { @@ -1175,7 +1186,9 @@ fail: *return_parse_end = (const char*)local_error.json + local_error.position; } + /* NOTE: disabled due to thread safety (see note at the top of this file). global_error = local_error; + */ } return NULL; @@ -2470,7 +2483,7 @@ CJSON_AS4CPP_PUBLIC(cJSON *) cJSON_AS4CPP_CreateInt64(long long num) if (num > INT_MAX || num < INT_MIN) { char buf[21]; - sprintf(buf, "%lld", num); + snprintf(buf, sizeof(buf), "%lld", num); item->valuestring = (char*)cJSON_AS4CPP_strdup((const unsigned char*)buf, &global_hooks); } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/tinyxml2/tinyxml2.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/tinyxml2/tinyxml2.cpp index ebe0fd9eec0..151a3686765 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/tinyxml2/tinyxml2.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/tinyxml2/tinyxml2.cpp @@ -135,13 +135,15 @@ struct Entity { char value; }; -static const int NUM_ENTITIES = 5; +static const int NUM_ENTITIES = 7; static const Entity entities[NUM_ENTITIES] = { - { "quot", 4, DOUBLE_QUOTE }, - { "amp", 3, '&' }, - { "apos", 4, SINGLE_QUOTE }, - { "lt", 2, '<' }, - { "gt", 2, '>' } + { "quot", 4, DOUBLE_QUOTE }, + { "amp", 3, '&' }, + { "apos", 4, SINGLE_QUOTE }, + { "lt", 2, '<' }, + { "gt", 2, '>' }, + { "#xA", 3, LF }, + { "#xD", 3, CR } }; @@ -2396,6 +2398,8 @@ XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) : _restrictedEntityFlag[(unsigned char)'&'] = true; _restrictedEntityFlag[(unsigned char)'<'] = true; _restrictedEntityFlag[(unsigned char)'>'] = true; // not required, but consistency is nice + _restrictedEntityFlag[(unsigned char)LF] = true; + _restrictedEntityFlag[(unsigned char)CR] = true; _buffer.Push( 0 ); } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClientFactory.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClientFactory.cpp index a556e39a5d8..a08b21f9b58 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClientFactory.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClientFactory.cpp @@ -121,9 +121,11 @@ namespace Aws void InitStaticState() override { + AWS_LOGSTREAM_DEBUG(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, "Initializing Http Static State"); #if ENABLE_CURL_CLIENT if(s_InitCleanupCurlFlag) { + AWS_LOGSTREAM_DEBUG(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, "Initializing Curl Http Client"); CurlHttpClient::InitGlobalState(); } #if !defined (_WIN32) @@ -139,9 +141,11 @@ namespace Aws virtual void CleanupStaticState() override { + AWS_LOGSTREAM_DEBUG(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, "Cleanup Http Static State"); #if ENABLE_CURL_CLIENT if(s_InitCleanupCurlFlag) { + AWS_LOGSTREAM_DEBUG(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, "Cleanup Curl Http Client"); CurlHttpClient::CleanupGlobalState(); } #endif diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpRequest.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpRequest.cpp index 95cb626c22e..1f109c86a92 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpRequest.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpRequest.cpp @@ -4,37 +4,88 @@ */ #include <aws/core/http/HttpRequest.h> - +#include <aws/core/utils/memory/stl/AWSStringStream.h> +#include <aws/http/request_response.h> +#include <aws/crt/Types.h> +#include <aws/crt/http/HttpRequestResponse.h> namespace Aws { -namespace Http -{ + namespace Http + { -const char DATE_HEADER[] = "date"; -const char AWS_DATE_HEADER[] = "X-Amz-Date"; -const char AWS_SECURITY_TOKEN[] = "X-Amz-Security-Token"; -const char ACCEPT_HEADER[] = "accept"; -const char ACCEPT_CHAR_SET_HEADER[] = "accept-charset"; -const char ACCEPT_ENCODING_HEADER[] = "accept-encoding"; -const char AUTHORIZATION_HEADER[] = "authorization"; -const char AWS_AUTHORIZATION_HEADER[] = "authorization"; -const char COOKIE_HEADER[] = "cookie"; -const char CONTENT_LENGTH_HEADER[] = "content-length"; -const char CONTENT_TYPE_HEADER[] = "content-type"; -const char TRANSFER_ENCODING_HEADER[] = "transfer-encoding"; -const char USER_AGENT_HEADER[] = "user-agent"; -const char VIA_HEADER[] = "via"; -const char HOST_HEADER[] = "host"; -const char AMZ_TARGET_HEADER[] = "x-amz-target"; -const char X_AMZ_EXPIRES_HEADER[] = "X-Amz-Expires"; -const char CONTENT_MD5_HEADER[] = "content-md5"; -const char API_VERSION_HEADER[] = "x-amz-api-version"; -const char SDK_INVOCATION_ID_HEADER[] = "amz-sdk-invocation-id"; -const char SDK_REQUEST_HEADER[] = "amz-sdk-request"; -const char CHUNKED_VALUE[] = "chunked"; + const char DATE_HEADER[] = "date"; + const char AWS_DATE_HEADER[] = "X-Amz-Date"; + const char AWS_SECURITY_TOKEN[] = "X-Amz-Security-Token"; + const char ACCEPT_HEADER[] = "accept"; + const char ACCEPT_CHAR_SET_HEADER[] = "accept-charset"; + const char ACCEPT_ENCODING_HEADER[] = "accept-encoding"; + const char AUTHORIZATION_HEADER[] = "authorization"; + const char AWS_AUTHORIZATION_HEADER[] = "authorization"; + const char COOKIE_HEADER[] = "cookie"; + const char DECODED_CONTENT_LENGTH_HEADER[] = "x-amz-decoded-content-length"; + const char CONTENT_LENGTH_HEADER[] = "content-length"; + const char CONTENT_TYPE_HEADER[] = "content-type"; + const char CONTENT_ENCODING_HEADER[] = "content-encoding"; + const char TRANSFER_ENCODING_HEADER[] = "transfer-encoding"; + const char USER_AGENT_HEADER[] = "user-agent"; + const char VIA_HEADER[] = "via"; + const char HOST_HEADER[] = "host"; + const char AMZ_TARGET_HEADER[] = "x-amz-target"; + const char X_AMZ_EXPIRES_HEADER[] = "X-Amz-Expires"; + const char CONTENT_MD5_HEADER[] = "content-md5"; + const char API_VERSION_HEADER[] = "x-amz-api-version"; + const char AWS_TRAILER_HEADER[] = "x-amz-trailer"; + const char SDK_INVOCATION_ID_HEADER[] = "amz-sdk-invocation-id"; + const char SDK_REQUEST_HEADER[] = "amz-sdk-request"; + const char CHUNKED_VALUE[] = "chunked"; + const char AWS_CHUNKED_VALUE[] = "aws-chunked"; + const char X_AMZN_TRACE_ID_HEADER[] = "X-Amzn-Trace-Id"; + const char ALLOCATION_TAG[] = "HttpRequestConversion"; + const char X_AMZN_ERROR_TYPE[] = "x-amzn-errortype"; -} // Http -} // Aws + std::shared_ptr<Aws::Crt::Http::HttpRequest> HttpRequest::ToCrtHttpRequest() + { + auto request = Aws::MakeShared<Aws::Crt::Http::HttpRequest>(ALLOCATION_TAG); + request->SetBody([&]() -> std::shared_ptr<IOStream> { + const std::shared_ptr<Aws::IOStream>& body = GetContentBody(); + if (body) { + return body; + } + // Return an empty string stream for no body + return Aws::MakeShared<Aws::StringStream>(ALLOCATION_TAG, ""); + }()); + auto headers = GetHeaders(); + for (const auto& it: headers) + { + Aws::Crt::Http::HttpHeader header; + header.name = Aws::Crt::ByteCursorFromCString(it.first.c_str()); + header.value = Aws::Crt::ByteCursorFromCString(it.second.c_str()); + request->AddHeader(header); + } + // Need a different URL encoding here. + // CRT sigv4 don't any encoding if double encoding is off, need to encode the path before passing to CRT. + const URI& uri = m_uri; + Aws::StringStream ss; + Aws::StringStream port; + if (uri.GetScheme() == Scheme::HTTP && uri.GetPort() != HTTP_DEFAULT_PORT) + { + port << ":" << uri.GetPort(); + } + else if (uri.GetScheme() == Scheme::HTTPS && uri.GetPort() != HTTPS_DEFAULT_PORT) + { + port << ":" << uri.GetPort(); + } + ss << SchemeMapper::ToString(uri.GetScheme()) << SEPARATOR << uri.GetAuthority() << port.str() + << ((uri.GetPath() == "/") ? "" : URI::URLEncodePath(uri.GetPath())) + << uri.GetQueryString(); + request->SetPath(Aws::Crt::ByteCursorFromCString(ss.str().c_str())); + const char *method = HttpMethodMapper::GetNameForHttpMethod(m_method); + request->SetMethod(Aws::Crt::ByteCursorFromCString(method)); + return request; + } + + } // Http +} // Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpResponse.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpResponse.cpp new file mode 100644 index 00000000000..d4e08336531 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpResponse.cpp @@ -0,0 +1,24 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/http/HttpResponse.h> + +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> +#include <aws/core/utils/StringUtils.h> + +namespace Aws +{ + namespace Http + { + /** + * Overload ostream operator<< for HttpResponseCode enum class for a prettier output such as "200" and not "<C8-00 00-00>" + */ + Aws::OStream& operator<< (Aws::OStream& oStream, HttpResponseCode code) + { + oStream << Aws::Utils::StringUtils::to_string(static_cast<typename std::underlying_type<HttpResponseCode>::type>(code)); + return oStream; + } + } // Http +} // Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp index a2239df54b1..0bc3c092458 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp @@ -5,9 +5,8 @@ #include <aws/core/http/URI.h> -#include <aws/core/utils/StringUtils.h> -#include <aws/core/utils/memory/stl/AWSStringStream.h> #include <aws/core/utils/memory/stl/AWSSet.h> +#include <aws/core/utils/logging/LogMacros.h> #include <cstdlib> #include <cctype> @@ -25,10 +24,52 @@ namespace Http const char* SEPARATOR = "://"; +bool s_compliantRfc3986Encoding = false; +void SetCompliantRfc3986Encoding(bool compliant) { s_compliantRfc3986Encoding = compliant; } + +Aws::String urlEncodeSegment(const Aws::String& segment) +{ + // consolidates legacy escaping logic into one local method + if (s_compliantRfc3986Encoding) + { + return StringUtils::URLEncode(segment.c_str()); + } + else + { + Aws::StringStream ss; + ss << std::hex << std::uppercase; + for(unsigned char c : segment) // alnum results in UB if the value of c is not unsigned char & is not EOF + { + // RFC 3986 §2.3 unreserved characters + if (StringUtils::IsAlnum(c)) + { + ss << c; + continue; + } + switch(c) + { + // §2.3 unreserved characters + // The path section of the URL allows unreserved characters to appear unescaped + case '-': case '_': case '.': case '~': + // RFC 3986 §2.2 Reserved characters + // NOTE: this implementation does not accurately implement the RFC on purpose to accommodate for + // discrepancies in the implementations of URL encoding between AWS services for legacy reasons. + case '$': case '&': case ',': + case ':': case '=': case '@': + ss << c; + break; + default: + ss << '%' << std::setfill('0') << std::setw(2) << (int)c << std::setw(0); + } + } + return ss.str(); + } +} + } // namespace Http } // namespace Aws -URI::URI() : m_scheme(Scheme::HTTP), m_port(HTTP_DEFAULT_PORT) +URI::URI() : m_scheme(Scheme::HTTP), m_port(HTTP_DEFAULT_PORT), m_pathHasTrailingSlash(false) { } @@ -102,7 +143,7 @@ void URI::SetScheme(Scheme value) Aws::String URI::URLEncodePathRFC3986(const Aws::String& path) { - if(path.empty()) + if (path.empty()) { return path; } @@ -114,34 +155,10 @@ Aws::String URI::URLEncodePathRFC3986(const Aws::String& path) // escape characters appearing in a URL path according to RFC 3986 for (const auto& segment : pathParts) { - ss << '/'; - for(unsigned char c : segment) // alnum results in UB if the value of c is not unsigned char & is not EOF - { - // §2.3 unreserved characters - if (StringUtils::IsAlnum(c)) - { - ss << c; - continue; - } - switch(c) - { - // §2.3 unreserved characters - case '-': case '_': case '.': case '~': - // The path section of the URL allow reserved characters to appear unescaped - // RFC 3986 §2.2 Reserved characters - // NOTE: this implementation does not accurately implement the RFC on purpose to accommodate for - // discrepancies in the implementations of URL encoding between AWS services for legacy reasons. - case '$': case '&': case ',': - case ':': case '=': case '@': - ss << c; - break; - default: - ss << '%' << std::setfill('0') << std::setw(2) << (int)((unsigned char)c) << std::setw(0); - } - } + ss << '/' << urlEncodeSegment(segment); } - //if the last character was also a slash, then add that back here. + // if the last character was also a slash, then add that back here. if (path.back() == '/') { ss << '/'; @@ -176,23 +193,65 @@ Aws::String URI::URLEncodePath(const Aws::String& path) } } -void URI::SetPath(const Aws::String& value) +Aws::String URI::GetPath() const { - const Aws::Vector<Aws::String> pathParts = StringUtils::Split(value, '/'); - Aws::String path; - path.reserve(value.length() + 1/* in case we have to append slash before the path. */); + Aws::String path = ""; - for (const auto& segment : pathParts) + for (auto const& segment : m_pathSegments) { path.push_back('/'); path.append(segment); } - if (value.back() == '/') + if (m_pathSegments.empty() || m_pathHasTrailingSlash) { path.push_back('/'); } - m_path = std::move(path); + + return path; +} + +Aws::String URI::GetURLEncodedPath() const +{ + Aws::StringStream ss; + + for (auto const& segment : m_pathSegments) + { + ss << '/' << StringUtils::URLEncode(segment.c_str()); + } + + if (m_pathSegments.empty() || m_pathHasTrailingSlash) + { + ss << '/'; + } + + return ss.str(); +} + +Aws::String URI::GetURLEncodedPathRFC3986() const +{ + Aws::StringStream ss; + ss << std::hex << std::uppercase; + + // escape characters appearing in a URL path according to RFC 3986 + // (mostly; there is some non-standards legacy support that can be disabled) + for (const auto& segment : m_pathSegments) + { + ss << '/' << urlEncodeSegment(segment); + } + + if (m_pathSegments.empty() || m_pathHasTrailingSlash) + { + ss << '/'; + } + + return ss.str(); +} + +void URI::SetPath(const Aws::String& value) +{ + m_pathSegments.clear(); + AddPathSegments(value); } //ugh, this isn't even part of the canonicalization spec. It is part of how our services have implemented their signers though.... @@ -347,9 +406,9 @@ Aws::String URI::GetURIString(bool includeQueryString) const ss << ":" << m_port; } - if(m_path != "/") + if (!m_pathSegments.empty()) { - ss << URLEncodePathRFC3986(m_path); + ss << GetURLEncodedPathRFC3986(); } if(includeQueryString) @@ -397,10 +456,26 @@ void URI::ExtractAndSetAuthority(const Aws::String& uri) authorityStart += 3; } - size_t posOfEndOfAuthorityPort = uri.find(':', authorityStart); - size_t posOfEndOfAuthoritySlash = uri.find('/', authorityStart); - size_t posOfEndOfAuthorityQuery = uri.find('?', authorityStart); - size_t posEndOfAuthority = (std::min)({posOfEndOfAuthorityPort, posOfEndOfAuthoritySlash, posOfEndOfAuthorityQuery}); + size_t posEndOfAuthority=0; + // are we extracting an ipv6 address? + if (uri.length() > authorityStart && uri.at(authorityStart) == '[') + { + posEndOfAuthority = uri.find(']', authorityStart); + if (posEndOfAuthority == Aws::String::npos) { + AWS_LOGSTREAM_ERROR("Uri", "Malformed uri: " << uri.c_str()); + } + else + { + ++posEndOfAuthority; + } + } + else + { + size_t posOfEndOfAuthorityPort = uri.find(':', authorityStart); + size_t posOfEndOfAuthoritySlash = uri.find('/', authorityStart); + size_t posOfEndOfAuthorityQuery = uri.find('?', authorityStart); + posEndOfAuthority = (std::min)({posOfEndOfAuthorityPort, posOfEndOfAuthoritySlash, posOfEndOfAuthorityQuery}); + } if (posEndOfAuthority == Aws::String::npos) { posEndOfAuthority = uri.length(); @@ -422,11 +497,25 @@ void URI::ExtractAndSetPort(const Aws::String& uri) authorityStart += 3; } - size_t positionOfPortDelimiter = uri.find(':', authorityStart); + size_t portSearchStart = authorityStart; + // are we extracting an ipv6 address? + if (uri.length() > portSearchStart && uri.at(portSearchStart) == '[') + { + size_t posEndOfAuthority = uri.find(']', portSearchStart); + if (posEndOfAuthority == Aws::String::npos) { + AWS_LOGSTREAM_ERROR("Uri", "Malformed uri: " << uri.c_str()); + } + else + { + portSearchStart = posEndOfAuthority; + } + } + + size_t positionOfPortDelimiter = uri.find(':', portSearchStart); bool hasPort = positionOfPortDelimiter != Aws::String::npos; - if ((uri.find('/', authorityStart) < positionOfPortDelimiter) || (uri.find('?', authorityStart) < positionOfPortDelimiter)) + if ((uri.find('/', portSearchStart) < positionOfPortDelimiter) || (uri.find('?', portSearchStart) < positionOfPortDelimiter)) { hasPort = false; } @@ -506,5 +595,5 @@ Aws::String URI::GetFormParameters() const bool URI::CompareURIParts(const URI& other) const { - return m_scheme == other.m_scheme && m_authority == other.m_authority && m_path == other.m_path && m_queryString == other.m_queryString; + return m_scheme == other.m_scheme && m_authority == other.m_authority && GetPath() == other.GetPath() && m_queryString == other.m_queryString; } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHandleContainer.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHandleContainer.cpp index 1a965cd7950..a6684c640a8 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHandleContainer.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHandleContainer.cpp @@ -43,7 +43,7 @@ CURL* CurlHandleContainer::AcquireCurlHandle() } CURL* handle = m_handleContainer.Acquire(); - AWS_LOGSTREAM_INFO(CURL_HANDLE_CONTAINER_TAG, "Connection has been released. Continuing."); + AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Connection has been released. Continuing."); AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Returning connection handle " << handle); return handle; } @@ -52,6 +52,9 @@ void CurlHandleContainer::ReleaseCurlHandle(CURL* handle) { if (handle) { +#if LIBCURL_VERSION_NUM >= 0x074D00 // 7.77.0 + curl_easy_setopt(handle, CURLOPT_COOKIEFILE, NULL); // workaround a mem leak on curl +#endif curl_easy_reset(handle); SetDefaultOptionsOnHandle(handle); AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Releasing curl handle " << handle); diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHttpClient.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHttpClient.cpp index 95132f5df0e..0f64b150629 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHttpClient.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHttpClient.cpp @@ -7,9 +7,12 @@ #include <aws/core/http/HttpRequest.h> #include <aws/core/http/standard/StandardHttpResponse.h> #include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/HashingUtils.h> #include <aws/core/utils/logging/LogMacros.h> #include <aws/core/utils/ratelimiter/RateLimiterInterface.h> #include <aws/core/utils/DateTime.h> +#include <aws/core/utils/crypto/Hash.h> +#include <aws/core/utils/Outcome.h> #include <aws/core/monitoring/HttpClientMetrics.h> #include <cassert> #include <algorithm> @@ -146,17 +149,34 @@ struct CurlReadCallbackContext m_client(client), m_curlHandle(curlHandle), m_rateLimiter(limiter), - m_request(request) + m_request(request), + m_chunkEnd(false) {} const CurlHttpClient* m_client; CURL* m_curlHandle; Aws::Utils::RateLimits::RateLimiterInterface* m_rateLimiter; HttpRequest* m_request; + bool m_chunkEnd; }; static const char* CURL_HTTP_CLIENT_TAG = "CurlHttpClient"; +static int64_t GetContentLengthFromHeader(CURL* connectionHandle, + bool& hasContentLength) { +#if LIBCURL_VERSION_NUM >= 0x073700 // 7.55.0 + curl_off_t contentLength = {}; + CURLcode res = curl_easy_getinfo( + connectionHandle, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &contentLength); +#else + double contentLength = {}; + CURLcode res = curl_easy_getinfo( + connectionHandle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &contentLength); +#endif + hasContentLength = (res == CURLE_OK) && (contentLength != -1); + return hasContentLength ? static_cast<int64_t>(contentLength) : -1; +} + static size_t WriteData(char* ptr, size_t size, size_t nmemb, void* userdata) { if (ptr) @@ -176,8 +196,13 @@ static size_t WriteData(char* ptr, size_t size, size_t nmemb, void* userdata) context->m_rateLimiter->ApplyAndPayForCost(static_cast<int64_t>(sizeToWrite)); } + for (const auto& hashIterator : context->m_request->GetResponseValidationHashes()) + { + hashIterator.second->Update(reinterpret_cast<unsigned char*>(ptr), sizeToWrite); + } + response->GetResponseBody().write(ptr, static_cast<std::streamsize>(sizeToWrite)); - if (context->m_request->IsEventStreamRequest()) + if (context->m_request->IsEventStreamRequest() && !response->HasHeader(Aws::Http::X_AMZN_ERROR_TYPE)) { response->GetResponseBody().flush(); } @@ -214,8 +239,7 @@ static size_t WriteHeader(char* ptr, size_t size, size_t nmemb, void* userdata) return 0; } - -static size_t ReadBody(char* ptr, size_t size, size_t nmemb, void* userdata) +static size_t ReadBody(char* ptr, size_t size, size_t nmemb, void* userdata, bool isStreaming) { CurlReadCallbackContext* context = reinterpret_cast<CurlReadCallbackContext*>(userdata); if(context == nullptr) @@ -232,10 +256,20 @@ static size_t ReadBody(char* ptr, size_t size, size_t nmemb, void* userdata) HttpRequest* request = context->m_request; const std::shared_ptr<Aws::IOStream>& ioStream = request->GetContentBody(); - const size_t amountToRead = size * nmemb; + size_t amountToRead = size * nmemb; + bool isAwsChunked = request->HasHeader(Aws::Http::CONTENT_ENCODING_HEADER) && + request->GetHeaderValue(Aws::Http::CONTENT_ENCODING_HEADER) == Aws::Http::AWS_CHUNKED_VALUE; + // aws-chunk = hex(chunk-size) + CRLF + chunk-data + CRLF + // Needs to reserve bytes of sizeof(hex(chunk-size)) + sizeof(CRLF) + sizeof(CRLF) + if (isAwsChunked) + { + Aws::String amountToReadHexString = Aws::Utils::StringUtils::ToHexString(amountToRead); + amountToRead -= (amountToReadHexString.size() + 4); + } + if (ioStream != nullptr && amountToRead > 0) { - if (request->IsEventStreamRequest()) + if (isStreaming) { if (ioStream->readsome(ptr, amountToRead) == 0 && !ioStream->eof()) { @@ -247,6 +281,39 @@ static size_t ReadBody(char* ptr, size_t size, size_t nmemb, void* userdata) ioStream->read(ptr, amountToRead); } size_t amountRead = static_cast<size_t>(ioStream->gcount()); + + if (isAwsChunked) + { + if (amountRead > 0) + { + if (request->GetRequestHash().second != nullptr) + { + request->GetRequestHash().second->Update(reinterpret_cast<unsigned char*>(ptr), amountRead); + } + + Aws::String hex = Aws::Utils::StringUtils::ToHexString(amountRead); + memmove(ptr + hex.size() + 2, ptr, amountRead); + memmove(ptr + hex.size() + 2 + amountRead, "\r\n", 2); + memmove(ptr, hex.c_str(), hex.size()); + memmove(ptr + hex.size(), "\r\n", 2); + amountRead += hex.size() + 4; + } + else if (!context->m_chunkEnd) + { + Aws::StringStream chunkedTrailer; + chunkedTrailer << "0\r\n"; + if (request->GetRequestHash().second != nullptr) + { + chunkedTrailer << "x-amz-checksum-" << request->GetRequestHash().first << ":" + << HashingUtils::Base64Encode(request->GetRequestHash().second->GetHash().GetResult()) << "\r\n"; + } + chunkedTrailer << "\r\n"; + amountRead = chunkedTrailer.str().size(); + memcpy(ptr, chunkedTrailer.str().c_str(), amountRead); + context->m_chunkEnd = true; + } + } + auto& sentHandler = request->GetDataSentEventHandler(); if (sentHandler) { @@ -264,6 +331,14 @@ static size_t ReadBody(char* ptr, size_t size, size_t nmemb, void* userdata) return 0; } +static size_t ReadBodyStreaming(char* ptr, size_t size, size_t nmemb, void* userdata) { + return ReadBody(ptr, size, nmemb, userdata, true); +} + +static size_t ReadBodyFunc(char* ptr, size_t size, size_t nmemb, void* userdata) { + return ReadBody(ptr, size, nmemb, userdata, false); +} + static size_t SeekBody(void* userdata, curl_off_t offset, int origin) { CurlReadCallbackContext* context = reinterpret_cast<CurlReadCallbackContext*>(userdata); @@ -358,7 +433,11 @@ void SetOptCodeForHttpMethod(CURL* requestHandle, const std::shared_ptr<HttpRequ } else { +#if LIBCURL_VERSION_NUM >= 0x070c01 // 7.12.1 + curl_easy_setopt(requestHandle, CURLOPT_UPLOAD, 1L); +#else curl_easy_setopt(requestHandle, CURLOPT_PUT, 1L); +#endif } break; case HttpMethod::HTTP_HEAD: @@ -579,6 +658,9 @@ std::shared_ptr<HttpResponse> CurlHttpClient::MakeRequest(const std::shared_ptr< curl_easy_setopt(connectionHandle, CURLOPT_CAINFO, m_caFile.c_str()); } + // enable the cookie engine without reading any initial cookies. + curl_easy_setopt(connectionHandle, CURLOPT_COOKIEFILE, ""); + // only set by android test builds because the emulator is missing a cert needed for aws services #ifdef TEST_CERT_PATH curl_easy_setopt(connectionHandle, CURLOPT_CAPATH, TEST_CERT_PATH); @@ -664,12 +746,13 @@ std::shared_ptr<HttpResponse> CurlHttpClient::MakeRequest(const std::shared_ptr< if (request->GetContentBody()) { - curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, ReadBody); + curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, ReadBodyFunc); curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &readContext); curl_easy_setopt(connectionHandle, CURLOPT_SEEKFUNCTION, SeekBody); curl_easy_setopt(connectionHandle, CURLOPT_SEEKDATA, &readContext); - if (request->IsEventStreamRequest()) + if (request->IsEventStreamRequest() && !response->HasHeader(Aws::Http::X_AMZN_ERROR_TYPE)) { + curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, ReadBodyStreaming); curl_easy_setopt(connectionHandle, CURLOPT_NOPROGRESS, 0L); #if LIBCURL_VERSION_NUM >= 0x072000 // 7.32.0 curl_easy_setopt(connectionHandle, CURLOPT_XFERINFOFUNCTION, CurlProgressCallback); @@ -714,15 +797,18 @@ std::shared_ptr<HttpResponse> CurlHttpClient::MakeRequest(const std::shared_ptr< AWS_LOGSTREAM_DEBUG(CURL_HTTP_CLIENT_TAG, "Returned content type " << contentType); } + bool hasContentLength = false; + int64_t contentLength = + GetContentLengthFromHeader(connectionHandle, hasContentLength); + if (request->GetMethod() != HttpMethod::HTTP_HEAD && writeContext.m_client->IsRequestProcessingEnabled() && - response->HasHeader(Aws::Http::CONTENT_LENGTH_HEADER)) + hasContentLength) { - const Aws::String& contentLength = response->GetHeader(Aws::Http::CONTENT_LENGTH_HEADER); int64_t numBytesResponseReceived = writeContext.m_numBytesResponseReceived; AWS_LOGSTREAM_TRACE(CURL_HTTP_CLIENT_TAG, "Response content-length header: " << contentLength); AWS_LOGSTREAM_TRACE(CURL_HTTP_CLIENT_TAG, "Response body length: " << numBytesResponseReceived); - if (StringUtils::ConvertToInt64(contentLength.c_str()) != numBytesResponseReceived) + if (contentLength != numBytesResponseReceived) { response->SetClientErrorType(CoreErrors::NETWORK_CONNECTION); response->SetClientErrorMessage("Response body length doesn't match the content-length header."); diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/standard/StandardHttpRequest.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/standard/StandardHttpRequest.cpp index 47a0ee4faca..87b857ca24e 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/standard/StandardHttpRequest.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/standard/StandardHttpRequest.cpp @@ -4,7 +4,7 @@ */ #include <aws/core/http/standard/StandardHttpRequest.h> - +#include <aws/core/utils/logging/LogMacros.h> #include <aws/core/utils/StringUtils.h> #include <iostream> @@ -15,6 +15,8 @@ using namespace Aws::Http; using namespace Aws::Http::Standard; using namespace Aws::Utils; +static const char* STANDARD_HTTP_REQUEST_LOG_TAG = "StandardHttpRequest"; + static bool IsDefaultPort(const URI& uri) { switch(uri.GetPort()) @@ -59,8 +61,13 @@ HeaderValueCollection StandardHttpRequest::GetHeaders() const const Aws::String& StandardHttpRequest::GetHeaderValue(const char* headerName) const { - auto iter = headerMap.find(headerName); + auto iter = headerMap.find(StringUtils::ToLower(headerName)); assert (iter != headerMap.end()); + if (iter == headerMap.end()) { + AWS_LOGSTREAM_ERROR(STANDARD_HTTP_REQUEST_LOG_TAG, "Requested a header value for a missing header key: " << headerName); + static const Aws::String EMPTY_STRING = ""; + return EMPTY_STRING; + } return iter->second; } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/standard/StandardHttpResponse.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/standard/StandardHttpResponse.cpp index 92d7a062b6c..8b62ae5e634 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/standard/StandardHttpResponse.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/standard/StandardHttpResponse.cpp @@ -6,6 +6,7 @@ #include <aws/core/http/standard/StandardHttpResponse.h> #include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/logging/LogMacros.h> #include <aws/core/utils/memory/AWSMemory.h> #include <istream> @@ -14,6 +15,7 @@ using namespace Aws::Http; using namespace Aws::Http::Standard; using namespace Aws::Utils; +static const char* STANDARD_HTTP_RESPONSE_LOG_TAG = "StandardHttpResponse"; HeaderValueCollection StandardHttpResponse::GetHeaders() const { @@ -35,6 +37,12 @@ bool StandardHttpResponse::HasHeader(const char* headerName) const const Aws::String& StandardHttpResponse::GetHeader(const Aws::String& headerName) const { Aws::Map<Aws::String, Aws::String>::const_iterator foundValue = headerMap.find(StringUtils::ToLower(headerName.c_str())); + assert(foundValue != headerMap.end()); + if (foundValue == headerMap.end()) { + AWS_LOGSTREAM_ERROR(STANDARD_HTTP_RESPONSE_LOG_TAG, "Requested a header value for a missing header key: " << headerName); + static const Aws::String EMPTY_STRING = ""; + return EMPTY_STRING; + } return foundValue->second; } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/internal/AWSHttpResourceClient.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/internal/AWSHttpResourceClient.cpp index 2f372ec82a7..ca664cc6c43 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/internal/AWSHttpResourceClient.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/internal/AWSHttpResourceClient.cpp @@ -140,12 +140,12 @@ namespace Aws } const Aws::Client::AWSError<Aws::Client::CoreErrors> error = [this, &response]() { - if (response->HasClientError() || response->GetResponseBody().tellp() < 1) + if (response->HasClientError() || response->GetResponseCode() == HttpResponseCode::REQUEST_NOT_MADE) { AWS_LOGSTREAM_ERROR(m_logtag.c_str(), "Http request to retrieve credentials failed"); return AWSError<CoreErrors>(CoreErrors::NETWORK_CONNECTION, true); // Retryable } - else if (m_errorMarshaller) + else if (m_errorMarshaller && response->GetResponseBody().tellp() > 0) { return m_errorMarshaller->Marshall(*response); } @@ -170,14 +170,23 @@ namespace Aws } } - EC2MetadataClient::EC2MetadataClient(const char* endpoint) - : AWSHttpResourceClient(EC2_METADATA_CLIENT_LOG_TAG), m_endpoint(endpoint), m_tokenRequired(true) + EC2MetadataClient::EC2MetadataClient(const char *endpoint) : + AWSHttpResourceClient(EC2_METADATA_CLIENT_LOG_TAG), + m_endpoint(endpoint), + m_disableIMDS(false), + m_tokenRequired(true) { + } - EC2MetadataClient::EC2MetadataClient(const Aws::Client::ClientConfiguration &clientConfiguration, const char *endpoint) - : AWSHttpResourceClient(clientConfiguration, EC2_METADATA_CLIENT_LOG_TAG), m_endpoint(endpoint), m_tokenRequired(true) + EC2MetadataClient::EC2MetadataClient(const Aws::Client::ClientConfiguration &clientConfiguration, + const char *endpoint) : + AWSHttpResourceClient(clientConfiguration, EC2_METADATA_CLIENT_LOG_TAG), + m_endpoint(endpoint), + m_disableIMDS(clientConfiguration.disableIMDS), + m_tokenRequired(true) { + } EC2MetadataClient::~EC2MetadataClient() @@ -190,15 +199,20 @@ namespace Aws return GetResource(m_endpoint.c_str(), resourcePath, nullptr/*authToken*/); } +#if !defined(DISABLE_IMDSV1) Aws::String EC2MetadataClient::GetDefaultCredentials() const { + if (m_disableIMDS) { + AWS_LOGSTREAM_TRACE(m_logtag.c_str(), "Skipping call to IMDS Service"); + return {}; + } std::unique_lock<std::recursive_mutex> locker(m_tokenMutex); if (m_tokenRequired) { return GetDefaultCredentialsSecurely(); } - AWS_LOGSTREAM_TRACE(m_logtag.c_str(), "Getting default credentials for ec2 instance"); + AWS_LOGSTREAM_TRACE(m_logtag.c_str(), "Getting default credentials for ec2 instance from " << m_endpoint); auto result = GetResourceWithAWSWebServiceResult(m_endpoint.c_str(), EC2_SECURITY_CREDENTIALS_RESOURCE, nullptr); Aws::String credentialsString = result.GetPayload(); auto httpResponseCode = result.GetResponseCode(); @@ -232,14 +246,20 @@ namespace Aws AWS_LOGSTREAM_DEBUG(m_logtag.c_str(), "Calling EC2MetadataService resource " << ss.str()); return GetResource(ss.str().c_str()); } +#endif Aws::String EC2MetadataClient::GetDefaultCredentialsSecurely() const { + if (m_disableIMDS) { + AWS_LOGSTREAM_TRACE(m_logtag.c_str(), "Skipping call to IMDS Service"); + return {}; + } std::unique_lock<std::recursive_mutex> locker(m_tokenMutex); - if (!m_tokenRequired) - { +#if !defined(DISABLE_IMDSV1) + if (!m_tokenRequired) { return GetDefaultCredentials(); } +#endif Aws::StringStream ss; ss << m_endpoint << EC2_IMDS_TOKEN_RESOURCE; @@ -257,12 +277,14 @@ namespace Aws { return {}; } +#if !defined(DISABLE_IMDSV1) else if (result.GetResponseCode() != HttpResponseCode::OK || trimmedTokenString.empty()) { m_tokenRequired = false; AWS_LOGSTREAM_TRACE(m_logtag.c_str(), "Calling EC2MetadataService to get token failed, falling back to less secure way."); return GetDefaultCredentials(); } +#endif m_token = trimmedTokenString; locker.unlock(); ss.str(""); @@ -278,7 +300,7 @@ namespace Aws AWS_LOGSTREAM_DEBUG(m_logtag.c_str(), "Calling EC2MetadataService resource, " << EC2_SECURITY_CREDENTIALS_RESOURCE << " with token returned profile string " << trimmedProfileString); - if (securityCredentials.size() == 0) + if (securityCredentials.empty()) { AWS_LOGSTREAM_WARN(m_logtag.c_str(), "Calling EC2Metadataservice to get profiles failed"); return {}; @@ -296,6 +318,10 @@ namespace Aws Aws::String EC2MetadataClient::GetCurrentRegion() const { + if (m_disableIMDS) { + AWS_LOGSTREAM_TRACE(m_logtag.c_str(), "Skipping call to IMDS Service"); + return {}; + } if (!m_region.empty()) { return m_region; @@ -311,6 +337,7 @@ namespace Aws std::lock_guard<std::recursive_mutex> locker(m_tokenMutex); if (m_tokenRequired) { + GetDefaultCredentialsSecurely(); regionRequest->SetHeaderValue(EC2_IMDS_TOKEN_HEADER, m_token); } } @@ -351,6 +378,16 @@ namespace Aws return region; } + void EC2MetadataClient::SetEndpoint(const Aws::String& endpoint) + { + m_endpoint = endpoint; + } + + Aws::String EC2MetadataClient::GetEndpoint() const + { + return Aws::String(m_endpoint); + } + #ifdef _MSC_VER // VS2015 compiler's bug, warning s_ec2metadataClient: symbol will be dynamically initialized (implementation limitation) AWS_SUPPRESS_WARNING(4592, @@ -366,7 +403,39 @@ namespace Aws { return; } - s_ec2metadataClient = Aws::MakeShared<EC2MetadataClient>(EC2_METADATA_CLIENT_LOG_TAG); + Aws::String ec2MetadataServiceEndpoint = Aws::Environment::GetEnv("AWS_EC2_METADATA_SERVICE_ENDPOINT"); + if (ec2MetadataServiceEndpoint.empty()) + { + Aws::String ec2MetadataServiceEndpointMode = Aws::Environment::GetEnv("AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE").c_str(); + if (ec2MetadataServiceEndpointMode.length() == 0 ) + { + ec2MetadataServiceEndpoint = "http://169.254.169.254"; //default to IPv4 default endpoint + } + else + { + if (ec2MetadataServiceEndpointMode.length() == 4 ) + { + if (Aws::Utils::StringUtils::CaselessCompare(ec2MetadataServiceEndpointMode.c_str(), "ipv4")) + { + ec2MetadataServiceEndpoint = "http://169.254.169.254"; //default to IPv4 default endpoint + } + else if (Aws::Utils::StringUtils::CaselessCompare(ec2MetadataServiceEndpointMode.c_str(), "ipv6")) + { + ec2MetadataServiceEndpoint = "http://[fd00:ec2::254]"; + } + else + { + AWS_LOGSTREAM_ERROR(EC2_METADATA_CLIENT_LOG_TAG, "AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE can only be set to ipv4 or ipv6, received: " << ec2MetadataServiceEndpointMode ); + } + } + else + { + AWS_LOGSTREAM_ERROR(EC2_METADATA_CLIENT_LOG_TAG, "AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE can only be set to ipv4 or ipv6, received: " << ec2MetadataServiceEndpointMode ); + } + } + } + AWS_LOGSTREAM_INFO(EC2_METADATA_CLIENT_LOG_TAG, "Using IMDS endpoint: " << ec2MetadataServiceEndpoint); + s_ec2metadataClient = Aws::MakeShared<EC2MetadataClient>(EC2_METADATA_CLIENT_LOG_TAG, ec2MetadataServiceEndpoint.c_str()); } void CleanupEC2MetadataClient() @@ -383,7 +452,6 @@ namespace Aws return s_ec2metadataClient; } - ECSCredentialsClient::ECSCredentialsClient(const char* resourcePath, const char* endpoint, const char* token) : AWSHttpResourceClient(ECS_CREDENTIALS_CLIENT_LOG_TAG), m_resourcePath(resourcePath), m_endpoint(endpoint), m_token(token) @@ -510,6 +578,17 @@ namespace Aws { SetErrorMarshaller(Aws::MakeUnique<Aws::Client::JsonErrorMarshaller>(SSO_RESOURCE_CLIENT_LOG_TAG)); + m_endpoint = buildEndpoint(clientConfiguration, "portal.sso.", "federation/credentials"); + m_oidcEndpoint = buildEndpoint(clientConfiguration, "oidc.", "token"); + + AWS_LOGSTREAM_INFO(SSO_RESOURCE_CLIENT_LOG_TAG, "Creating SSO ResourceClient with endpoint: " << m_endpoint); + } + + Aws::String SSOCredentialsClient::buildEndpoint( + const Aws::Client::ClientConfiguration& clientConfiguration, + const Aws::String& domain, + const Aws::String& endpoint) + { Aws::StringStream ss; if (clientConfiguration.scheme == Aws::Http::Scheme::HTTP) { @@ -525,15 +604,12 @@ namespace Aws auto hash = Aws::Utils::HashingUtils::HashString(clientConfiguration.region.c_str()); AWS_LOGSTREAM_DEBUG(SSO_RESOURCE_CLIENT_LOG_TAG, "Preparing SSO client for region: " << clientConfiguration.region); - - ss << "portal.sso." << clientConfiguration.region << ".amazonaws.com/federation/credentials"; + ss << domain << clientConfiguration.region << ".amazonaws.com/" << endpoint; if (hash == CN_NORTH_1_HASH || hash == CN_NORTHWEST_1_HASH) { ss << ".cn"; } - m_endpoint = ss.str(); - - AWS_LOGSTREAM_INFO(SSO_RESOURCE_CLIENT_LOG_TAG, "Creating SSO ResourceClient with endpoint: " << m_endpoint); + return ss.str(); } SSOCredentialsClient::SSOGetRoleCredentialsResult SSOCredentialsClient::GetSSOCredentials(const SSOGetRoleCredentialsRequest &request) @@ -571,5 +647,70 @@ namespace Aws result.creds = creds; return result; } + + // An internal SSO CreateToken implementation to lightweight core package and not introduce a dependency on sso-oidc + SSOCredentialsClient::SSOCreateTokenResult SSOCredentialsClient::CreateToken(const SSOCreateTokenRequest& request) + { + std::shared_ptr<HttpRequest> httpRequest(CreateHttpRequest(m_oidcEndpoint, HttpMethod::HTTP_POST, + Aws::Utils::Stream::DefaultResponseStreamFactoryMethod)); + SSOCreateTokenResult result; + if(!httpRequest) { + AWS_LOGSTREAM_FATAL(SSO_RESOURCE_CLIENT_LOG_TAG, "Failed to CreateHttpRequest: nullptr returned"); + return result; + } + httpRequest->SetUserAgent(ComputeUserAgentString()); + + Json::JsonValue requestDoc; + if(!request.clientId.empty()) { + requestDoc.WithString("clientId", request.clientId); + } + if(!request.clientSecret.empty()) { + requestDoc.WithString("clientSecret", request.clientSecret); + } + if(!request.grantType.empty()) { + requestDoc.WithString("grantType", request.grantType); + } + if(!request.refreshToken.empty()) { + requestDoc.WithString("refreshToken", request.refreshToken); + } + + std::shared_ptr<Aws::IOStream> body = Aws::MakeShared<Aws::StringStream>("SSO_BEARER_TOKEN_CREATE_TOKEN"); + if(!body) { + AWS_LOGSTREAM_FATAL(SSO_RESOURCE_CLIENT_LOG_TAG, "Failed to allocate body"); // exceptions disabled + return result; + } + *body << requestDoc.View().WriteReadable();; + + httpRequest->AddContentBody(body); + body->seekg(0, body->end); + auto streamSize = body->tellg(); + body->seekg(0, body->beg); + Aws::StringStream contentLength; + contentLength << streamSize; + httpRequest->SetContentLength(contentLength.str()); + httpRequest->SetContentType("application/json"); + + Aws::String rawReply = GetResourceWithAWSWebServiceResult(httpRequest).GetPayload(); + Json::JsonValue refreshTokenDoc(rawReply); + Utils::Json::JsonView jsonValue = refreshTokenDoc.View(); + + if(jsonValue.ValueExists("accessToken")) { + result.accessToken = jsonValue.GetString("accessToken"); + } + if(jsonValue.ValueExists("tokenType")) { + result.tokenType = jsonValue.GetString("tokenType"); + } + if(jsonValue.ValueExists("expiresIn")) { + result.expiresIn = jsonValue.GetInteger("expiresIn"); + } + if(jsonValue.ValueExists("idToken")) { + result.idToken = jsonValue.GetString("idToken"); + } + if(jsonValue.ValueExists("refreshToken")) { + result.refreshToken = jsonValue.GetString("refreshToken"); + } + + return result; + } } } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/MonitoringManager.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/MonitoringManager.cpp index 7a8d3adb41c..d6891933c7c 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/MonitoringManager.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/MonitoringManager.cpp @@ -25,16 +25,18 @@ namespace Aws /** * Global factory to create global metrics instance. */ - static Aws::UniquePtr<Monitors> s_monitors; + static Monitors* s_monitors(nullptr); Aws::Vector<void*> OnRequestStarted(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request) { - assert(s_monitors); Aws::Vector<void*> contexts; - contexts.reserve(s_monitors->size()); - for (const auto& interface: *s_monitors) + if (s_monitors) { - contexts.emplace_back(interface->OnRequestStarted(serviceName, requestName, request)); + contexts.reserve(s_monitors->size()); + for (const auto& interface: *s_monitors) + { + contexts.emplace_back(interface->OnRequestStarted(serviceName, requestName, request)); + } } return contexts; } @@ -42,48 +44,56 @@ namespace Aws void OnRequestSucceeded(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, const Aws::Vector<void*>& contexts) { - assert(s_monitors); - assert(contexts.size() == s_monitors->size()); - size_t index = 0; - for (const auto& interface: *s_monitors) + if (s_monitors) { - interface->OnRequestSucceeded(serviceName, requestName, request, outcome, metricsFromCore, contexts[index++]); + assert(contexts.size() == s_monitors->size()); + size_t index = 0; + for (const auto& interface: *s_monitors) + { + interface->OnRequestSucceeded(serviceName, requestName, request, outcome, metricsFromCore, contexts[index++]); + } } } void OnRequestFailed(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, const Aws::Vector<void*>& contexts) { - assert(s_monitors); - assert(contexts.size() == s_monitors->size()); - size_t index = 0; - for (const auto& interface: *s_monitors) + if (s_monitors) { - interface->OnRequestFailed(serviceName, requestName, request, outcome, metricsFromCore, contexts[index++]); + assert(contexts.size() == s_monitors->size()); + size_t index = 0; + for (const auto& interface: *s_monitors) + { + interface->OnRequestFailed(serviceName, requestName, request, outcome, metricsFromCore, contexts[index++]); + } } } void OnRequestRetry(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, const Aws::Vector<void*>& contexts) { - assert(s_monitors); - assert(contexts.size() == s_monitors->size()); - size_t index = 0; - for (const auto& interface: *s_monitors) + if (s_monitors) { - interface->OnRequestRetry(serviceName, requestName, request, contexts[index++]); + assert(contexts.size() == s_monitors->size()); + size_t index = 0; + for (const auto& interface: *s_monitors) + { + interface->OnRequestRetry(serviceName, requestName, request, contexts[index++]); + } } } void OnFinish(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, const Aws::Vector<void*>& contexts) { - assert(s_monitors); - assert(contexts.size() == s_monitors->size()); - size_t index = 0; - for (const auto& interface: *s_monitors) + if (s_monitors) { - interface->OnFinish(serviceName, requestName, request, contexts[index++]); + assert(contexts.size() == s_monitors->size()); + size_t index = 0; + for (const auto& interface: *s_monitors) + { + interface->OnFinish(serviceName, requestName, request, contexts[index++]); + } } } @@ -93,7 +103,8 @@ namespace Aws { return; } - s_monitors = Aws::MakeUnique<Monitors>(MonitoringTag); + assert(Aws::get_aws_allocator() != nullptr); + s_monitors = Aws::New<Monitors>(MonitoringTag); for (const auto& function: monitoringFactoryCreateFunctions) { auto factory = function(); @@ -117,11 +128,7 @@ namespace Aws void CleanupMonitoring() { - if (!s_monitors) - { - return; - } - + Aws::Delete(s_monitors); s_monitors = nullptr; } } // namespace Monitoring diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DateTimeCommon.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DateTimeCommon.cpp index b690c90c2dd..5ef76dcfc67 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DateTimeCommon.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DateTimeCommon.cpp @@ -176,7 +176,7 @@ static int GetWeekDayNumberFromStr(const char* timeString, size_t startIndex, si } } -//Get the 0-11 monthy number from a string representing Month. Case insensitive and will stop on abbreviation +//Get the 0-11 monthly number from a string representing Month. Case insensitive and will stop on abbreviation static int GetMonthNumberFromStr(const char* timeString, size_t startIndex, size_t stopIndex) { if (stopIndex - startIndex < 3) @@ -842,7 +842,9 @@ public: break; case 6: - if ((c == 'Z' || c == '+' || c == '-' ) && (index - stateStartIndex == 3)) + if ((c == 'Z' || c == '+' || c == '-' ) && + (index - stateStartIndex >= 3) && + (index - stateStartIndex <= 9)) { m_tz[0] = c; m_state = 7; @@ -1268,6 +1270,12 @@ double DateTime::SecondsWithMSPrecision() const return timestamp.count(); } +int64_t DateTime::Seconds() const +{ + auto timestamp = std::chrono::duration_cast<std::chrono::seconds>(m_time.time_since_epoch()); + return timestamp.count(); +} + int64_t DateTime::Millis() const { auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(m_time.time_since_epoch()); diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Document.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Document.cpp new file mode 100644 index 00000000000..ef8210aeb1e --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Document.cpp @@ -0,0 +1,673 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/utils/Document.h> + +#include <iterator> +#include <algorithm> +#include <aws/core/utils/memory/stl/AWSStringStream.h> +#include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/json/JsonSerializer.h> + +using namespace Aws::Utils; + +Document::Document() : m_wasParseSuccessful(true) +{ + m_json = nullptr; +} + +Document::Document(cJSON* value) : + m_json(cJSON_AS4CPP_Duplicate(value, true /* recurse */)), + m_wasParseSuccessful(true) +{ +} + +Document::Document(const Aws::String& value) : m_wasParseSuccessful(true) +{ + const char* return_parse_end; + m_json = cJSON_AS4CPP_ParseWithOpts(value.c_str(), &return_parse_end, 1/*require_null_terminated*/); + + if (!m_json || cJSON_AS4CPP_IsInvalid(m_json)) + { + m_wasParseSuccessful = false; + m_errorMessage = "Failed to parse JSON at: "; + m_errorMessage += return_parse_end; + } +} + +Document::Document(Aws::IStream& istream) : m_wasParseSuccessful(true) +{ + Aws::StringStream memoryStream; + std::copy(std::istreambuf_iterator<char>(istream), std::istreambuf_iterator<char>(), std::ostreambuf_iterator<char>(memoryStream)); + const char* return_parse_end; + const auto input = memoryStream.str(); + m_json = cJSON_AS4CPP_ParseWithOpts(input.c_str(), &return_parse_end, 1/*require_null_terminated*/); + + if (!m_json || cJSON_AS4CPP_IsInvalid(m_json)) + { + m_wasParseSuccessful = false; + m_errorMessage = "Failed to parse JSON. Invalid input at: "; + m_errorMessage += return_parse_end; + } +} + +Document::Document(const Document& value) : + m_json(cJSON_AS4CPP_Duplicate(value.m_json, true/*recurse*/)), + m_wasParseSuccessful(value.m_wasParseSuccessful), + m_errorMessage(value.m_errorMessage) +{ +} + +Document::Document(Document&& value) : + m_json(value.m_json), + m_wasParseSuccessful(value.m_wasParseSuccessful), + m_errorMessage(std::move(value.m_errorMessage)) +{ + value.m_json = nullptr; +} + +Document::Document(const Json::JsonView& view) : + m_json(cJSON_AS4CPP_Duplicate(view.m_value, true/*recurse*/)), + m_wasParseSuccessful(true), + m_errorMessage({}) +{ +} + +void Document::Destroy() +{ + cJSON_AS4CPP_Delete(m_json); +} + +Document::~Document() +{ + Destroy(); +} + +Document& Document::operator=(const Document& other) +{ + if (this == &other) + { + return *this; + } + + Destroy(); + m_json = cJSON_AS4CPP_Duplicate(other.m_json, true /*recurse*/); + m_wasParseSuccessful = other.m_wasParseSuccessful; + m_errorMessage = other.m_errorMessage; + return *this; +} + +Document& Document::operator=(Document&& other) +{ + if (this == &other) + { + return *this; + } + + using std::swap; + swap(m_json, other.m_json); + swap(m_errorMessage, other.m_errorMessage); + m_wasParseSuccessful = other.m_wasParseSuccessful; + return *this; +} + +Document& Document::operator=(const Json::JsonView& other) +{ + Destroy(); + m_json = cJSON_AS4CPP_Duplicate(other.m_value, true /*recurse*/); + m_wasParseSuccessful = true; + m_errorMessage = {}; + return *this; +} + +bool Document::operator==(const Document& other) const +{ + return cJSON_AS4CPP_Compare(m_json, other.m_json, true /*case-sensitive*/) != 0; +} + +bool Document::operator!=(const Document& other) const +{ + return !(*this == other); +} + +static void AddOrReplace(cJSON* root, const char* key, cJSON* value) +{ + const auto existing = cJSON_AS4CPP_GetObjectItemCaseSensitive(root, key); + if (existing) + { + cJSON_AS4CPP_ReplaceItemInObjectCaseSensitive(root, key, value); + } + else + { + cJSON_AS4CPP_AddItemToObject(root, key, value); + } +} + +Document& Document::WithString(const char* key, const Aws::String& value) +{ + if (!m_json) + { + m_json = cJSON_AS4CPP_CreateObject(); + } + + const auto val = cJSON_AS4CPP_CreateString(value.c_str()); + AddOrReplace(m_json, key, val); + return *this; +} + +Document& Document::WithString(const Aws::String& key, const Aws::String& value) +{ + return WithString(key.c_str(), value); +} + +Document& Document::AsString(const Aws::String& value) +{ + Destroy(); + m_json = cJSON_AS4CPP_CreateString(value.c_str()); + return *this; +} + +Document& Document::WithBool(const char* key, bool value) +{ + if (!m_json) + { + m_json = cJSON_AS4CPP_CreateObject(); + } + + const auto val = cJSON_AS4CPP_CreateBool(value); + AddOrReplace(m_json, key, val); + return *this; +} + +Document& Document::WithBool(const Aws::String& key, bool value) +{ + return WithBool(key.c_str(), value); +} + +Document& Document::AsBool(bool value) +{ + Destroy(); + m_json = cJSON_AS4CPP_CreateBool(value); + return *this; +} + +Document& Document::WithInteger(const char* key, int value) +{ + return WithDouble(key, static_cast<double>(value)); +} + +Document& Document::WithInteger(const Aws::String& key, int value) +{ + return WithDouble(key.c_str(), static_cast<double>(value)); +} + +Document& Document::AsInteger(int value) +{ + Destroy(); + m_json = cJSON_AS4CPP_CreateNumber(static_cast<double>(value)); + return *this; +} + +Document& Document::WithInt64(const char* key, long long value) +{ + if (!m_json) + { + m_json = cJSON_AS4CPP_CreateObject(); + } + + const auto val = cJSON_AS4CPP_CreateInt64(value); + AddOrReplace(m_json, key, val); + return *this; +} + +Document& Document::WithInt64(const Aws::String& key, long long value) +{ + return WithInt64(key.c_str(), value); +} + +Document& Document::AsInt64(long long value) +{ + Destroy(); + m_json = cJSON_AS4CPP_CreateInt64(value); + return *this; +} + +Document& Document::WithDouble(const char* key, double value) +{ + if (!m_json) + { + m_json = cJSON_AS4CPP_CreateObject(); + } + + const auto val = cJSON_AS4CPP_CreateNumber(value); + AddOrReplace(m_json, key, val); + return *this; +} + +Document& Document::WithDouble(const Aws::String& key, double value) +{ + return WithDouble(key.c_str(), value); +} + +Document& Document::AsDouble(double value) +{ + Destroy(); + m_json = cJSON_AS4CPP_CreateNumber(value); + return *this; +} + +Document& Document::WithArray(const char* key, const Array<Aws::String>& array) +{ + if (!m_json) + { + m_json = cJSON_AS4CPP_CreateObject(); + } + + auto arrayValue = cJSON_AS4CPP_CreateArray(); + for (unsigned i = 0; i < array.GetLength(); ++i) + { + cJSON_AS4CPP_AddItemToArray(arrayValue, cJSON_AS4CPP_CreateString(array[i].c_str())); + } + + AddOrReplace(m_json, key, arrayValue); + return *this; +} + +Document& Document::WithArray(const Aws::String& key, const Array<Aws::String>& array) +{ + return WithArray(key.c_str(), array); +} + +Document& Document::WithArray(const Aws::String& key, const Array<Document>& array) +{ + if (!m_json) + { + m_json = cJSON_AS4CPP_CreateObject(); + } + + auto arrayValue = cJSON_AS4CPP_CreateArray(); + for (unsigned i = 0; i < array.GetLength(); ++i) + { + cJSON_AS4CPP_AddItemToArray(arrayValue, cJSON_AS4CPP_Duplicate(array[i].m_json, true /*recurse*/)); + } + + AddOrReplace(m_json, key.c_str(), arrayValue); + return *this; +} + +Document& Document::WithArray(const Aws::String& key, Array<Document>&& array) +{ + if (!m_json) + { + m_json = cJSON_AS4CPP_CreateObject(); + } + + auto arrayValue = cJSON_AS4CPP_CreateArray(); + for (unsigned i = 0; i < array.GetLength(); ++i) + { + cJSON_AS4CPP_AddItemToArray(arrayValue, array[i].m_json); + array[i].m_json = nullptr; + } + + AddOrReplace(m_json, key.c_str(), arrayValue); + return *this; +} + +Document& Document::AsArray(const Array<Document>& array) +{ + auto arrayValue = cJSON_AS4CPP_CreateArray(); + for (unsigned i = 0; i < array.GetLength(); ++i) + { + cJSON_AS4CPP_AddItemToArray(arrayValue, cJSON_AS4CPP_Duplicate(array[i].m_json, true /*recurse*/)); + } + + Destroy(); + m_json = arrayValue; + return *this; +} + +Document& Document::AsArray(Array<Document>&& array) +{ + auto arrayValue = cJSON_AS4CPP_CreateArray(); + for (unsigned i = 0; i < array.GetLength(); ++i) + { + cJSON_AS4CPP_AddItemToArray(arrayValue, array[i].m_json); + array[i].m_json = nullptr; + } + + Destroy(); + m_json = arrayValue; + return *this; +} + +Document& Document::WithObject(const char* key, const Document& value) +{ + if (!m_json) + { + m_json = cJSON_AS4CPP_CreateObject(); + } + + const auto copy = value.m_json == nullptr ? cJSON_AS4CPP_CreateObject() : cJSON_AS4CPP_Duplicate(value.m_json, true /*recurse*/); + AddOrReplace(m_json, key, copy); + return *this; +} + +Document& Document::WithObject(const Aws::String& key, const Document& value) +{ + return WithObject(key.c_str(), value); +} + +Document& Document::WithObject(const char* key, Document&& value) +{ + if (!m_json) + { + m_json = cJSON_AS4CPP_CreateObject(); + } + + AddOrReplace(m_json, key, value.m_json == nullptr ? cJSON_AS4CPP_CreateObject() : value.m_json); + value.m_json = nullptr; + return *this; +} + +Document& Document::WithObject(const Aws::String& key, Document&& value) +{ + return WithObject(key.c_str(), std::move(value)); +} + +Document& Document::AsObject(const Document& value) +{ + *this = value; + return *this; +} + +Document& Document::AsObject(Document && value) +{ + *this = std::move(value); + return *this; +} + +DocumentView Document::View() const +{ + return *this; +} + +DocumentView::DocumentView() : m_json(nullptr) +{ +} + +DocumentView::DocumentView(const Document& value) : m_json(value.m_json) +{ +} + +DocumentView::DocumentView(cJSON* v) : m_json(v) +{ +} + +DocumentView& DocumentView::operator=(const Document& value) +{ + m_json = value.m_json; + return *this; +} + +DocumentView& DocumentView::operator=(cJSON* value) +{ + m_json = value; + return *this; +} + +Aws::String DocumentView::GetString(const Aws::String& key) const +{ + assert(m_json); + auto item = cJSON_AS4CPP_GetObjectItemCaseSensitive(m_json, key.c_str()); + auto str = cJSON_AS4CPP_GetStringValue(item); + return str ? str : ""; +} + +Aws::String DocumentView::AsString() const +{ + const char* str = cJSON_AS4CPP_GetStringValue(m_json); + if (str == nullptr) + { + return {}; + } + return str; +} + +bool DocumentView::IsString() const +{ + return cJSON_AS4CPP_IsString(m_json) != 0; +} + +bool DocumentView::GetBool(const Aws::String& key) const +{ + assert(m_json); + auto item = cJSON_AS4CPP_GetObjectItemCaseSensitive(m_json, key.c_str()); + assert(item); + return item->valueint != 0; +} + +bool DocumentView::AsBool() const +{ + assert(cJSON_AS4CPP_IsBool(m_json)); + return cJSON_AS4CPP_IsTrue(m_json) != 0; +} + +bool DocumentView::IsBool() const +{ + return cJSON_AS4CPP_IsBool(m_json) != 0; +} + +int DocumentView::GetInteger(const Aws::String& key) const +{ + assert(m_json); + auto item = cJSON_AS4CPP_GetObjectItemCaseSensitive(m_json, key.c_str()); + assert(item); + return item->valueint; +} + +int DocumentView::AsInteger() const +{ + assert(cJSON_AS4CPP_IsNumber(m_json)); // can be double or value larger than int_max, but at least not UB + return m_json->valueint; +} + +bool DocumentView::IsIntegerType() const +{ + if (!cJSON_AS4CPP_IsNumber(m_json)) + { + return false; + } + + if (m_json->valuestring) + { + Aws::String valueString = m_json->valuestring; + return std::all_of(valueString.begin(), valueString.end(), [](unsigned char c){ return ::isdigit(c) || c == '+' || c == '-'; }); + } + return m_json->valuedouble == static_cast<long long>(m_json->valuedouble); +} + +int64_t DocumentView::GetInt64(const Aws::String& key) const +{ + assert(m_json); + auto item = cJSON_AS4CPP_GetObjectItemCaseSensitive(m_json, key.c_str()); + assert(item); + if (item->valuestring) + { + return Aws::Utils::StringUtils::ConvertToInt64(item->valuestring); + } + else + { + return static_cast<int64_t>(item->valuedouble); + } +} + +int64_t DocumentView::AsInt64() const +{ + assert(cJSON_AS4CPP_IsNumber(m_json)); + if (m_json->valuestring) + { + return Aws::Utils::StringUtils::ConvertToInt64(m_json->valuestring); + } + else + { + return static_cast<int64_t>(m_json->valuedouble); + } +} + +double DocumentView::GetDouble(const Aws::String& key) const +{ + assert(m_json); + auto item = cJSON_AS4CPP_GetObjectItemCaseSensitive(m_json, key.c_str()); + assert(item); + return item->valuedouble; +} + +double DocumentView::AsDouble() const +{ + assert(cJSON_AS4CPP_IsNumber(m_json)); + return m_json->valuedouble; +} + +bool DocumentView::IsFloatingPointType() const +{ + if (!cJSON_AS4CPP_IsNumber(m_json)) + { + return false; + } + + if (m_json->valuestring) + { + Aws::String valueString = m_json->valuestring; + return std::any_of(valueString.begin(), valueString.end(), [](unsigned char c){ return !::isdigit(c) && c != '+' && c != '-'; }); + } + return m_json->valuedouble != static_cast<long long>(m_json->valuedouble); +} + +Array<DocumentView> DocumentView::GetArray(const Aws::String& key) const +{ + assert(m_json); + auto array = cJSON_AS4CPP_GetObjectItemCaseSensitive(m_json, key.c_str()); + assert(cJSON_AS4CPP_IsArray(array)); + Array<DocumentView> returnArray(cJSON_AS4CPP_GetArraySize(array)); + + auto element = array->child; + for (unsigned i = 0; element && i < returnArray.GetLength(); ++i, element = element->next) + { + returnArray[i] = element; + } + + return returnArray; +} + +Array<DocumentView> DocumentView::AsArray() const +{ + assert(cJSON_AS4CPP_IsArray(m_json)); + Array<DocumentView> returnArray(cJSON_AS4CPP_GetArraySize(m_json)); + + auto element = m_json->child; + + for (unsigned i = 0; element && i < returnArray.GetLength(); ++i, element = element->next) + { + returnArray[i] = element; + } + + return returnArray; +} + +bool DocumentView::IsListType() const +{ + return cJSON_AS4CPP_IsArray(m_json) != 0; +} + +DocumentView DocumentView::GetObject(const Aws::String& key) const +{ + assert(m_json); + auto item = cJSON_AS4CPP_GetObjectItemCaseSensitive(m_json, key.c_str()); + return item; +} + +DocumentView DocumentView::AsObject() const +{ + assert(cJSON_AS4CPP_IsObject(m_json) || cJSON_AS4CPP_IsNull(m_json)); + return m_json; +} + +bool DocumentView::IsObject() const +{ + return cJSON_AS4CPP_IsObject(m_json) != 0; +} + +bool DocumentView::IsNull() const +{ + return cJSON_AS4CPP_IsNull(m_json) != 0; +} + +Aws::Map<Aws::String, DocumentView> DocumentView::GetAllObjects() const +{ + Aws::Map<Aws::String, DocumentView> valueMap; + if (!m_json) + { + return valueMap; + } + + for (auto iter = m_json->child; iter; iter = iter->next) + { + valueMap.emplace(std::make_pair(Aws::String(iter->string), DocumentView(iter))); + } + + return valueMap; +} + +bool DocumentView::ValueExists(const Aws::String& key) const +{ + if (!cJSON_AS4CPP_IsObject(m_json)) + { + return false; + } + + auto item = cJSON_AS4CPP_GetObjectItemCaseSensitive(m_json, key.c_str()); + return !(item == nullptr || cJSON_AS4CPP_IsNull(item)); +} + +bool DocumentView::KeyExists(const Aws::String& key) const +{ + if (!cJSON_AS4CPP_IsObject(m_json)) + { + return false; + } + + return cJSON_AS4CPP_GetObjectItemCaseSensitive(m_json, key.c_str()) != nullptr;; +} + +Aws::String DocumentView::WriteCompact() const +{ + if (!m_json) + { + return "null"; + } + + auto temp = cJSON_AS4CPP_PrintUnformatted(m_json); + Aws::String out(temp); + cJSON_AS4CPP_free(temp); + return out; +} + +Aws::String DocumentView::WriteReadable() const +{ + if (!m_json) + { + return "null"; + } + + auto temp = cJSON_AS4CPP_Print(m_json); + Aws::String out(temp); + cJSON_AS4CPP_free(temp); + return out; +} + +Document DocumentView::Materialize() const +{ + return m_json; +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/HashingUtils.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/HashingUtils.cpp index 0e49a616343..0431835a615 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/HashingUtils.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/HashingUtils.cpp @@ -11,6 +11,7 @@ #include <aws/core/utils/crypto/Sha256HMAC.h> #include <aws/core/utils/crypto/Sha1.h> #include <aws/core/utils/crypto/MD5.h> +#include <aws/core/utils/crypto/CRC32.h> #include <aws/core/utils/Outcome.h> #include <aws/core/utils/memory/stl/AWSStringStream.h> #include <aws/core/utils/memory/stl/AWSList.h> @@ -234,6 +235,30 @@ ByteBuffer HashingUtils::CalculateMD5(Aws::IOStream& stream) return hash.Calculate(stream).GetResult(); } +ByteBuffer HashingUtils::CalculateCRC32(const Aws::String& str) +{ + CRC32 hash; + return hash.Calculate(str).GetResult(); +} + +ByteBuffer HashingUtils::CalculateCRC32(Aws::IOStream& stream) +{ + CRC32 hash; + return hash.Calculate(stream).GetResult(); +} + +ByteBuffer HashingUtils::CalculateCRC32C(const Aws::String& str) +{ + CRC32C hash; + return hash.Calculate(str).GetResult(); +} + +ByteBuffer HashingUtils::CalculateCRC32C(Aws::IOStream& stream) +{ + CRC32C hash; + return hash.Calculate(stream).GetResult(); +} + int HashingUtils::HashString(const char* strToHash) { if (!strToHash) @@ -242,7 +267,7 @@ int HashingUtils::HashString(const char* strToHash) unsigned hash = 0; while (char charValue = *strToHash++) { - hash = charValue + 31 * hash; + hash = charValue + 31 * hash; } return hash; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CRC32.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CRC32.cpp new file mode 100644 index 00000000000..c09806fbe0b --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CRC32.cpp @@ -0,0 +1,218 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + + +#include <aws/core/utils/crypto/CRC32.h> +#include <aws/core/utils/Outcome.h> +#include <aws/core/utils/crypto/Factories.h> +#include <aws/crt/Types.h> +#include <aws/checksums/crc.h> +#include <aws/common/byte_buf.h> + +using namespace Aws::Utils::Crypto; + +static Aws::Utils::ByteBuffer ByteBufferFromInt32(uint32_t value) +{ + Aws::Utils::ByteBuffer buffer(4); + buffer[0] = (value >> 24) & 0xFF; + buffer[1] = (value >> 16) & 0xFF; + buffer[2] = (value >> 8) & 0xFF; + buffer[3] = value & 0xFF; + return buffer; +} + +CRC32::CRC32() : + m_hashImpl(CreateCRC32Implementation()) +{ +} + +CRC32::~CRC32() +{ +} + +HashResult CRC32::Calculate(const Aws::String& str) +{ + return m_hashImpl->Calculate(str); +} + +HashResult CRC32::Calculate(Aws::IStream& stream) +{ + return m_hashImpl->Calculate(stream); +} + +void CRC32::Update(unsigned char* buffer, size_t bufferSize) +{ + m_hashImpl->Update(buffer, bufferSize); +} + +HashResult CRC32::GetHash() +{ + return m_hashImpl->GetHash(); +} + +CRC32C::CRC32C() : + m_hashImpl(CreateCRC32CImplementation()) +{ +} + +CRC32C::~CRC32C() +{ +} + +HashResult CRC32C::Calculate(const Aws::String& str) +{ + return m_hashImpl->Calculate(str); +} + +HashResult CRC32C::Calculate(Aws::IStream& stream) +{ + return m_hashImpl->Calculate(stream); +} + + +void CRC32C::Update(unsigned char* buffer, size_t bufferSize) +{ + m_hashImpl->Update(buffer, bufferSize); +} + +HashResult CRC32C::GetHash() +{ + return m_hashImpl->GetHash(); +} + + +CRC32Impl::CRC32Impl() : m_runningCrc32(0) {} + +HashResult CRC32Impl::Calculate(const Aws::String& str) +{ + Aws::Crt::ByteCursor byteCursor = Aws::Crt::ByteCursorFromArray(reinterpret_cast<const uint8_t*>(str.data()), str.size()); + + uint32_t runningCrc32 = 0; + while (byteCursor.len > INT_MAX) + { + runningCrc32 = aws_checksums_crc32(byteCursor.ptr, INT_MAX, runningCrc32); + aws_byte_cursor_advance(&byteCursor, INT_MAX); + } + runningCrc32 = aws_checksums_crc32(byteCursor.ptr, static_cast<int>(byteCursor.len), runningCrc32); + const Aws::Utils::ByteBuffer& hash = ByteBufferFromInt32(runningCrc32); + return HashResult(std::move(hash)); +} + +HashResult CRC32Impl::Calculate(Aws::IStream& stream) +{ + uint32_t runningCrc32 = 0; + + auto currentPos = stream.tellg(); + if (currentPos == std::ios::pos_type(-1)) + { + currentPos = 0; + stream.clear(); + } + + stream.seekg(0, stream.beg); + + uint8_t streamBuffer[Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE]; + while (stream.good()) + { + stream.read(reinterpret_cast<char*>(streamBuffer), Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE); + auto bytesRead = stream.gcount(); + + if (bytesRead > 0) + { + runningCrc32 = aws_checksums_crc32(streamBuffer, static_cast<int>(bytesRead), runningCrc32); + } + } + + stream.clear(); + stream.seekg(currentPos, stream.beg); + + const Aws::Utils::ByteBuffer& hash = ByteBufferFromInt32(runningCrc32); + return HashResult(std::move(hash)); +} + +void CRC32Impl::Update(unsigned char* buffer, size_t bufferSize) +{ + Aws::Crt::ByteCursor byteCursor = Aws::Crt::ByteCursorFromArray(buffer, bufferSize); + + while (byteCursor.len > INT_MAX) + { + m_runningCrc32 = aws_checksums_crc32(byteCursor.ptr, INT_MAX, m_runningCrc32); + aws_byte_cursor_advance(&byteCursor, INT_MAX); + } + m_runningCrc32 = aws_checksums_crc32(byteCursor.ptr, static_cast<int>(byteCursor.len), m_runningCrc32); +} + +HashResult CRC32Impl::GetHash() +{ + const Aws::Utils::ByteBuffer& hash = ByteBufferFromInt32(m_runningCrc32); + return HashResult(std::move(hash)); +} + +CRC32CImpl::CRC32CImpl() : m_runningCrc32c(0) {} + +HashResult CRC32CImpl::Calculate(const Aws::String& str) +{ + Aws::Crt::ByteCursor byteCursor = Aws::Crt::ByteCursorFromArray(reinterpret_cast<const uint8_t*>(str.data()), str.size()); + + uint32_t runningCrc32c = 0; + while (byteCursor.len > INT_MAX) + { + runningCrc32c = aws_checksums_crc32c(byteCursor.ptr, INT_MAX, runningCrc32c); + aws_byte_cursor_advance(&byteCursor, INT_MAX); + } + runningCrc32c = aws_checksums_crc32c(byteCursor.ptr, static_cast<int>(byteCursor.len), runningCrc32c); + const Aws::Utils::ByteBuffer& hash = ByteBufferFromInt32(runningCrc32c); + return HashResult(std::move(hash)); +} + +HashResult CRC32CImpl::Calculate(Aws::IStream& stream) +{ + uint32_t runningCrc32c = 0; + + auto currentPos = stream.tellg(); + if (currentPos == std::ios::pos_type(-1)) + { + currentPos = 0; + stream.clear(); + } + + stream.seekg(0, stream.beg); + + uint8_t streamBuffer[Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE]; + while (stream.good()) + { + stream.read(reinterpret_cast<char*>(streamBuffer), Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE); + auto bytesRead = stream.gcount(); + + if (bytesRead > 0) + { + runningCrc32c = aws_checksums_crc32c(streamBuffer, static_cast<int>(bytesRead), runningCrc32c); + } + } + + stream.clear(); + stream.seekg(currentPos, stream.beg); + + const Aws::Utils::ByteBuffer& hash = ByteBufferFromInt32(runningCrc32c); + return HashResult(std::move(hash)); +} + +void CRC32CImpl::Update(unsigned char* buffer, size_t bufferSize) +{ + Aws::Crt::ByteCursor byteCursor = Aws::Crt::ByteCursorFromArray(buffer, bufferSize); + + while (byteCursor.len > INT_MAX) + { + m_runningCrc32c = aws_checksums_crc32c(byteCursor.ptr, INT_MAX, m_runningCrc32c); + aws_byte_cursor_advance(&byteCursor, INT_MAX); + } + m_runningCrc32c = aws_checksums_crc32c(byteCursor.ptr, static_cast<int>(byteCursor.len), m_runningCrc32c); +} + +HashResult CRC32CImpl::GetHash() +{ + const Aws::Utils::ByteBuffer& hash = ByteBufferFromInt32(m_runningCrc32c); + return HashResult(std::move(hash)); +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/MD5.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/MD5.cpp index bf14ace1ad3..f442878a90b 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/MD5.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/MD5.cpp @@ -11,7 +11,7 @@ using namespace Aws::Utils::Crypto; -MD5::MD5() : +MD5::MD5() : m_hashImpl(CreateMD5Implementation()) { } @@ -28,4 +28,14 @@ HashResult MD5::Calculate(const Aws::String& str) HashResult MD5::Calculate(Aws::IStream& stream) { return m_hashImpl->Calculate(stream); -}
\ No newline at end of file +} + +void MD5::Update(unsigned char* buffer, size_t bufferSize) +{ + return m_hashImpl->Update(buffer, bufferSize); +} + +HashResult MD5::GetHash() +{ + return m_hashImpl->GetHash(); +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha1.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha1.cpp index 5da3e63d28f..a6783e18f0f 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha1.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha1.cpp @@ -28,3 +28,13 @@ HashResult Sha1::Calculate(Aws::IStream& stream) { return m_hashImpl->Calculate(stream); } + +void Sha1::Update(unsigned char* buffer, size_t bufferSize) +{ + return m_hashImpl->Update(buffer, bufferSize); +} + +HashResult Sha1::GetHash() +{ + return m_hashImpl->GetHash(); +}
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256.cpp index a8aa5ae8790..48612e8cf03 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256.cpp @@ -27,4 +27,14 @@ HashResult Sha256::Calculate(const Aws::String& str) HashResult Sha256::Calculate(Aws::IStream& stream) { return m_hashImpl->Calculate(stream); -}
\ No newline at end of file +} + +void Sha256::Update(unsigned char* buffer, size_t bufferSize) +{ + return m_hashImpl->Update(buffer, bufferSize); +} + +HashResult Sha256::GetHash() +{ + return m_hashImpl->GetHash(); +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/factory/Factories.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/factory/Factories.cpp index 88ca147d116..cba90af4f4d 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/factory/Factories.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/factory/Factories.cpp @@ -7,6 +7,7 @@ #include <aws/core/utils/crypto/Factories.h> #include <aws/core/utils/crypto/Hash.h> #include <aws/core/utils/crypto/HMAC.h> +#include <aws/core/utils/crypto/CRC32.h> #if ENABLE_BCRYPT_ENCRYPTION #error #include <aws/core/utils/crypto/bcrypt/CryptoImpl.h> @@ -35,6 +36,18 @@ static std::shared_ptr<HashFactory>& GetMD5Factory() return s_MD5Factory; } +static std::shared_ptr<HashFactory>& GetCRC32Factory() +{ + static std::shared_ptr<HashFactory> s_CRC32Factory(nullptr); + return s_CRC32Factory; +} + +static std::shared_ptr<HashFactory>& GetCRC32CFactory() +{ + static std::shared_ptr<HashFactory> s_CRC32CFactory(nullptr); + return s_CRC32CFactory; +} + static std::shared_ptr<HashFactory>& GetSha1Factory() { static std::shared_ptr<HashFactory> s_Sha1Factory(nullptr); @@ -136,6 +149,24 @@ public: } }; +class DefaultCRC32Factory : public HashFactory +{ +public: + std::shared_ptr<Hash> CreateImplementation() const override + { + return Aws::MakeShared<CRC32Impl>(s_allocationTag); + } +}; + +class DefaultCRC32CFactory : public HashFactory +{ +public: + std::shared_ptr<Hash> CreateImplementation() const override + { + return Aws::MakeShared<CRC32CImpl>(s_allocationTag); + } +}; + class DefaultSHA1Factory : public HashFactory { public: @@ -667,6 +698,16 @@ void Aws::Utils::Crypto::InitCrypto() GetMD5Factory()->InitStaticState(); } + if(!GetCRC32Factory()) + { + GetCRC32Factory() = Aws::MakeShared<DefaultCRC32Factory>(s_allocationTag); + } + + if(!GetCRC32CFactory()) + { + GetCRC32CFactory() = Aws::MakeShared<DefaultCRC32CFactory>(s_allocationTag); + } + if(GetSha1Factory()) { GetSha1Factory()->InitStaticState(); @@ -754,6 +795,16 @@ void Aws::Utils::Crypto::CleanupCrypto() GetMD5Factory() = nullptr; } + if(GetCRC32CFactory()) + { + GetCRC32Factory() = nullptr; + } + + if(GetCRC32CFactory()) + { + GetCRC32CFactory() = nullptr; + } + if(GetSha1Factory()) { GetSha1Factory()->CleanupStaticState(); @@ -809,6 +860,16 @@ void Aws::Utils::Crypto::SetMD5Factory(const std::shared_ptr<HashFactory>& facto GetMD5Factory() = factory; } +void Aws::Utils::Crypto::SetCRC32Factory(const std::shared_ptr<HashFactory>& factory) +{ + GetCRC32Factory() = factory; +} + +void Aws::Utils::Crypto::SetCRC32CFactory(const std::shared_ptr<HashFactory>& factory) +{ + GetCRC32CFactory() = factory; +} + void Aws::Utils::Crypto::SetSha1Factory(const std::shared_ptr<HashFactory>& factory) { GetSha1Factory() = factory; @@ -854,6 +915,16 @@ std::shared_ptr<Hash> Aws::Utils::Crypto::CreateMD5Implementation() return GetMD5Factory()->CreateImplementation(); } +std::shared_ptr<Hash> Aws::Utils::Crypto::CreateCRC32Implementation() +{ + return GetCRC32Factory()->CreateImplementation(); +} + +std::shared_ptr<Hash> Aws::Utils::Crypto::CreateCRC32CImplementation() +{ + return GetCRC32CFactory()->CreateImplementation(); +} + std::shared_ptr<Hash> Aws::Utils::Crypto::CreateSha1Implementation() { return GetSha1Factory()->CreateImplementation(); @@ -967,5 +1038,5 @@ std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_KeyWrapImplementa std::shared_ptr<SecureRandomBytes> Aws::Utils::Crypto::CreateSecureRandomBytesImplementation() { - return GetSecureRandom(); + return GetSecureRandomFactory()->CreateImplementation(); } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/openssl/CryptoImpl.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/openssl/CryptoImpl.cpp index 3a89265e6ec..faebde3a8d5 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/openssl/CryptoImpl.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/openssl/CryptoImpl.cpp @@ -8,6 +8,7 @@ #include <aws/core/utils/memory/AWSMemory.h> #include <aws/core/utils/crypto/openssl/CryptoImpl.h> #include <aws/core/utils/Outcome.h> +#include <openssl/crypto.h> #include <openssl/md5.h> #ifdef OPENSSL_IS_BORINGSSL @@ -47,9 +48,19 @@ namespace Aws */ #if defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER == 0x20000000L) #undef OPENSSL_VERSION_NUMBER +#if LIBRESSL_VERSION_NUMBER < 0x3050000fL #define OPENSSL_VERSION_NUMBER 0x1000107fL +#else +#define OPENSSL_VERSION_NUMBER 0x1010000fL +#endif #endif + #define OPENSSL_VERSION_LESS_1_1 (OPENSSL_VERSION_NUMBER < 0x10100003L) +#define OPENSSL_VERSION_LESS_3_0 (OPENSSL_VERSION_NUMBER < 0x30000000L) + +#if !OPENSSL_VERSION_LESS_3_0 +#error #include <openssl/core_names.h> +#endif #if OPENSSL_VERSION_LESS_1_1 static const char* OPENSSL_INTERNALS_TAG = "OpenSSLCallbackState"; @@ -65,7 +76,7 @@ namespace Aws #else OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS /*options*/ ,NULL /* OpenSSL init settings*/ ); #endif -#if !defined(OPENSSL_IS_BORINGSSL) +#if !(defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)) OPENSSL_add_all_algorithms_noconf(); #endif #if OPENSSL_VERSION_LESS_1_1 @@ -168,6 +179,22 @@ namespace Aws EVP_MD_CTX *m_ctx; }; + MD5OpenSSLImpl::MD5OpenSSLImpl() + { + m_ctx = EVP_MD_CTX_create(); + assert(m_ctx != nullptr); +#if !defined(OPENSSL_IS_BORINGSSL) + EVP_MD_CTX_set_flags(m_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); +#endif + EVP_DigestInit_ex(m_ctx, EVP_md5(), nullptr); + } + + MD5OpenSSLImpl::~MD5OpenSSLImpl() + { + EVP_MD_CTX_destroy(m_ctx); + m_ctx = nullptr; + } + HashResult MD5OpenSSLImpl::Calculate(const Aws::String& str) { OpensslCtxRAIIGuard guard; @@ -222,6 +249,34 @@ namespace Aws return HashResult(std::move(hash)); } + void MD5OpenSSLImpl::Update(unsigned char* buffer, size_t bufferSize) + { + EVP_DigestUpdate(m_ctx, buffer, bufferSize); + } + + HashResult MD5OpenSSLImpl::GetHash() + { + ByteBuffer hash(EVP_MD_size(EVP_md5())); + EVP_DigestFinal(m_ctx, hash.GetUnderlyingData(), nullptr); + return HashResult(std::move(hash)); + } + + Sha1OpenSSLImpl::Sha1OpenSSLImpl() + { + m_ctx = EVP_MD_CTX_create(); + assert(m_ctx != nullptr); +#if !defined(OPENSSL_IS_BORINGSSL) + EVP_MD_CTX_set_flags(m_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); +#endif + EVP_DigestInit_ex(m_ctx, EVP_sha1(), nullptr); + } + + Sha1OpenSSLImpl::~Sha1OpenSSLImpl() + { + EVP_MD_CTX_destroy(m_ctx); + m_ctx = nullptr; + } + HashResult Sha1OpenSSLImpl::Calculate(const Aws::String& str) { OpensslCtxRAIIGuard guard; @@ -272,6 +327,34 @@ namespace Aws return HashResult(std::move(hash)); } + void Sha1OpenSSLImpl::Update(unsigned char* buffer, size_t bufferSize) + { + EVP_DigestUpdate(m_ctx, buffer, bufferSize); + } + + HashResult Sha1OpenSSLImpl::GetHash() + { + ByteBuffer hash(EVP_MD_size(EVP_sha1())); + EVP_DigestFinal(m_ctx, hash.GetUnderlyingData(), nullptr); + return HashResult(std::move(hash)); + } + + Sha256OpenSSLImpl::Sha256OpenSSLImpl() + { + m_ctx = EVP_MD_CTX_create(); + assert(m_ctx != nullptr); +#if !defined(OPENSSL_IS_BORINGSSL) + EVP_MD_CTX_set_flags(m_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); +#endif + EVP_DigestInit_ex(m_ctx, EVP_sha256(), nullptr); + } + + Sha256OpenSSLImpl::~Sha256OpenSSLImpl() + { + EVP_MD_CTX_destroy(m_ctx); + m_ctx = nullptr; + } + HashResult Sha256OpenSSLImpl::Calculate(const Aws::String& str) { OpensslCtxRAIIGuard guard; @@ -322,13 +405,28 @@ namespace Aws return HashResult(std::move(hash)); } + void Sha256OpenSSLImpl::Update(unsigned char* buffer, size_t bufferSize) + { + EVP_DigestUpdate(m_ctx, buffer, bufferSize); + } + + HashResult Sha256OpenSSLImpl::GetHash() + { + ByteBuffer hash(EVP_MD_size(EVP_sha256())); + EVP_DigestFinal(m_ctx, hash.GetUnderlyingData(), nullptr); + return HashResult(std::move(hash)); + } + class HMACRAIIGuard { public: HMACRAIIGuard() { #if OPENSSL_VERSION_LESS_1_1 m_ctx = Aws::New<HMAC_CTX>("AllocSha256HAMCOpenSSLContext"); -#else +#elif OPENSSL_VERSION_LESS_3_0 m_ctx = HMAC_CTX_new(); +#else + m_mac = EVP_MAC_fetch(NULL, "HMAC", NULL); + m_ctx = EVP_MAC_CTX_new(m_mac); #endif assert(m_ctx != nullptr); } @@ -336,17 +434,29 @@ namespace Aws ~HMACRAIIGuard() { #if OPENSSL_VERSION_LESS_1_1 Aws::Delete<HMAC_CTX>(m_ctx); -#else +#elif OPENSSL_VERSION_LESS_3_0 HMAC_CTX_free(m_ctx); +#else + EVP_MAC_free(m_mac); + EVP_MAC_CTX_free(m_ctx); #endif m_ctx = nullptr; } +#if OPENSSL_VERSION_LESS_3_0 HMAC_CTX* getResource() { +#else + EVP_MAC_CTX* getResource() { +#endif return m_ctx; } private: +#if OPENSSL_VERSION_LESS_3_0 HMAC_CTX *m_ctx; +#else + EVP_MAC *m_mac; + EVP_MAC_CTX *m_ctx; +#endif }; HashResult Sha256HMACOpenSSLImpl::Calculate(const ByteBuffer& toSign, const ByteBuffer& secret) @@ -356,20 +466,36 @@ namespace Aws memset(digest.GetUnderlyingData(), 0, length); HMACRAIIGuard guard; +#if OPENSSL_VERSION_LESS_3_0 HMAC_CTX* m_ctx = guard.getResource(); +#else + EVP_MAC_CTX* m_ctx = guard.getResource(); +#endif #if OPENSSL_VERSION_LESS_1_1 HMAC_CTX_init(m_ctx); #endif +#if OPENSSL_VERSION_LESS_3_0 HMAC_Init_ex(m_ctx, secret.GetUnderlyingData(), static_cast<int>(secret.GetLength()), EVP_sha256(), NULL); HMAC_Update(m_ctx, toSign.GetUnderlyingData(), toSign.GetLength()); HMAC_Final(m_ctx, digest.GetUnderlyingData(), &length); +#else + char sha256[] {"SHA256"}; + OSSL_PARAM ossl_params[2]; + ossl_params[0] = + OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, sha256, 0); + ossl_params[1] = OSSL_PARAM_construct_end(); + EVP_MAC_init(m_ctx, secret.GetUnderlyingData(), + static_cast<int>(secret.GetLength()), ossl_params); + EVP_MAC_update(m_ctx, toSign.GetUnderlyingData(), toSign.GetLength()); + EVP_MAC_final(m_ctx, digest.GetUnderlyingData(), NULL, length); +#endif #if OPENSSL_VERSION_LESS_1_1 HMAC_CTX_cleanup(m_ctx); -#else +#elif OPENSSL_VERSION_LESS_3_0 HMAC_CTX_reset(m_ctx); #endif return HashResult(std::move(digest)); @@ -547,7 +673,7 @@ namespace Aws CryptoBuffer finalBlock(GetBlockSizeBytes()); int writtenSize = static_cast<int>(finalBlock.GetLength()); int ret = EVP_DecryptFinal_ex(m_decryptor_ctx, finalBlock.GetUnderlyingData(), &writtenSize); -#if OPENSSL_VERSION_NUMBER > 0x1010104fL //1.1.1d +#if !defined(OPENSSL_IS_AWSLC) && OPENSSL_VERSION_NUMBER > 0x1010104fL //1.1.1d if (ret <= 0) #else if (ret <= 0 && !m_emptyPlaintext) // see details why making exception for empty string at: https://github.com/aws/aws-sdk-cpp/issues/1413 diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamDecoder.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamDecoder.cpp index f70a6c88f61..053ff938d44 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamDecoder.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamDecoder.cpp @@ -72,9 +72,7 @@ namespace Aws assert(handler); if (!handler) { - AWS_LOGSTREAM_ERROR(EVENT_STREAM_DECODER_CLASS_TAG, "Payload received, but decoder encountered internal errors before." - "ErrorCode: " << EventStreamErrorsMapper::GetNameForError(handler->GetInternalError()) << ", " - "ErrorMessage: " << handler->GetEventPayloadAsString()); + AWS_LOGSTREAM_ERROR(EVENT_STREAM_DECODER_CLASS_TAG, "Payload received, but handler is null."); return; } handler->WriteMessageEventPayload(static_cast<unsigned char*>(payload->buffer), payload->len); @@ -129,9 +127,7 @@ namespace Aws assert(handler); if (!handler) { - AWS_LOGSTREAM_ERROR(EVENT_STREAM_DECODER_CLASS_TAG, "Payload received, but decoder encountered internal errors before." - "ErrorCode: " << EventStreamErrorsMapper::GetNameForError(handler->GetInternalError()) << ", " - "ErrorMessage: " << handler->GetEventPayloadAsString()); + AWS_LOGSTREAM_ERROR(EVENT_STREAM_DECODER_CLASS_TAG, "Header received, but handler is null."); return; } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamEncoder.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamEncoder.cpp index ef7104e839c..750bf9e1e6d 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamEncoder.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamEncoder.cpp @@ -80,80 +80,83 @@ namespace Aws Aws::Vector<unsigned char> EventStreamEncoder::EncodeAndSign(const Aws::Utils::Event::Message& msg) { - aws_event_stream_message encoded = Encode(msg); - aws_event_stream_message signedMessage = Sign(&encoded); + Aws::Vector<unsigned char> outputBits; - const auto signedMessageLength = signedMessage.message_buffer ? aws_event_stream_message_total_length(&signedMessage) : 0; + aws_event_stream_message encoded; + if (InitEncodedStruct(msg, &encoded)) + { + aws_event_stream_message signedMessage; + if (InitSignedStruct(&encoded, &signedMessage)) + { + // success! + const auto signedMessageBuffer = aws_event_stream_message_buffer(&signedMessage); + const auto signedMessageLength = aws_event_stream_message_total_length(&signedMessage); + outputBits.reserve(signedMessageLength); + outputBits.insert(outputBits.end(), signedMessageBuffer, signedMessageBuffer + signedMessageLength); + + aws_event_stream_message_clean_up(&signedMessage); + } + aws_event_stream_message_clean_up(&encoded); + } - Aws::Vector<unsigned char> outputBits(signedMessage.message_buffer, signedMessage.message_buffer + signedMessageLength); - aws_event_stream_message_clean_up(&encoded); - aws_event_stream_message_clean_up(&signedMessage); return outputBits; } - aws_event_stream_message EventStreamEncoder::Encode(const Aws::Utils::Event::Message& msg) + bool EventStreamEncoder::InitEncodedStruct(const Aws::Utils::Event::Message& msg, aws_event_stream_message* encoded) { + bool success = false; + aws_array_list headers; EncodeHeaders(msg, &headers); - aws_byte_buf payload; - payload.len = msg.GetEventPayload().size(); - // this const_cast is OK because aws_byte_buf will only be "read from" by the following functions. - payload.buffer = const_cast<uint8_t*>(msg.GetEventPayload().data()); - payload.capacity = 0; - payload.allocator = nullptr; + aws_byte_buf payload = aws_byte_buf_from_array(msg.GetEventPayload().data(), msg.GetEventPayload().size()); - aws_event_stream_message encoded; - if(aws_event_stream_message_init(&encoded, get_aws_allocator(), &headers, &payload) == AWS_OP_ERR) + if(aws_event_stream_message_init(encoded, get_aws_allocator(), &headers, &payload) == AWS_OP_SUCCESS) + { + success = true; + } + else { AWS_LOGSTREAM_ERROR(TAG, "Error creating event-stream message from payload."); - aws_event_stream_headers_list_cleanup(&headers); - // GCC 4.9.4 issues a warning with -Wextra if we simply do - // return {}; - aws_event_stream_message empty{nullptr, nullptr, 0}; - return empty; } + aws_event_stream_headers_list_cleanup(&headers); - return encoded; + return success; } - aws_event_stream_message EventStreamEncoder::Sign(aws_event_stream_message* msg) + bool EventStreamEncoder::InitSignedStruct(const aws_event_stream_message* msg, aws_event_stream_message* signedmsg) { - const auto msglen = msg->message_buffer ? aws_event_stream_message_total_length(msg) : 0; + bool success = false; + + const auto msgbuf = aws_event_stream_message_buffer(msg); + const auto msglen = aws_event_stream_message_total_length(msg); Event::Message signedMessage; - signedMessage.WriteEventPayload(msg->message_buffer, msglen); + signedMessage.WriteEventPayload(msgbuf, msglen); assert(m_signer); - if (!m_signer->SignEventMessage(signedMessage, m_signatureSeed)) + if (m_signer->SignEventMessage(signedMessage, m_signatureSeed)) { - AWS_LOGSTREAM_ERROR(TAG, "Failed to sign event message frame."); - // GCC 4.9.4 issues a warning with -Wextra if we simply do - // return {}; - aws_event_stream_message empty{nullptr, nullptr, 0}; - return empty; - } - - aws_array_list headers; - EncodeHeaders(signedMessage, &headers); + aws_array_list headers; + EncodeHeaders(signedMessage, &headers); - aws_byte_buf payload; - payload.len = signedMessage.GetEventPayload().size(); - payload.buffer = signedMessage.GetEventPayload().data(); - payload.capacity = 0; - payload.allocator = nullptr; + aws_byte_buf payload = aws_byte_buf_from_array(signedMessage.GetEventPayload().data(), signedMessage.GetEventPayload().size()); - aws_event_stream_message signedmsg; - if(aws_event_stream_message_init(&signedmsg, get_aws_allocator(), &headers, &payload)) - { - AWS_LOGSTREAM_ERROR(TAG, "Error creating event-stream message from payload."); + if(aws_event_stream_message_init(signedmsg, get_aws_allocator(), &headers, &payload) == AWS_OP_SUCCESS) + { + success = true; + } + else + { + AWS_LOGSTREAM_ERROR(TAG, "Error creating event-stream message from payload."); + } aws_event_stream_headers_list_cleanup(&headers); - // GCC 4.9.4 issues a warning with -Wextra if we simply do - // return {}; - aws_event_stream_message empty{nullptr, nullptr, 0}; - return empty; } - aws_event_stream_headers_list_cleanup(&headers); - return signedmsg; + else + { + AWS_LOGSTREAM_ERROR(TAG, "Failed to sign event message frame."); + } + + return success; } } // namespace Event diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp index 9358d00c0a8..ebfd5d44568 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp @@ -9,6 +9,7 @@ #include <algorithm> #include <aws/core/utils/memory/stl/AWSStringStream.h> #include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/Document.h> using namespace Aws::Utils; using namespace Aws::Utils::Json; @@ -68,6 +69,13 @@ JsonValue::JsonValue(JsonValue&& value) : value.m_value = nullptr; } +JsonValue::JsonValue(const Aws::Utils::DocumentView& value) : + m_value(cJSON_AS4CPP_Duplicate(value.m_json, true/*recurse*/)), + m_wasParseSuccessful(true), + m_errorMessage({}) +{ +} + void JsonValue::Destroy() { cJSON_AS4CPP_Delete(m_value); @@ -106,6 +114,15 @@ JsonValue& JsonValue::operator=(JsonValue&& other) return *this; } +JsonValue& JsonValue::operator=(const Aws::Utils::DocumentView& other) +{ + Destroy(); + m_value = cJSON_AS4CPP_Duplicate(other.m_json, true /*recurse*/); + m_wasParseSuccessful = true; + m_errorMessage = {}; + return *this; +} + static void AddOrReplace(cJSON* root, const char* key, cJSON* value) { const auto existing = cJSON_AS4CPP_GetObjectItemCaseSensitive(root, key); diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/CRTLogSystem.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/CRTLogSystem.cpp new file mode 100644 index 00000000000..81f94d0d3af --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/CRTLogSystem.cpp @@ -0,0 +1,107 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/utils/logging/CRTLogSystem.h> +#include <aws/core/utils/logging/AWSLogging.h> +#include <aws/core/utils/logging/LogSystemInterface.h> +#include <aws/core/utils/Array.h> +#include <aws/common/common.h> +#include <cstdarg> + +using namespace Aws::Utils; +using namespace Aws::Utils::Logging; + +namespace Aws +{ + namespace Utils + { + namespace Logging + { + static int s_aws_logger_redirect_log( + struct aws_logger *logger, + enum aws_log_level log_level, + aws_log_subject_t subject, + const char *format, ...) + { + DefaultCRTLogSystem* crtLogSystem = reinterpret_cast<DefaultCRTLogSystem*>(logger->p_impl); + Logging::LogLevel logLevel = static_cast<LogLevel>(log_level); + const char* subjectName = aws_log_subject_name(subject); + va_list args; + va_start(args, format); + crtLogSystem->Log(logLevel, subjectName, format, args); + va_end(args); + return AWS_OP_SUCCESS; + } + + static enum aws_log_level s_aws_logger_redirect_get_log_level(struct aws_logger *logger, aws_log_subject_t subject) { + (void)subject; + DefaultCRTLogSystem* crtLogSystem = reinterpret_cast<DefaultCRTLogSystem*>(logger->p_impl); + return (aws_log_level)(crtLogSystem->GetLogLevel()); + } + + static void s_aws_logger_redirect_clean_up(struct aws_logger *logger) { + (void)logger; + } + + static int s_aws_logger_redirect_set_log_level(struct aws_logger *logger, enum aws_log_level log_level) + { + DefaultCRTLogSystem* crtLogSystem = reinterpret_cast<DefaultCRTLogSystem*>(logger->p_impl); + crtLogSystem->SetLogLevel(static_cast<LogLevel>(log_level)); + return AWS_OP_SUCCESS; + } + + static struct aws_logger_vtable s_aws_logger_redirect_vtable = { + s_aws_logger_redirect_log, // .log + s_aws_logger_redirect_get_log_level, // .get_log_level + s_aws_logger_redirect_clean_up, // .clean_up + s_aws_logger_redirect_set_log_level // set_log_level + }; + + DefaultCRTLogSystem::DefaultCRTLogSystem(LogLevel logLevel) : + m_logLevel(logLevel), + m_logger() + { + m_logger.vtable = &s_aws_logger_redirect_vtable; + m_logger.allocator = Aws::get_aws_allocator(); + m_logger.p_impl = this; + + aws_logger_set(&m_logger); + } + + DefaultCRTLogSystem::~DefaultCRTLogSystem() + { + if (aws_logger_get() == &m_logger) + { + aws_logger_set(NULL); + aws_logger_clean_up(&m_logger); + } + } + + void DefaultCRTLogSystem::Log(LogLevel logLevel, const char* subjectName, const char* formatStr, va_list args) + { + va_list tmp_args; + va_copy(tmp_args, args); + #ifdef _WIN32 + const int requiredLength = _vscprintf(formatStr, tmp_args) + 1; + #else + const int requiredLength = vsnprintf(nullptr, 0, formatStr, tmp_args) + 1; + #endif + va_end(tmp_args); + + Array<char> outputBuff(requiredLength); + #ifdef _WIN32 + vsnprintf_s(outputBuff.GetUnderlyingData(), requiredLength, _TRUNCATE, formatStr, args); + #else + vsnprintf(outputBuff.GetUnderlyingData(), requiredLength, formatStr, args); + #endif // _WIN32 + + Aws::OStringStream logStream; + logStream << outputBuff.GetUnderlyingData(); + Logging::GetLogSystem()->LogStream(logLevel, subjectName, logStream); + } + } + } +} + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/CRTLogging.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/CRTLogging.cpp new file mode 100644 index 00000000000..5875ead9c01 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/CRTLogging.cpp @@ -0,0 +1,31 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/utils/logging/CRTLogging.h> +#include <aws/common/logging.h> +#include <memory> + +using namespace Aws::Utils; +using namespace Aws::Utils::Logging; + +namespace Aws +{ +namespace Utils +{ +namespace Logging { + +static std::shared_ptr<CRTLogSystemInterface> CRTLogSystem(nullptr); + +void InitializeCRTLogging(const std::shared_ptr<CRTLogSystemInterface>& crtLogSystem) { + CRTLogSystem = crtLogSystem; +} + +void ShutdownCRTLogging() { + CRTLogSystem = nullptr; +} + +} // namespace Logging +} // namespace Utils +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/FormattedLogSystem.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/FormattedLogSystem.cpp index 41c4d7e09c5..26348b68fe2 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/FormattedLogSystem.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/FormattedLogSystem.cpp @@ -72,7 +72,7 @@ void FormattedLogSystem::Log(LogLevel logLevel, const char* tag, const char* for va_list tmp_args; //unfortunately you cannot consume a va_list twice va_copy(tmp_args, args); //so we have to copy it - #ifdef WIN32 + #ifdef _WIN32 const int requiredLength = _vscprintf(formatStr, tmp_args) + 1; #else const int requiredLength = vsnprintf(nullptr, 0, formatStr, tmp_args) + 1; @@ -80,11 +80,11 @@ void FormattedLogSystem::Log(LogLevel logLevel, const char* tag, const char* for va_end(tmp_args); Array<char> outputBuff(requiredLength); - #ifdef WIN32 + #ifdef _WIN32 vsnprintf_s(outputBuff.GetUnderlyingData(), requiredLength, _TRUNCATE, formatStr, args); #else vsnprintf(outputBuff.GetUnderlyingData(), requiredLength, formatStr, args); - #endif // WIN32 + #endif // _WIN32 ss << outputBuff.GetUnderlyingData() << std::endl; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ResponseStream.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ResponseStream.cpp index 6d1f90ed124..26c92eaafdf 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ResponseStream.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ResponseStream.cpp @@ -5,6 +5,7 @@ #include <aws/core/utils/stream/ResponseStream.h> #include <aws/core/utils/memory/stl/AWSStringStream.h> +#include <aws/core/utils/logging/LogMacros.h> #if defined(_GLIBCXX_FULLY_DYNAMIC_STRING) && _GLIBCXX_FULLY_DYNAMIC_STRING == 0 && defined(__ANDROID__) #include <aws/core/utils/stream/SimpleStreamBuf.h> @@ -15,6 +16,8 @@ using DefaultStreamBufType = Aws::StringBuf; using namespace Aws::Utils::Stream; +const int ResponseStream::ResponseStream::xindex = std::ios_base::xalloc(); + ResponseStream::ResponseStream(void) : m_underlyingStream(nullptr) { @@ -23,16 +26,20 @@ ResponseStream::ResponseStream(void) : ResponseStream::ResponseStream(Aws::IOStream* underlyingStreamToManage) : m_underlyingStream(underlyingStreamToManage) { + RegisterStream(); } ResponseStream::ResponseStream(const Aws::IOStreamFactory& factory) : m_underlyingStream(factory()) { + RegisterStream(); } ResponseStream::ResponseStream(ResponseStream&& toMove) : m_underlyingStream(toMove.m_underlyingStream) { + toMove.DeregisterStream(); toMove.m_underlyingStream = nullptr; + RegisterStream(); } ResponseStream& ResponseStream::operator=(ResponseStream&& toMove) @@ -43,12 +50,26 @@ ResponseStream& ResponseStream::operator=(ResponseStream&& toMove) } ReleaseStream(); + toMove.DeregisterStream(); m_underlyingStream = toMove.m_underlyingStream; toMove.m_underlyingStream = nullptr; + RegisterStream(); return *this; } +Aws::IOStream& ResponseStream::GetUnderlyingStream() const +{ + if (!m_underlyingStream) + { + assert(m_underlyingStream); + AWS_LOGSTREAM_FATAL("ResponseStream", "Unexpected nullptr m_underlyingStream"); + static DefaultUnderlyingStream fallbackStream; // we are already in UB, let's just not crash existing apps + return fallbackStream; + } + return *m_underlyingStream; +} + ResponseStream::~ResponseStream() { ReleaseStream(); @@ -58,13 +79,53 @@ void ResponseStream::ReleaseStream() { if (m_underlyingStream) { - m_underlyingStream->flush(); + DeregisterStream(); Aws::Delete(m_underlyingStream); } m_underlyingStream = nullptr; } +void ResponseStream::RegisterStream() +{ + if (m_underlyingStream) + { + ResponseStream* pThat = static_cast<ResponseStream*>(m_underlyingStream->pword(ResponseStream::xindex)); + if (pThat != nullptr) + { + // callback is already registered + assert(pThat != this); // Underlying stream must not be owned by more than one ResponseStream + } + else + { + m_underlyingStream->register_callback(ResponseStream::StreamCallback, ResponseStream::xindex); + } + m_underlyingStream->pword(ResponseStream::xindex) = this; + } +} + +void ResponseStream::DeregisterStream() +{ + if (m_underlyingStream) + { + assert(static_cast<ResponseStream*>(m_underlyingStream->pword(ResponseStream::xindex)) == this); // Attempt to deregister another ResponseStream's stream + m_underlyingStream->pword(ResponseStream::xindex) = nullptr; // ios does not support deregister, so just erasing the context + } +} + +void ResponseStream::StreamCallback(Aws::IOStream::event evt, std::ios_base& stream, int idx) +{ + if (evt == std::ios_base::erase_event) + { + ResponseStream* pThis = static_cast<ResponseStream*>(stream.pword(idx)); + if (pThis) + { + // m_underlyingStream is being destructed, let's avoid double destruction or having a dangling pointer + pThis->m_underlyingStream = nullptr; + } + } +} + static const char *DEFAULT_STREAM_TAG = "DefaultUnderlyingStream"; DefaultUnderlyingStream::DefaultUnderlyingStream() : diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/SimpleStreamBuf.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/SimpleStreamBuf.cpp index 6e429947445..dbf77ab6468 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/SimpleStreamBuf.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/SimpleStreamBuf.cpp @@ -5,6 +5,7 @@ */ #include <aws/core/utils/stream/SimpleStreamBuf.h> +#include <aws/core/utils/logging/LogMacros.h> #include <algorithm> #include <cassert> @@ -123,7 +124,14 @@ bool SimpleStreamBuf::GrowBuffer() if(currentSize > 0) { - std::memcpy(newBuffer, m_buffer, currentSize); + if(m_buffer) + { + std::memcpy(newBuffer, m_buffer, currentSize); + } + else + { + AWS_LOGSTREAM_FATAL(SIMPLE_STREAMBUF_ALLOCATION_TAG, "Unexpected nullptr m_buffer"); + } } if(m_buffer) diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Executor.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Executor.cpp index 4a3c4209c41..f9538f00336 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Executor.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Executor.cpp @@ -14,10 +14,15 @@ using namespace Aws::Utils::Threading; bool DefaultExecutor::SubmitToThread(std::function<void()>&& fx) { - auto main = [fx, this] { - fx(); - Detach(std::this_thread::get_id()); - }; + // Generalized lambda capture is C++14, using std::bind as a workaround to force moving fx (instead of copying) + std::function<void()> main = std::bind( + [this](std::function<void()>& storedFx) + { + storedFx(); + Detach(std::this_thread::get_id()); + }, + std::move(fx) + ); State expected; do @@ -25,7 +30,7 @@ bool DefaultExecutor::SubmitToThread(std::function<void()>&& fx) expected = State::Free; if(m_state.compare_exchange_strong(expected, State::Locked)) { - std::thread t(main); + std::thread t(std::move(main)); const auto id = t.get_id(); // copy the id before we std::move the thread m_threads.emplace(id, std::move(t)); m_state = State::Free; diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/xml/XmlSerializer.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/xml/XmlSerializer.cpp index c06befaf9b0..2d91f700005 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/xml/XmlSerializer.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/xml/XmlSerializer.cpp @@ -23,6 +23,8 @@ Aws::String Aws::Utils::Xml::DecodeEscapedXmlText(const Aws::String& textToDecod StringUtils::Replace(decodedString, "<", "<"); StringUtils::Replace(decodedString, ">", ">"); StringUtils::Replace(decodedString, "&", "&"); + StringUtils::Replace(decodedString, "
", "\n"); + StringUtils::Replace(decodedString, "
", "\r"); return decodedString; } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/ya.make b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/ya.make index bdbeda12d74..773a14e3ea6 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/ya.make +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/ya.make @@ -13,8 +13,17 @@ LICENSE_TEXTS(.yandex_meta/licenses.list.txt) PEERDIR( contrib/libs/curl contrib/libs/openssl + contrib/libs/zlib + contrib/restricted/aws/aws-c-auth + contrib/restricted/aws/aws-c-cal contrib/restricted/aws/aws-c-common contrib/restricted/aws/aws-c-event-stream + contrib/restricted/aws/aws-c-http + contrib/restricted/aws/aws-c-io + contrib/restricted/aws/aws-c-mqtt + contrib/restricted/aws/aws-c-sdkutils + contrib/restricted/aws/aws-checksums + contrib/restricted/aws/aws-crt-cpp ) ADDINCL( @@ -26,32 +35,44 @@ NO_COMPILER_WARNINGS() NO_UTIL() CFLAGS( + -DAWS_AUTH_USE_IMPORT_EXPORT -DAWS_CAL_USE_IMPORT_EXPORT -DAWS_CHECKSUMS_USE_IMPORT_EXPORT -DAWS_COMMON_USE_IMPORT_EXPORT + -DAWS_COMPRESSION_USE_IMPORT_EXPORT + -DAWS_CRT_CPP_USE_IMPORT_EXPORT -DAWS_EVENT_STREAM_USE_IMPORT_EXPORT + -DAWS_HTTP_USE_IMPORT_EXPORT -DAWS_IO_USE_IMPORT_EXPORT + -DAWS_MQTT_USE_IMPORT_EXPORT + -DAWS_MQTT_WITH_WEBSOCKETS + -DAWS_S3_USE_IMPORT_EXPORT + -DAWS_SDKUTILS_USE_IMPORT_EXPORT -DAWS_SDK_VERSION_MAJOR=1 - -DAWS_SDK_VERSION_MINOR=8 - -DAWS_SDK_VERSION_PATCH=186 + -DAWS_SDK_VERSION_MINOR=11 + -DAWS_SDK_VERSION_PATCH=37 + -DAWS_TEST_REGION=US_EAST_1 -DAWS_USE_EPOLL -DCURL_HAS_H2 -DCURL_HAS_TLS_PROXY + -DENABLED_REQUEST_COMPRESSION + -DENABLED_ZLIB_REQUEST_COMPRESSION -DENABLE_CURL_CLIENT -DENABLE_CURL_LOGGING -DENABLE_OPENSSL_ENCRYPTION -DHAS_PATHCONF -DHAS_UMASK - -DS2N_ADX - -DS2N_BIKE_R3_AVX2 - -DS2N_BIKE_R3_AVX512 - -DS2N_BIKE_R3_PCLMUL - -DS2N_BIKE_R3_VPCLMUL + -DS2N_CLONE_SUPPORTED -DS2N_CPUID_AVAILABLE -DS2N_FALL_THROUGH_SUPPORTED - -DS2N_HAVE_EXECINFO + -DS2N_FEATURES_AVAILABLE -DS2N_KYBER512R3_AVX2_BMI2 - -DS2N_SIKE_P434_R3_ASM + -DS2N_LIBCRYPTO_SUPPORTS_EVP_MD5_SHA1_HASH + -DS2N_LIBCRYPTO_SUPPORTS_EVP_MD_CTX_SET_PKEY_CTX + -DS2N_LIBCRYPTO_SUPPORTS_EVP_RC4 + -DS2N_MADVISE_SUPPORTED + -DS2N_PLATFORM_SUPPORTS_KTLS + -DS2N_STACKTRACE -DS2N___RESTRICT__SUPPORTED ) @@ -63,26 +84,52 @@ SRCS( source/Globals.cpp source/Region.cpp source/Version.cpp - source/auth/AWSAuthSigner.cpp - source/auth/AWSAuthSignerProvider.cpp source/auth/AWSCredentialsProvider.cpp source/auth/AWSCredentialsProviderChain.cpp source/auth/SSOCredentialsProvider.cpp source/auth/STSCredentialsProvider.cpp + source/auth/bearer-token-provider/DefaultBearerTokenProviderChain.cpp + source/auth/bearer-token-provider/SSOBearerTokenProvider.cpp + source/auth/signer-provider/BearerTokenAuthSignerProvider.cpp + source/auth/signer-provider/DefaultAuthSignerProvider.cpp + source/auth/signer/AWSAuthBearerSigner.cpp + source/auth/signer/AWSAuthEventStreamV4Signer.cpp + source/auth/signer/AWSAuthSignerCommon.cpp + source/auth/signer/AWSAuthSignerHelper.cpp + source/auth/signer/AWSAuthV4Signer.cpp + source/auth/signer/AWSNullSigner.cpp source/client/AWSClient.cpp source/client/AWSErrorMarshaller.cpp + source/client/AWSJsonClient.cpp + source/client/AWSUrlPresigner.cpp + source/client/AWSXmlClient.cpp + source/client/AdaptiveRetryStrategy.cpp source/client/AsyncCallerContext.cpp source/client/ClientConfiguration.cpp source/client/CoreErrors.cpp source/client/DefaultRetryStrategy.cpp + source/client/GenericClientConfiguration.cpp + source/client/RequestCompression.cpp source/client/RetryStrategy.cpp source/client/SpecifiedRetryableErrorsRetryStrategy.cpp - source/config/AWSProfileConfigLoader.cpp + source/config/AWSConfigFileProfileConfigLoader.cpp + source/config/AWSProfileConfigLoaderBase.cpp + source/config/ConfigAndCredentialsCacheManager.cpp + source/config/EC2InstanceProfileConfigLoader.cpp + source/config/defaults/ClientConfigurationDefaults.cpp + source/endpoint/AWSEndpoint.cpp + source/endpoint/AWSPartitions.cpp + source/endpoint/BuiltInParameters.cpp + source/endpoint/ClientContextParameters.cpp + source/endpoint/DefaultEndpointProvider.cpp + source/endpoint/EndpointProviderBase.cpp + source/endpoint/internal/AWSEndpointAttribute.cpp source/external/cjson/cJSON.cpp source/external/tinyxml2/tinyxml2.cpp source/http/HttpClient.cpp source/http/HttpClientFactory.cpp source/http/HttpRequest.cpp + source/http/HttpResponse.cpp source/http/HttpTypes.cpp source/http/Scheme.cpp source/http/URI.cpp @@ -99,6 +146,7 @@ SRCS( source/utils/DNS.cpp source/utils/DateTimeCommon.cpp source/utils/Directory.cpp + source/utils/Document.cpp source/utils/EnumParseOverflowContainer.cpp source/utils/FileSystemUtils.cpp source/utils/GetTheLights.cpp @@ -107,6 +155,7 @@ SRCS( source/utils/TempFile.cpp source/utils/UUID.cpp source/utils/base64/Base64.cpp + source/utils/crypto/CRC32.cpp source/utils/crypto/Cipher.cpp source/utils/crypto/ContentCryptoMaterial.cpp source/utils/crypto/ContentCryptoScheme.cpp @@ -130,6 +179,8 @@ SRCS( source/utils/event/EventStreamErrors.cpp source/utils/json/JsonSerializer.cpp source/utils/logging/AWSLogging.cpp + source/utils/logging/CRTLogSystem.cpp + source/utils/logging/CRTLogging.cpp source/utils/logging/ConsoleLogSystem.cpp source/utils/logging/DefaultLogSystem.cpp source/utils/logging/FormattedLogSystem.cpp |