From d51a28b7a195a952ae434b6035917b5e507b78fd Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Sun, 4 Aug 2024 09:57:26 -0700 Subject: [PATCH 001/126] AutoTag PR for v0.27.5 (#645) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 9f222923a..69bf493e5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.27.4 +0.27.5 From 1ec6c546cf11ae559ce8c147f4812446686586a8 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Wed, 7 Aug 2024 11:41:01 -0700 Subject: [PATCH 002/126] Proxy fix (#647) Co-authored-by: Ryan Smith --- source/iot/Mqtt5Client.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source/iot/Mqtt5Client.cpp b/source/iot/Mqtt5Client.cpp index 46aaa8e29..e9cc5226e 100644 --- a/source/iot/Mqtt5Client.cpp +++ b/source/iot/Mqtt5Client.cpp @@ -571,6 +571,8 @@ namespace Aws m_options->WithConnectOptions(m_connectOptions); } + bool proxyOptionsSet = false; + if (m_websocketConfig.has_value()) { auto websocketConfig = m_websocketConfig.value(); @@ -595,13 +597,20 @@ namespace Aws if (useWebsocketProxyOptions) { m_options->WithHttpProxyOptions(m_websocketConfig->ProxyOptions.value()); + proxyOptionsSet = true; } else if (m_proxyOptions.has_value()) { m_options->WithHttpProxyOptions(m_proxyOptions.value()); + proxyOptionsSet = true; } } + if (m_proxyOptions.has_value() && !proxyOptionsSet) + { + m_options->WithHttpProxyOptions(m_proxyOptions.value()); + } + return Crt::Mqtt5::Mqtt5Client::NewMqtt5Client(*m_options, m_allocator); } From 52dea442dd7a495c3c691268d99eb5f5765c7cee Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Thu, 15 Aug 2024 14:44:10 -0700 Subject: [PATCH 003/126] Update submodules (#649) --- crt/aws-c-auth | 2 +- crt/aws-c-cal | 2 +- crt/aws-c-common | 2 +- crt/aws-c-http | 2 +- crt/aws-c-io | 2 +- crt/aws-c-sdkutils | 2 +- crt/aws-lc | 2 +- crt/s2n | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crt/aws-c-auth b/crt/aws-c-auth index 53a31bacf..52bf59161 160000 --- a/crt/aws-c-auth +++ b/crt/aws-c-auth @@ -1 +1 @@ -Subproject commit 53a31bacf2918e848e00b052d2e25cba0be069d9 +Subproject commit 52bf591613d1a001c43ec99af7376f871759c5fe diff --git a/crt/aws-c-cal b/crt/aws-c-cal index 71810b1ad..77ca3aea8 160000 --- a/crt/aws-c-cal +++ b/crt/aws-c-cal @@ -1 +1 @@ -Subproject commit 71810b1ade7af4747104ae245b74240ae8e8cf77 +Subproject commit 77ca3aea879bc768082fe7ec715adcde8e98c332 diff --git a/crt/aws-c-common b/crt/aws-c-common index 6d974f92c..8419fe707 160000 --- a/crt/aws-c-common +++ b/crt/aws-c-common @@ -1 +1 @@ -Subproject commit 6d974f92c1d86391c1dcb1173239adf757c52b2d +Subproject commit 8419fe7077778b5ca40e8822f969665bbddc226c diff --git a/crt/aws-c-http b/crt/aws-c-http index 652e2febf..7db245223 160000 --- a/crt/aws-c-http +++ b/crt/aws-c-http @@ -1 +1 @@ -Subproject commit 652e2febf2242d6b3562267dc0dd982375ed698e +Subproject commit 7db2452238caece2d3a91e6cbed75324edccea7d diff --git a/crt/aws-c-io b/crt/aws-c-io index d04508d11..c345d7727 160000 --- a/crt/aws-c-io +++ b/crt/aws-c-io @@ -1 +1 @@ -Subproject commit d04508d113851f1bc15630d93490b2aa09676137 +Subproject commit c345d77274db83c0c2e30331814093e7c84c45e2 diff --git a/crt/aws-c-sdkutils b/crt/aws-c-sdkutils index 8c7af71f9..4658412a6 160000 --- a/crt/aws-c-sdkutils +++ b/crt/aws-c-sdkutils @@ -1 +1 @@ -Subproject commit 8c7af71f91ed5b9d2a043d51f120495f43723f80 +Subproject commit 4658412a61ad5749db92a8d1e0717cb5e76ada1c diff --git a/crt/aws-lc b/crt/aws-lc index 05d3bfd63..057477806 160000 --- a/crt/aws-lc +++ b/crt/aws-lc @@ -1 +1 @@ -Subproject commit 05d3bfd6303c65d7392dee1a47d6e161c36a04e5 +Subproject commit 05747780676652f41d0b9c570a495e4bb6608560 diff --git a/crt/s2n b/crt/s2n index 073c7b415..79c0f1b43 160000 --- a/crt/s2n +++ b/crt/s2n @@ -1 +1 @@ -Subproject commit 073c7b415a17d271a7b2c8c385d0e641fc94871f +Subproject commit 79c0f1b434742d9f1152c48d3781433649f6f8fe From 64aa255ea5b42ada86f75b5200dc6903dea8e493 Mon Sep 17 00:00:00 2001 From: Dmitriy Musatkin <63878209+DmitriyMusatkin@users.noreply.github.com> Date: Fri, 16 Aug 2024 11:04:32 -0700 Subject: [PATCH 004/126] Add support for string array ep context params (#646) --- include/aws/crt/endpoints/RuleEngine.h | 7 +++++++ source/endpoints/RuleEngine.cpp | 6 ++++++ tests/RuleEngineTest.cpp | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/include/aws/crt/endpoints/RuleEngine.h b/include/aws/crt/endpoints/RuleEngine.h index 1472492c0..558b43b3e 100644 --- a/include/aws/crt/endpoints/RuleEngine.h +++ b/include/aws/crt/endpoints/RuleEngine.h @@ -53,6 +53,13 @@ namespace Aws */ bool AddBoolean(const ByteCursor &name, bool value); + /* + * Add string array parameter. + * True if added successfully and false if failed. + * Aws::Crt::LastError() can be used to retrieve failure error code. + */ + bool AddStringArray(const ByteCursor &name, const Vector &value); + /// @private aws_endpoints_request_context *GetNativeHandle() const noexcept { return m_requestContext; } diff --git a/source/endpoints/RuleEngine.cpp b/source/endpoints/RuleEngine.cpp index 681eb5267..906ccb787 100644 --- a/source/endpoints/RuleEngine.cpp +++ b/source/endpoints/RuleEngine.cpp @@ -37,6 +37,12 @@ namespace Aws aws_endpoints_request_context_add_boolean(m_allocator, m_requestContext, name, value); } + bool RequestContext::AddStringArray(const ByteCursor &name, const Vector &value) + { + return AWS_OP_SUCCESS != aws_endpoints_request_context_add_string_array( + m_allocator, m_requestContext, name, value.data(), value.size()); + } + ResolutionOutcome::ResolutionOutcome(aws_endpoints_resolved_endpoint *impl) : m_resolvedEndpoint(impl) {} ResolutionOutcome::ResolutionOutcome(ResolutionOutcome &&toMove) noexcept diff --git a/tests/RuleEngineTest.cpp b/tests/RuleEngineTest.cpp index 42cbf094a..7388029e4 100644 --- a/tests/RuleEngineTest.cpp +++ b/tests/RuleEngineTest.cpp @@ -173,3 +173,21 @@ static int s_TestRuleEngine(struct aws_allocator *allocator, void *ctx) } AWS_TEST_CASE(RuleEngine, s_TestRuleEngine) + +static int s_TestRuleEngineContextParams(struct aws_allocator *allocator, void *ctx) +{ + (void)ctx; + + Aws::Crt::ApiHandle apiHandle(allocator); + + Aws::Crt::Endpoints::RequestContext context(allocator); + context.AddString(ByteCursorFromCString("Region"), ByteCursorFromCString("us-west-2")); + context.AddBoolean(ByteCursorFromCString("AValidBoolParam"), false); + context.AddStringArray(ByteCursorFromCString("StringArray1"), {}); + context.AddStringArray( + ByteCursorFromCString("StringArray2"), {ByteCursorFromCString("a"), ByteCursorFromCString("b")}); + + return AWS_OP_SUCCESS; +} + +AWS_TEST_CASE(RuleEngineContextParams, s_TestRuleEngineContextParams) \ No newline at end of file From b8df6b1897e0c1b6467408cfafd407448836812e Mon Sep 17 00:00:00 2001 From: Michael Graeb Date: Fri, 16 Aug 2024 11:53:25 -0700 Subject: [PATCH 005/126] Fix websocket shutdown behavior (submodule updates) (#650) Update submodules, bringing in this fix: https://github.com/awslabs/aws-c-http/pull/483 ``` aws-c-common v0.9.26 -> v0.9.27 aws-c-event-stream v0.4.2 -> v0.4.3 aws-c-http v0.8.7 -> v0.8.8 ``` --- crt/aws-c-common | 2 +- crt/aws-c-event-stream | 2 +- crt/aws-c-http | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crt/aws-c-common b/crt/aws-c-common index 8419fe707..672cc0032 160000 --- a/crt/aws-c-common +++ b/crt/aws-c-common @@ -1 +1 @@ -Subproject commit 8419fe7077778b5ca40e8822f969665bbddc226c +Subproject commit 672cc0032eb28d69fbdd22c9463253c89d7a6f30 diff --git a/crt/aws-c-event-stream b/crt/aws-c-event-stream index 1a70c50f7..1b3825fc9 160000 --- a/crt/aws-c-event-stream +++ b/crt/aws-c-event-stream @@ -1 +1 @@ -Subproject commit 1a70c50f78a6e706f1f91a4ed138478271b6d9d3 +Subproject commit 1b3825fc9cae2e9c7ed7479ee5d354d52ebdf7a0 diff --git a/crt/aws-c-http b/crt/aws-c-http index 7db245223..4e74ab1e3 160000 --- a/crt/aws-c-http +++ b/crt/aws-c-http @@ -1 +1 @@ -Subproject commit 7db2452238caece2d3a91e6cbed75324edccea7d +Subproject commit 4e74ab1e3702763e0b87bd1752f5a37c2f0400ac From dca3cd9a15b0f5521c0a0b0552c1a925061303b8 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Wed, 21 Aug 2024 10:11:01 -0700 Subject: [PATCH 006/126] AutoTag PR for v0.27.6 (#651) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 69bf493e5..c7c49b4b4 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.27.5 +0.27.6 From 116bb95de9ddaf207c8aef5d9efc650cc00d3291 Mon Sep 17 00:00:00 2001 From: Vera Xia Date: Mon, 26 Aug 2024 09:50:37 -0700 Subject: [PATCH 007/126] Expose socket options from Mqtt5ClientBuilder (#652) --- include/aws/iot/Mqtt5Client.h | 9 +++++++++ source/iot/Mqtt5Client.cpp | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/include/aws/iot/Mqtt5Client.h b/include/aws/iot/Mqtt5Client.h index fbe5b8524..e1711bcee 100644 --- a/include/aws/iot/Mqtt5Client.h +++ b/include/aws/iot/Mqtt5Client.h @@ -298,6 +298,15 @@ namespace Aws */ Mqtt5ClientBuilder &WithCertificateAuthority(const Crt::ByteCursor &cert) noexcept; + /** + * Overrides the socket properties of the underlying MQTT connections made by the client. Leave undefined + * to use defaults (no TCP keep alive, 10 second socket timeout). + * + * @param socketOptions - The socket properties of the underlying MQTT connections made by the client + * @return - The Mqtt5ClientBuilder + */ + Mqtt5ClientBuilder &WithSocketOptions(Crt::Io::SocketOptions socketOptions) noexcept; + /** * Sets http proxy options. * diff --git a/source/iot/Mqtt5Client.cpp b/source/iot/Mqtt5Client.cpp index e9cc5226e..fa4b27e72 100644 --- a/source/iot/Mqtt5Client.cpp +++ b/source/iot/Mqtt5Client.cpp @@ -344,6 +344,12 @@ namespace Aws return *this; } + Mqtt5ClientBuilder &Mqtt5ClientBuilder::WithSocketOptions(Crt::Io::SocketOptions socketOptions) noexcept + { + m_options->WithSocketOptions(std::move(socketOptions)); + return *this; + } + Mqtt5ClientBuilder &Mqtt5ClientBuilder::WithHttpProxyOptions( const Crt::Http::HttpClientConnectionProxyOptions &proxyOptions) noexcept { From 8a9da3b018daf7bfaddf5a362bc010aa297fa630 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Mon, 26 Aug 2024 10:25:18 -0700 Subject: [PATCH 008/126] AutoTag PR for v0.28.0 (#654) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index c7c49b4b4..697f087f3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.27.6 +0.28.0 From 00b6e9acdf03d6d0b3b69d7768514871b23a37ca Mon Sep 17 00:00:00 2001 From: sbiscigl Date: Fri, 23 Aug 2024 15:26:28 -0400 Subject: [PATCH 009/126] Fix typo in variant --- include/aws/crt/Variant.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/aws/crt/Variant.h b/include/aws/crt/Variant.h index f973316e6..e4cec4af5 100644 --- a/include/aws/crt/Variant.h +++ b/include/aws/crt/Variant.h @@ -53,7 +53,7 @@ namespace Aws { using VariantIndex = short; - template constexpr VariantIndex GetIndexOf(VariantIndex curIndex = -1) + template constexpr VariantIndex GetIndexOf(VariantIndex curIndex = 0) { return std::is_same::value ? curIndex : -1; } From 1cf4763184ef783dfc79b8b0a26f8cbaf578194f Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Tue, 27 Aug 2024 11:16:48 -0700 Subject: [PATCH 010/126] Fix Openssl Compile and Runtime Version Mismatch (#656) --- .github/workflows/ci.yml | 2 +- crt/aws-c-auth | 2 +- crt/aws-c-cal | 2 +- crt/aws-c-compression | 2 +- crt/aws-lc | 2 +- crt/s2n | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f7631a21a..3f0fde7ad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: - 'docs' env: - BUILDER_VERSION: v0.9.56 + BUILDER_VERSION: v0.9.63 BUILDER_SOURCE: releases BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net PACKAGE_NAME: aws-crt-cpp diff --git a/crt/aws-c-auth b/crt/aws-c-auth index 52bf59161..877c029fc 160000 --- a/crt/aws-c-auth +++ b/crt/aws-c-auth @@ -1 +1 @@ -Subproject commit 52bf591613d1a001c43ec99af7376f871759c5fe +Subproject commit 877c029fc4e93d205f9c6855188c3c51f6b497b4 diff --git a/crt/aws-c-cal b/crt/aws-c-cal index 77ca3aea8..2cb1d2eac 160000 --- a/crt/aws-c-cal +++ b/crt/aws-c-cal @@ -1 +1 @@ -Subproject commit 77ca3aea879bc768082fe7ec715adcde8e98c332 +Subproject commit 2cb1d2eac925e2dbc45025eb89af82bd790c23a0 diff --git a/crt/aws-c-compression b/crt/aws-c-compression index ea1d421a4..f36d01672 160000 --- a/crt/aws-c-compression +++ b/crt/aws-c-compression @@ -1 +1 @@ -Subproject commit ea1d421a421ad83a540309a94c38d50b6a5d836b +Subproject commit f36d01672d61e49d96a777870d456f66fa391cd4 diff --git a/crt/aws-lc b/crt/aws-lc index 057477806..2f1879759 160000 --- a/crt/aws-lc +++ b/crt/aws-lc @@ -1 +1 @@ -Subproject commit 05747780676652f41d0b9c570a495e4bb6608560 +Subproject commit 2f1879759b2e0fc70592665bdf10087b64f44b7d diff --git a/crt/s2n b/crt/s2n index 79c0f1b43..87f4a0585 160000 --- a/crt/s2n +++ b/crt/s2n @@ -1 +1 @@ -Subproject commit 79c0f1b434742d9f1152c48d3781433649f6f8fe +Subproject commit 87f4a0585dc3056433f193b9305f587cff239be3 From 433e820caa44a5f87219ae4c2d0dba5e9a456923 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Tue, 27 Aug 2024 11:17:22 -0700 Subject: [PATCH 011/126] AutoTag PR for v0.28.1 (#657) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 697f087f3..48f7a71df 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.28.0 +0.28.1 From a2cb2c5bd9cd51205ad52e4ab16d321b03caa068 Mon Sep 17 00:00:00 2001 From: sbiscigl Date: Thu, 29 Aug 2024 13:45:24 -0400 Subject: [PATCH 012/126] fix MSVC most vexing parse --- include/aws/crt/StringView.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/aws/crt/StringView.h b/include/aws/crt/StringView.h index 27c162ffe..3b6dc2f0f 100644 --- a/include/aws/crt/StringView.h +++ b/include/aws/crt/StringView.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) @@ -859,6 +860,6 @@ namespace std const Aws::Crt::basic_string_view &val) const noexcept { auto str = std::basic_string(val.data(), val.size()); - return std::hash>()(str); + return std::hash>{}(str); } } // namespace std From a4ef09fae941f4fe28eb03801bc8bbfe47928d74 Mon Sep 17 00:00:00 2001 From: SergeyRyabinin Date: Wed, 28 Aug 2024 18:34:18 +0000 Subject: [PATCH 013/126] Add wrappers around readsome and peek methods in std istream --- include/aws/crt/io/Stream.h | 24 ++++++++++++++++++++++++ source/io/Stream.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/include/aws/crt/io/Stream.h b/include/aws/crt/io/Stream.h index 91c8c36f2..b41f36413 100644 --- a/include/aws/crt/io/Stream.h +++ b/include/aws/crt/io/Stream.h @@ -114,6 +114,19 @@ namespace Aws */ virtual bool ReadImpl(ByteBuf &buffer) noexcept = 0; + /*** + * Read up-to buffer::capacity - buffer::len immediately available bytes into buffer::buffer + * Increment buffer::len by the amount you read in. + * + * @return true if nothing went wrong. + * Return true even if you read 0 bytes because the end-of-file has been reached. + * Return true even if you read 0 bytes because data is not currently available. + * + * Return false if an actual failure condition occurs, + * you SHOULD also raise an error via aws_raise_error(). + */ + virtual bool ReadSomeImpl(ByteBuf &buffer) noexcept = 0; + /** * @return the current status of the stream. */ @@ -136,6 +149,15 @@ namespace Aws */ virtual bool SeekImpl(int64_t offset, StreamSeekBasis seekBasis) noexcept = 0; + /** + * Peeks the stream + * + * Essentially calls peek on the underlying istream + * + * @return return value of the underlying istream::peek + */ + virtual int64_t PeekImpl() const noexcept = 0; + private: static int s_Seek(aws_input_stream *stream, int64_t offset, enum aws_stream_seek_basis basis); static int s_Read(aws_input_stream *stream, aws_byte_buf *dest); @@ -161,9 +183,11 @@ namespace Aws protected: bool ReadImpl(ByteBuf &buffer) noexcept override; + bool ReadSomeImpl(ByteBuf &buffer) noexcept override; StreamStatus GetStatusImpl() const noexcept override; int64_t GetLengthImpl() const noexcept override; bool SeekImpl(OffsetType offsetType, StreamSeekBasis seekBasis) noexcept override; + int64_t PeekImpl() const noexcept override; private: std::shared_ptr m_stream; diff --git a/source/io/Stream.cpp b/source/io/Stream.cpp index 975d1c516..b16267f10 100644 --- a/source/io/Stream.cpp +++ b/source/io/Stream.cpp @@ -5,6 +5,7 @@ #include #include +#include #include @@ -150,6 +151,26 @@ namespace Aws return status.is_valid && !status.is_end_of_stream; } + bool StdIOStreamInputStream::ReadSomeImpl(ByteBuf &buffer) noexcept + { + // I have no idea why "readsome() doesn't work at all" for the original dev. It works well for me + // Jokes aside, read will always block and try to read till eof + // readsome will return available bytes without waiting for eof and without closing the stream. + auto actuallyRead = m_stream->readsome( + reinterpret_cast(buffer.buffer + buffer.len), buffer.capacity - buffer.len); + + buffer.len += static_cast(actuallyRead); + + if (actuallyRead > 0 || (actuallyRead == 0 && m_stream->eof())) + { + return true; + } + + auto status = GetStatusImpl(); + + return status.is_valid && !status.is_end_of_stream; + } + StreamStatus StdIOStreamInputStream::GetStatusImpl() const noexcept { StreamStatus status; @@ -206,6 +227,11 @@ namespace Aws return true; } + + int64_t StdIOStreamInputStream::PeekImpl() const noexcept + { + return m_stream->peek(); + } } // namespace Io } // namespace Crt } // namespace Aws From e14c814728dc438a0b7dc694bd83418addc5a6a1 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Fri, 30 Aug 2024 09:25:19 -0700 Subject: [PATCH 014/126] AutoTag PR for v0.28.2 (#660) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 48f7a71df..a37255a85 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.28.1 +0.28.2 From 260575a9f3c961d9a3c73304c3df710ebe3c8403 Mon Sep 17 00:00:00 2001 From: Dmitriy Musatkin <63878209+DmitriyMusatkin@users.noreply.github.com> Date: Fri, 13 Sep 2024 12:50:40 -0700 Subject: [PATCH 015/126] Bind out CRC64 (#662) --- CMakeLists.txt | 13 ++++++++++ crt/aws-checksums | 2 +- include/aws/crt/checksum/CRC.h | 39 ++++++++++++++++++++++++++++ include/aws/crt/crypto/Hash.h | 2 +- source/checksum/CRC.cpp | 32 +++++++++++++++++++++++ tests/CRCTest.cpp | 46 ++++++++++++++++++++++++++++++++++ 6 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 include/aws/crt/checksum/CRC.h create mode 100644 source/checksum/CRC.cpp create mode 100644 tests/CRCTest.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fb54a14e0..1cab5f4f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -147,6 +147,10 @@ file(GLOB AWS_CRT_AUTH_HEADERS "include/aws/crt/auth/*.h" ) +file(GLOB AWS_CRT_CHECKSUM_HEADERS + "include/aws/crt/checksum/*.h" +) + file(GLOB AWS_CRT_CRYPTO_HEADERS "include/aws/crt/crypto/*.h" ) @@ -178,6 +182,7 @@ file(GLOB AWS_CRT_CBOR_HEADERS file(GLOB AWS_CRT_PUBLIC_HEADERS ${AWS_CRT_HEADERS} ${AWS_CRT_AUTH_HEADERS} + ${AWS_CRT_CHECKSUM_HEADERS} ${AWS_CRT_CRYPTO_HEADERS} ${AWS_CRT_IO_HEADERS} ${AWS_CRT_IOT_HEADERS} @@ -204,6 +209,10 @@ file(GLOB AWS_CRT_AUTH_SRC "source/auth/*.cpp" ) +file(GLOB AWS_CRT_CHECKSUM_SRC + "source/checksum/*.cpp" +) + file(GLOB AWS_CRT_CRYPTO_SRC "source/crypto/*.cpp" ) @@ -235,6 +244,7 @@ file(GLOB AWS_CRT_CBOR_SRC file(GLOB AWS_CRT_CPP_SRC ${AWS_CRT_SRC} ${AWS_CRT_AUTH_SRC} + ${AWS_CRT_CHECKSUM_SRC} ${AWS_CRT_CRYPTO_SRC} ${AWS_CRT_IO_SRC} ${AWS_CRT_IOT_SRC} @@ -248,6 +258,7 @@ if(WIN32) if(MSVC) source_group("Header Files\\aws\\crt" FILES ${AWS_CRT_HEADERS}) source_group("Header Files\\aws\\crt\\auth" FILES ${AWS_CRT_AUTH_HEADERS}) + source_group("Header Files\\aws\\crt\\checksum" FILES ${AWS_CRT_CHECKSUM_HEADERS}) source_group("Header Files\\aws\\crt\\crypto" FILES ${AWS_CRT_CRYPTO_HEADERS}) source_group("Header Files\\aws\\crt\\io" FILES ${AWS_CRT_IO_HEADERS}) source_group("Header Files\\aws\\iot" FILES ${AWS_CRT_IOT_HEADERS}) @@ -258,6 +269,7 @@ if(WIN32) source_group("Source Files" FILES ${AWS_CRT_SRC}) source_group("Source Files\\auth" FILES ${AWS_CRT_AUTH_SRC}) + source_group("Source Files\\checksum" FILES ${AWS_CRT_CHECKSUM_SRC}) source_group("Source Files\\crypto" FILES ${AWS_CRT_CRYPTO_SRC}) source_group("Source Files\\io" FILES ${AWS_CRT_IO_SRC}) source_group("Source Files\\iot" FILES ${AWS_CRT_IOT_SRC}) @@ -328,6 +340,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC ${DEP_AWS_LIBS}) install(FILES ${AWS_CRT_HEADERS} DESTINATION "include/aws/crt" COMPONENT Development) install(FILES ${AWS_CRT_AUTH_HEADERS} DESTINATION "include/aws/crt/auth" COMPONENT Development) +install(FILES ${AWS_CRT_CHECKSUM_HEADERS} DESTINATION "include/aws/crt/crypto" COMPONENT Development) install(FILES ${AWS_CRT_CRYPTO_HEADERS} DESTINATION "include/aws/crt/crypto" COMPONENT Development) install(FILES ${AWS_CRT_IO_HEADERS} DESTINATION "include/aws/crt/io" COMPONENT Development) install(FILES ${AWS_CRT_IOT_HEADERS} DESTINATION "include/aws/iot" COMPONENT Development) diff --git a/crt/aws-checksums b/crt/aws-checksums index aac442a2d..ce04ab00b 160000 --- a/crt/aws-checksums +++ b/crt/aws-checksums @@ -1 +1 @@ -Subproject commit aac442a2dbbb5e72d0a3eca8313cf65e7e1cac2f +Subproject commit ce04ab00b3ecc41912f478bfedca39f8e1919d6b diff --git a/include/aws/crt/checksum/CRC.h b/include/aws/crt/checksum/CRC.h new file mode 100644 index 000000000..023d1d21a --- /dev/null +++ b/include/aws/crt/checksum/CRC.h @@ -0,0 +1,39 @@ +#pragma once +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include +#include + +namespace Aws +{ + namespace Crt + { + namespace Checksum + { + /** + * The entry point function to perform a CRC32 (Ethernet, gzip) computation. + * Selects a suitable implementation based on hardware capabilities. + * Pass previousCRC32 if updating a running checksum. + */ + uint32_t AWS_CRT_CPP_API ComputeCRC32(ByteCursor input, uint32_t previousCRC32 = 0) noexcept; + + /** + * The entry point function to perform a Castagnoli CRC32c (iSCSI) computation. + * Selects a suitable implementation based on hardware capabilities. + * Pass previousCRC32C if updating a running checksum. + */ + uint32_t AWS_CRT_CPP_API ComputeCRC32C(ByteCursor input, uint32_t previousCRC32C = 0) noexcept; + + /** + * The entry point function to perform a CRC64-NVME (a.k.a. CRC64-Rocksoft) computation. + * Selects a suitable implementation based on hardware capabilities. + * Pass previousCRC64NVME if updating a running checksum. + * There are many variants of CRC64 algorithms. This CRC64 variant is bit-reflected (based on + * the non bit-reflected polynomial 0xad93d23594c93659) and inverts the CRC input and output bits. + */ + uint64_t AWS_CRT_CPP_API ComputeCRC64NVME(ByteCursor input, uint64_t previousCRC64NVME = 0) noexcept; + } // namespace Checksum + } // namespace Crt +} // namespace Aws diff --git a/include/aws/crt/crypto/Hash.h b/include/aws/crt/crypto/Hash.h index 98e3e3c93..af8a7c7d2 100644 --- a/include/aws/crt/crypto/Hash.h +++ b/include/aws/crt/crypto/Hash.h @@ -189,7 +189,7 @@ namespace Aws /** * Complete the hash computation and write the final digest to output. - * This cannote be called more than once. + * This cannot be called more than once. * If truncate_to is something other than 0, the output must be truncated to that number of bytes. * Raise an AWS error and return false to indicate failure. */ diff --git a/source/checksum/CRC.cpp b/source/checksum/CRC.cpp new file mode 100644 index 000000000..65ed70e28 --- /dev/null +++ b/source/checksum/CRC.cpp @@ -0,0 +1,32 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include + +#include + +namespace Aws +{ + namespace Crt + { + namespace Checksum + { + uint32_t ComputeCRC32(ByteCursor input, uint32_t previousCRC32) noexcept + { + return aws_checksums_crc32_ex(input.ptr, input.len, previousCRC32); + } + + uint32_t ComputeCRC32C(ByteCursor input, uint32_t previousCRC32C) noexcept + { + return aws_checksums_crc32c_ex(input.ptr, input.len, previousCRC32C); + } + + uint64_t ComputeCRC64NVME(ByteCursor input, uint64_t previousCRC64NVME) noexcept + { + return aws_checksums_crc64nvme_ex(input.ptr, input.len, previousCRC64NVME); + } + + } // namespace Checksum + } // namespace Crt +} // namespace Aws diff --git a/tests/CRCTest.cpp b/tests/CRCTest.cpp new file mode 100644 index 000000000..464fe4862 --- /dev/null +++ b/tests/CRCTest.cpp @@ -0,0 +1,46 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include +#include +#include + +static int s_TestCRC32Piping(struct aws_allocator *allocator, void *) +{ + Aws::Crt::ApiHandle apiHandle(allocator); + uint8_t data[32] = {0}; + + Aws::Crt::ByteCursor dataCur = aws_byte_cursor_from_array(data, sizeof(data)); + + ASSERT_UINT_EQUALS(0x190A55AD, Aws::Crt::Checksum::ComputeCRC32(dataCur)); + + return AWS_OP_SUCCESS; +} +AWS_TEST_CASE(CRC32Piping, s_TestCRC32Piping) + +static int s_TestCRC32CPiping(struct aws_allocator *allocator, void *) +{ + Aws::Crt::ApiHandle apiHandle(allocator); + uint8_t data[32] = {0}; + + Aws::Crt::ByteCursor dataCur = aws_byte_cursor_from_array(data, sizeof(data)); + + ASSERT_UINT_EQUALS(0x8A9136AA, Aws::Crt::Checksum::ComputeCRC32C(dataCur)); + + return AWS_OP_SUCCESS; +} +AWS_TEST_CASE(CRC32CPiping, s_TestCRC32CPiping) + +static int s_TestCRC64NVMEPiping(struct aws_allocator *allocator, void *) +{ + Aws::Crt::ApiHandle apiHandle(allocator); + uint8_t data[32] = {0}; + + Aws::Crt::ByteCursor dataCur = aws_byte_cursor_from_array(data, sizeof(data)); + + ASSERT_UINT_EQUALS(0xCF3473434D4ECF3B, Aws::Crt::Checksum::ComputeCRC64NVME(dataCur)); + + return AWS_OP_SUCCESS; +} +AWS_TEST_CASE(CRC64NVMEPiping, s_TestCRC64NVMEPiping) From 83aacf7ae3a79c1cd1d2e1fe901a8ac9c427a199 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Fri, 13 Sep 2024 14:54:18 -0700 Subject: [PATCH 016/126] AutoTag PR for v0.28.3 (#663) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index a37255a85..b79f04f44 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.28.2 +0.28.3 From 188cff7c288e34ed076ea7cd637615a0b74bafc8 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Tue, 8 Oct 2024 11:59:31 -0700 Subject: [PATCH 017/126] Prebuild aws-lc (#648) --- CMakeLists.txt | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1cab5f4f4..048f1eec9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,35 +84,36 @@ if(BUILD_DEPS) if(UNIX AND NOT APPLE AND NOT BYO_CRYPTO) if(NOT USE_OPENSSL) - set(DISABLE_PERL ON CACHE BOOL "Disable Perl for AWS-LC.") - set(DISABLE_GO ON CACHE BOOL "Disable Go for AWS-LC.") - set(BUILD_LIBSSL OFF CACHE BOOL "Build libssl for AWS-LC.") + include(AwsPrebuildDependency) - # temporarily disable certain warnings as errors for the aws-lc build - set(OLD_CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + set(AWSLC_CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + # temporarily disable certain warnings as errors for the aws-lc build if(NOT MSVC) check_c_compiler_flag(-Wno-stringop-overflow HAS_WNO_STRINGOP_OVERFLOW) if(HAS_WNO_STRINGOP_OVERFLOW) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-stringop-overflow") + set(AWSLC_CMAKE_C_FLAGS "${AWSLC_CMAKE_C_FLAGS} -Wno-stringop-overflow") endif() check_c_compiler_flag(-Wno-array-parameter HAS_WNO_ARRAY_PARAMETER) if(HAS_WNO_ARRAY_PARAMETER) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-array-parameter") + set(AWSLC_CMAKE_C_FLAGS "${AWSLC_CMAKE_C_FLAGS} -Wno-array-parameter") endif() endif() - add_subdirectory(crt/aws-lc) - - # restore previous build flags - set(CMAKE_C_FLAGS "${OLD_CMAKE_C_FLAGS}") - - set(SEARCH_LIBCRYPTO OFF CACHE BOOL "Let S2N use libcrypto from AWS-LC.") - else() - set(SEARCH_LIBCRYPTO ON CACHE BOOL "Let S2N search libcrypto in the system.") + # s2n-tls uses libcrypto during its configuration, so we need to prebuild aws-lc. + prebuild_dependency( + DEPENDENCY_NAME AWSLC + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/crt/aws-lc + CMAKE_ARGUMENTS + -DDISABLE_GO=ON + -DDISABLE_PERL=ON + -DBUILD_LIBSSL=OFF + -DBUILD_TESTING=OFF + -DCMAKE_C_FLAGS=${AWSLC_CMAKE_C_FLAGS} + ) endif() set(UNSAFE_TREAT_WARNINGS_AS_ERRORS OFF CACHE BOOL "Disable warnings-as-errors when building S2N") From 29d329011e5b967d3e2ee5feb4155c287cb8d72d Mon Sep 17 00:00:00 2001 From: Dengke Tang Date: Fri, 18 Oct 2024 14:55:06 -0700 Subject: [PATCH 018/126] prebuild s2n (#665) --- .github/workflows/ci.yml | 1 + CMakeLists.txt | 14 ++++++++++---- crt/aws-c-auth | 2 +- crt/aws-c-common | 2 +- crt/aws-c-http | 2 +- crt/aws-c-io | 2 +- crt/aws-c-mqtt | 2 +- crt/aws-c-s3 | 2 +- crt/aws-lc | 2 +- crt/s2n | 2 +- 10 files changed, 19 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3f0fde7ad..4fc023abd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,6 +40,7 @@ jobs: linux-compat: runs-on: ubuntu-22.04 # latest strategy: + fail-fast: false matrix: image: - manylinux2014-x64 diff --git a/CMakeLists.txt b/CMakeLists.txt index 048f1eec9..2efcee399 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,8 +83,8 @@ if(BUILD_DEPS) add_subdirectory(crt/aws-c-common) if(UNIX AND NOT APPLE AND NOT BYO_CRYPTO) + include(AwsPrebuildDependency) if(NOT USE_OPENSSL) - include(AwsPrebuildDependency) set(AWSLC_CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") @@ -104,7 +104,7 @@ if(BUILD_DEPS) endif() # s2n-tls uses libcrypto during its configuration, so we need to prebuild aws-lc. - prebuild_dependency( + aws_prebuild_dependency( DEPENDENCY_NAME AWSLC SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/crt/aws-lc CMAKE_ARGUMENTS @@ -116,8 +116,14 @@ if(BUILD_DEPS) ) endif() - set(UNSAFE_TREAT_WARNINGS_AS_ERRORS OFF CACHE BOOL "Disable warnings-as-errors when building S2N") - add_subdirectory(crt/s2n) + # prebuild s2n-tls. + aws_prebuild_dependency( + DEPENDENCY_NAME S2N + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/crt/s2n + CMAKE_ARGUMENTS + -DUNSAFE_TREAT_WARNINGS_AS_ERRORS=OFF + -DBUILD_TESTING=OFF + ) endif() add_subdirectory(crt/aws-c-sdkutils) diff --git a/crt/aws-c-auth b/crt/aws-c-auth index 877c029fc..48d647bf4 160000 --- a/crt/aws-c-auth +++ b/crt/aws-c-auth @@ -1 +1 @@ -Subproject commit 877c029fc4e93d205f9c6855188c3c51f6b497b4 +Subproject commit 48d647bf43f8872e4dc5ec6343b0c5974195fbdd diff --git a/crt/aws-c-common b/crt/aws-c-common index 672cc0032..f8c5d8e51 160000 --- a/crt/aws-c-common +++ b/crt/aws-c-common @@ -1 +1 @@ -Subproject commit 672cc0032eb28d69fbdd22c9463253c89d7a6f30 +Subproject commit f8c5d8e5134fa97955351a44f16b84f96de24045 diff --git a/crt/aws-c-http b/crt/aws-c-http index 4e74ab1e3..6068653e1 160000 --- a/crt/aws-c-http +++ b/crt/aws-c-http @@ -1 +1 @@ -Subproject commit 4e74ab1e3702763e0b87bd1752f5a37c2f0400ac +Subproject commit 6068653e1d582bd8e7d1c9f81f86beaf10444e3d diff --git a/crt/aws-c-io b/crt/aws-c-io index c345d7727..dc41ddc49 160000 --- a/crt/aws-c-io +++ b/crt/aws-c-io @@ -1 +1 @@ -Subproject commit c345d77274db83c0c2e30331814093e7c84c45e2 +Subproject commit dc41ddc498c10ebbf69aba7775afa36c8c1910bd diff --git a/crt/aws-c-mqtt b/crt/aws-c-mqtt index ed7bbd68c..77d6f00e8 160000 --- a/crt/aws-c-mqtt +++ b/crt/aws-c-mqtt @@ -1 +1 @@ -Subproject commit ed7bbd68c03d7022c915a2924740ab7992ad2311 +Subproject commit 77d6f00e89b10e3263d8a17576ec8e91c45b4606 diff --git a/crt/aws-c-s3 b/crt/aws-c-s3 index 0ab4d58ef..aede1d8c2 160000 --- a/crt/aws-c-s3 +++ b/crt/aws-c-s3 @@ -1 +1 @@ -Subproject commit 0ab4d58ef0bd97970d43828cb6b57a3de5747343 +Subproject commit aede1d8c24f9f580d5a96c089878e9b258b88d04 diff --git a/crt/aws-lc b/crt/aws-lc index 2f1879759..8b2ebfcf3 160000 --- a/crt/aws-lc +++ b/crt/aws-lc @@ -1 +1 @@ -Subproject commit 2f1879759b2e0fc70592665bdf10087b64f44b7d +Subproject commit 8b2ebfcf3fc8b0656f1f4161166484a70238aeaa diff --git a/crt/s2n b/crt/s2n index 87f4a0585..ffe0bf42d 160000 --- a/crt/s2n +++ b/crt/s2n @@ -1 +1 @@ -Subproject commit 87f4a0585dc3056433f193b9305f587cff239be3 +Subproject commit ffe0bf42da8f139eff8fd2237f47fbde40b478fb From e08c87abfc3f6a26952b54c733580ad9d0b599c0 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Fri, 18 Oct 2024 14:56:00 -0700 Subject: [PATCH 019/126] AutoTag PR for v0.28.4 (#667) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index b79f04f44..097bc9362 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.28.3 +0.28.4 From 8ebe6e5cf2bd627692fb93befd2d982c150493af Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Mon, 21 Oct 2024 08:38:13 -0700 Subject: [PATCH 020/126] latest submodules (#668) --- crt/aws-c-common | 2 +- crt/aws-c-io | 2 +- crt/aws-c-s3 | 2 +- crt/aws-lc | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crt/aws-c-common b/crt/aws-c-common index f8c5d8e51..f58e807d8 160000 --- a/crt/aws-c-common +++ b/crt/aws-c-common @@ -1 +1 @@ -Subproject commit f8c5d8e5134fa97955351a44f16b84f96de24045 +Subproject commit f58e807d8fd643bd9a96eef182c1db37d01b88e7 diff --git a/crt/aws-c-io b/crt/aws-c-io index dc41ddc49..e36374047 160000 --- a/crt/aws-c-io +++ b/crt/aws-c-io @@ -1 +1 @@ -Subproject commit dc41ddc498c10ebbf69aba7775afa36c8c1910bd +Subproject commit e36374047beadc72a0eb6df14ce3cbc822a789a3 diff --git a/crt/aws-c-s3 b/crt/aws-c-s3 index aede1d8c2..16701501f 160000 --- a/crt/aws-c-s3 +++ b/crt/aws-c-s3 @@ -1 +1 @@ -Subproject commit aede1d8c24f9f580d5a96c089878e9b258b88d04 +Subproject commit 16701501fa9d1684b0ff5406211d058ce2a5b404 diff --git a/crt/aws-lc b/crt/aws-lc index 8b2ebfcf3..8ffe277c2 160000 --- a/crt/aws-lc +++ b/crt/aws-lc @@ -1 +1 @@ -Subproject commit 8b2ebfcf3fc8b0656f1f4161166484a70238aeaa +Subproject commit 8ffe277c21915ca82dc78a3bdc6a92e10c284b92 From 1f3d0a342e1502d5e97f8811248878b844493349 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Mon, 21 Oct 2024 08:38:47 -0700 Subject: [PATCH 021/126] AutoTag PR for v0.28.5 (#670) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 097bc9362..16b6bcee6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.28.4 +0.28.5 From cc157e86d3bef4ab6de3d4a9168a31e932487735 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Wed, 23 Oct 2024 10:55:47 -0700 Subject: [PATCH 022/126] Update CMake to 3.9 (#666) Co-authored-by: Michael Graeb --- CMakeLists.txt | 3 ++- crt/aws-c-auth | 2 +- crt/aws-c-cal | 2 +- crt/aws-c-common | 2 +- crt/aws-c-compression | 2 +- crt/aws-c-event-stream | 2 +- crt/aws-c-http | 2 +- crt/aws-c-io | 2 +- crt/aws-c-mqtt | 2 +- crt/aws-c-s3 | 2 +- crt/aws-c-sdkutils | 2 +- crt/aws-checksums | 2 +- 12 files changed, 13 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2efcee399..560ed5259 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) if(POLICY CMP0077) cmake_policy(SET CMP0077 NEW) @@ -302,6 +302,7 @@ endif() set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX) set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD ${CMAKE_CXX_STANDARD}) +set_target_properties(${PROJECT_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON) aws_prepare_symbol_visibility_args(${PROJECT_NAME} "AWS_CRT_CPP") diff --git a/crt/aws-c-auth b/crt/aws-c-auth index 48d647bf4..3982bd75f 160000 --- a/crt/aws-c-auth +++ b/crt/aws-c-auth @@ -1 +1 @@ -Subproject commit 48d647bf43f8872e4dc5ec6343b0c5974195fbdd +Subproject commit 3982bd75fea74efd8f9b462b27fedd4599db4f53 diff --git a/crt/aws-c-cal b/crt/aws-c-cal index 2cb1d2eac..656762aef 160000 --- a/crt/aws-c-cal +++ b/crt/aws-c-cal @@ -1 +1 @@ -Subproject commit 2cb1d2eac925e2dbc45025eb89af82bd790c23a0 +Subproject commit 656762aefbee2bc8f509cb23cd107abff20a72bb diff --git a/crt/aws-c-common b/crt/aws-c-common index f58e807d8..f41b772f0 160000 --- a/crt/aws-c-common +++ b/crt/aws-c-common @@ -1 +1 @@ -Subproject commit f58e807d8fd643bd9a96eef182c1db37d01b88e7 +Subproject commit f41b772f0de9454a4e7a65750b58c2379533bbf1 diff --git a/crt/aws-c-compression b/crt/aws-c-compression index f36d01672..c6c1191e5 160000 --- a/crt/aws-c-compression +++ b/crt/aws-c-compression @@ -1 +1 @@ -Subproject commit f36d01672d61e49d96a777870d456f66fa391cd4 +Subproject commit c6c1191e525e5aa6ead9e1afc392e35d3b50331e diff --git a/crt/aws-c-event-stream b/crt/aws-c-event-stream index 1b3825fc9..d2dcc9344 160000 --- a/crt/aws-c-event-stream +++ b/crt/aws-c-event-stream @@ -1 +1 @@ -Subproject commit 1b3825fc9cae2e9c7ed7479ee5d354d52ebdf7a0 +Subproject commit d2dcc9344dae24de320866045d85166d8a91a0d1 diff --git a/crt/aws-c-http b/crt/aws-c-http index 6068653e1..74b3a0dd1 160000 --- a/crt/aws-c-http +++ b/crt/aws-c-http @@ -1 +1 @@ -Subproject commit 6068653e1d582bd8e7d1c9f81f86beaf10444e3d +Subproject commit 74b3a0dd1396b72f701c8bdf24e5c6f41e52cf87 diff --git a/crt/aws-c-io b/crt/aws-c-io index e36374047..fe93d0afc 160000 --- a/crt/aws-c-io +++ b/crt/aws-c-io @@ -1 +1 @@ -Subproject commit e36374047beadc72a0eb6df14ce3cbc822a789a3 +Subproject commit fe93d0afcc1cede32ac9569abd8669ed011b1b8c diff --git a/crt/aws-c-mqtt b/crt/aws-c-mqtt index 77d6f00e8..627c3334e 160000 --- a/crt/aws-c-mqtt +++ b/crt/aws-c-mqtt @@ -1 +1 @@ -Subproject commit 77d6f00e89b10e3263d8a17576ec8e91c45b4606 +Subproject commit 627c3334e52021aa8d5772b6ca076884610f3219 diff --git a/crt/aws-c-s3 b/crt/aws-c-s3 index 16701501f..8c1969bce 160000 --- a/crt/aws-c-s3 +++ b/crt/aws-c-s3 @@ -1 +1 @@ -Subproject commit 16701501fa9d1684b0ff5406211d058ce2a5b404 +Subproject commit 8c1969bce5bfe0e063cbc719182dbe344342b880 diff --git a/crt/aws-c-sdkutils b/crt/aws-c-sdkutils index 4658412a6..0818f28ee 160000 --- a/crt/aws-c-sdkutils +++ b/crt/aws-c-sdkutils @@ -1 +1 @@ -Subproject commit 4658412a61ad5749db92a8d1e0717cb5e76ada1c +Subproject commit 0818f28ee436b892f09fbe8e3a6ae37ff40e9436 diff --git a/crt/aws-checksums b/crt/aws-checksums index ce04ab00b..0d2f5521f 160000 --- a/crt/aws-checksums +++ b/crt/aws-checksums @@ -1 +1 @@ -Subproject commit ce04ab00b3ecc41912f478bfedca39f8e1919d6b +Subproject commit 0d2f5521f61215f38f791d106ae304402208112d From fbd5310be54cc853807c06e85a9290560fc8f986 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Wed, 23 Oct 2024 10:56:23 -0700 Subject: [PATCH 023/126] AutoTag PR for v0.29.0 (#671) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 16b6bcee6..ae6dd4e20 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.28.5 +0.29.0 From 3eeab89d57c50ff307c03aca87fd374bce3dd821 Mon Sep 17 00:00:00 2001 From: Ashish Dhingra <67916761+ashishdhingra@users.noreply.github.com> Date: Fri, 25 Oct 2024 16:09:33 -0700 Subject: [PATCH 024/126] chore: Modified bug issue template to add checkbox to report potential regression. (#661) Co-authored-by: Joseph Klix --- .github/ISSUE_TEMPLATE/bug-report.yml | 8 +++++ .../workflows/issue-regression-labeler.yml | 32 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 .github/workflows/issue-regression-labeler.yml diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 1f3e1f5d5..f54c30d45 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -12,6 +12,14 @@ body: description: What is the problem? A clear and concise description of the bug. validations: required: true + - type: checkboxes + id: regression + attributes: + label: Regression Issue + description: What is a regression? If it worked in a previous version but doesn't in the latest version, it's considered a regression. In this case, please provide specific version number in the report. + options: + - label: Select this option if this issue appears to be a regression. + required: false - type: textarea id: expected attributes: diff --git a/.github/workflows/issue-regression-labeler.yml b/.github/workflows/issue-regression-labeler.yml new file mode 100644 index 000000000..bd000719d --- /dev/null +++ b/.github/workflows/issue-regression-labeler.yml @@ -0,0 +1,32 @@ +# Apply potential regression label on issues +name: issue-regression-label +on: + issues: + types: [opened, edited] +jobs: + add-regression-label: + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - name: Fetch template body + id: check_regression + uses: actions/github-script@v7 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TEMPLATE_BODY: ${{ github.event.issue.body }} + with: + script: | + const regressionPattern = /\[x\] Select this option if this issue appears to be a regression\./i; + const template = `${process.env.TEMPLATE_BODY}` + const match = regressionPattern.test(template); + core.setOutput('is_regression', match); + - name: Manage regression label + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + if [ "${{ steps.check_regression.outputs.is_regression }}" == "true" ]; then + gh issue edit ${{ github.event.issue.number }} --add-label "potential-regression" -R ${{ github.repository }} + else + gh issue edit ${{ github.event.issue.number }} --remove-label "potential-regression" -R ${{ github.repository }} + fi From 80f4736126e14223a0c3882d3b734607143731f3 Mon Sep 17 00:00:00 2001 From: Michael Graeb Date: Wed, 30 Oct 2024 15:19:10 -0700 Subject: [PATCH 025/126] Fix s2n cleanup (#672) Fix comes from updated submodules: s2n v1.5.5 -> 9819ac0e (no tagged releases yet with s2n_cleanup_final(), so using commit from main branch) aws-c-io v0.15.0 -> v0.15.1 --- crt/aws-c-io | 2 +- crt/s2n | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crt/aws-c-io b/crt/aws-c-io index fe93d0afc..e247ef89c 160000 --- a/crt/aws-c-io +++ b/crt/aws-c-io @@ -1 +1 @@ -Subproject commit fe93d0afcc1cede32ac9569abd8669ed011b1b8c +Subproject commit e247ef89cdf170cadcb4c665fb0146e82cd6e135 diff --git a/crt/s2n b/crt/s2n index ffe0bf42d..9819ac0e2 160000 --- a/crt/s2n +++ b/crt/s2n @@ -1 +1 @@ -Subproject commit ffe0bf42da8f139eff8fd2237f47fbde40b478fb +Subproject commit 9819ac0e2e028e3b761855fc4f2f8134008d3f4b From 405c59d2876bd433ece3acd51730d2182d0786b3 Mon Sep 17 00:00:00 2001 From: Michael Graeb Date: Fri, 1 Nov 2024 17:26:21 -0700 Subject: [PATCH 026/126] Use S2N-TLS v1.5.7 (#673) Previously, we were using an untagged commit of S2N-TLS to get at the new `s2n_cleanup_final()` function, but now that function is available in a tagged release, so use it. --- crt/s2n | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crt/s2n b/crt/s2n index 9819ac0e2..9f4baecc7 160000 --- a/crt/s2n +++ b/crt/s2n @@ -1 +1 @@ -Subproject commit 9819ac0e2e028e3b761855fc4f2f8134008d3f4b +Subproject commit 9f4baecc753d6fe01c13e4f422d2e327c64d06b8 From c21e25548edacf26150c862d1a54e206b1564e9b Mon Sep 17 00:00:00 2001 From: Michael Graeb Date: Mon, 4 Nov 2024 10:55:11 -0800 Subject: [PATCH 027/126] Fix crashes in GCC 4.x shared-libs builds, due to recent symbol visibility changes (#675) **Issue:** When building with GCC 4.8 and 4.9 and `-DBUILD_SHARED_LIBS=ON`, many tests were crashing. The crashes would say something like "free(): invalid pointer" and the stack trace would point into the c++ string headers. **Things we tried** - Crash stopped if we commented out the [recently-added line in CMakeLists.txt](https://github.com/awslabs/aws-crt-cpp/blob/80f4736126e14223a0c3882d3b734607143731f3/CMakeLists.txt#L305) line that sets `CXX_VISIBILITY_PRESET hidden`. So obviously symbol visibility has something to do with it. - We tried adding adding `AWS_CRT_CPP_API` to the templated `StlAllocator` class (see https://github.com/awslabs/aws-crt-cpp/pull/675/commits/edfed1419841cd20bd21c0421861329f2deb2aad), which stopped GCC 4.x from crashing, but then the [Windows compiler didn't like that](https://github.com/awslabs/aws-crt-cpp/actions/runs/11636848409/job/32409003392#step:2:2373). **Description of Changes:** Don't set visibility to hidden for GCC < 5. That's how we had it before. GCC 4.x is very old. This isn't the first time it's disappointed us --- .github/workflows/ci.yml | 10 +++++++++- CMakeLists.txt | 8 +++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4fc023abd..37879946f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,6 +17,11 @@ env: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_REGION: us-east-1 +# cancel in-progress builds after a new commit +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: linux-compat-use-openssl: runs-on: ubuntu-22.04 # latest @@ -128,12 +133,15 @@ jobs: linux-shared-libs: runs-on: ubuntu-22.04 # latest + strategy: + matrix: + compiler: [gcc-4.8, gcc-11] # oldest, latest steps: # We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages - name: Build ${{ env.PACKAGE_NAME }} run: | aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh - ./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --cmake-extra=-DBUILD_SHARED_LIBS=ON + ./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --compiler=${{ matrix.compiler }} --cmake-extra=-DBUILD_SHARED_LIBS=ON linux-openssl-static: runs-on: ubuntu-22.04 # latest diff --git a/CMakeLists.txt b/CMakeLists.txt index 560ed5259..7b703140a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -302,7 +302,13 @@ endif() set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX) set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD ${CMAKE_CXX_STANDARD}) -set_target_properties(${PROJECT_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON) + +# Hide symbols by default +# Except for ancient GCC, because it leads to crashes in shared-lib builds +# see: https://github.com/awslabs/aws-crt-cpp/pull/675 +if(NOT (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0")) + set_target_properties(${PROJECT_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON) +endif() aws_prepare_symbol_visibility_args(${PROJECT_NAME} "AWS_CRT_CPP") From c39783983e9b72b5070813b1958ed592d065ddc3 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Mon, 4 Nov 2024 10:56:38 -0800 Subject: [PATCH 028/126] AutoTag PR for v0.29.1 (#676) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index ae6dd4e20..25939d35c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.29.0 +0.29.1 From 28db85efd01b3a2610a5051d2f6eeaa6af82e45b Mon Sep 17 00:00:00 2001 From: Michael Graeb Date: Thu, 7 Nov 2024 09:21:05 -0800 Subject: [PATCH 029/126] stop building s2n via aws_prebuild_dependency() (#677) **Issue:** aws-sdk-cpp could no longer cross-compile for Android, after we switched to building S2N via [aws_prebuild_dependency()](https://github.com/awslabs/aws-c-common/blob/bb29dc816ac6fe8678765c3b869f47326b942367/cmake/AwsPrebuildDependency.cmake) in this PR: https://github.com/awslabs/aws-crt-cpp/pull/665 **Description of changes:** Go back to building s2n via CMake's `add_subdirectory()`. This does a better job picking up misc CMake settings (like toolchains for cross-compilation) than `aws_prebuild_dependency()` We'll continue building AWS-LC via `aws_prebuild_dependency()` for now, since we still need `libcrypto` fully built before S2N's configure stage. But that won't be a problem for `aws-sdk-cpp` which always passes `-DUSE_OPENSSL=ON` to skip building AWS-LC and use the system's pre-existing libcrypto instead. --- CMakeLists.txt | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b703140a..7c33e204e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,8 +83,8 @@ if(BUILD_DEPS) add_subdirectory(crt/aws-c-common) if(UNIX AND NOT APPLE AND NOT BYO_CRYPTO) - include(AwsPrebuildDependency) if(NOT USE_OPENSSL) + include(AwsPrebuildDependency) set(AWSLC_CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") @@ -116,14 +116,8 @@ if(BUILD_DEPS) ) endif() - # prebuild s2n-tls. - aws_prebuild_dependency( - DEPENDENCY_NAME S2N - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/crt/s2n - CMAKE_ARGUMENTS - -DUNSAFE_TREAT_WARNINGS_AS_ERRORS=OFF - -DBUILD_TESTING=OFF - ) + set(UNSAFE_TREAT_WARNINGS_AS_ERRORS OFF CACHE BOOL "Disable warnings-as-errors when building S2N") + add_subdirectory(crt/s2n) endif() add_subdirectory(crt/aws-c-sdkutils) From ea7aa818bb07276bfcf7c8b418eac73726a0b0d2 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Thu, 7 Nov 2024 09:31:49 -0800 Subject: [PATCH 030/126] AutoTag PR for v0.29.2 (#681) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 25939d35c..20f068700 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.29.1 +0.29.2 From 51f26b56fc30653ee203bba40af91cb88cc60fa4 Mon Sep 17 00:00:00 2001 From: Sam Bisciglia Date: Thu, 7 Nov 2024 12:48:07 -0500 Subject: [PATCH 031/126] fix checksum install location (#680) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c33e204e..9f062caa6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -348,7 +348,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC ${DEP_AWS_LIBS}) install(FILES ${AWS_CRT_HEADERS} DESTINATION "include/aws/crt" COMPONENT Development) install(FILES ${AWS_CRT_AUTH_HEADERS} DESTINATION "include/aws/crt/auth" COMPONENT Development) -install(FILES ${AWS_CRT_CHECKSUM_HEADERS} DESTINATION "include/aws/crt/crypto" COMPONENT Development) +install(FILES ${AWS_CRT_CHECKSUM_HEADERS} DESTINATION "include/aws/crt/checksum" COMPONENT Development) install(FILES ${AWS_CRT_CRYPTO_HEADERS} DESTINATION "include/aws/crt/crypto" COMPONENT Development) install(FILES ${AWS_CRT_IO_HEADERS} DESTINATION "include/aws/crt/io" COMPONENT Development) install(FILES ${AWS_CRT_IOT_HEADERS} DESTINATION "include/aws/iot" COMPONENT Development) From 281a7caff7e10f68a5422d8fca8acf0b48e4215f Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Thu, 7 Nov 2024 09:50:50 -0800 Subject: [PATCH 032/126] AutoTag PR for v0.29.3 (#682) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 20f068700..5540b6e00 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.29.2 +0.29.3 From 6bbd4ebe0bfd7f89601f8d2351f1ce54ba7fb27b Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Fri, 8 Nov 2024 11:04:27 -0800 Subject: [PATCH 033/126] Request response workspace (#664) Co-authored-by: Bret Ambrose --- .clang-tidy | 2 +- include/aws/crt/Variant.h | 1 + include/aws/crt/mqtt/Mqtt5Client.h | 2 + include/aws/crt/mqtt/MqttConnection.h | 2 +- .../aws/crt/mqtt/private/Mqtt5ClientCore.h | 2 + .../aws/crt/mqtt/private/MqttConnectionCore.h | 2 +- include/aws/iot/MqttRequestResponseClient.h | 550 +++++++++ source/iot/MqttRequestResponseClient.cpp | 508 ++++++++ source/mqtt/Mqtt5Client.cpp | 5 + source/mqtt/MqttConnection.cpp | 2 +- source/mqtt/MqttConnectionCore.cpp | 2 +- tests/CMakeLists.txt | 32 + tests/MqttRequestResponse.cpp | 1099 +++++++++++++++++ 13 files changed, 2204 insertions(+), 5 deletions(-) create mode 100644 include/aws/iot/MqttRequestResponseClient.h create mode 100644 source/iot/MqttRequestResponseClient.cpp create mode 100644 tests/MqttRequestResponse.cpp diff --git a/.clang-tidy b/.clang-tidy index 1e6248e3d..d7cb48794 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,5 +1,5 @@ --- -Checks: 'clang-diagnostic-*,clang-analyzer-*,readability-*,modernize-*,bugprone-*,misc-*,google-runtime-int,llvm-header-guard,fuchsia-restrict-system-includes,-clang-analyzer-valist.Uninitialized,-clang-analyzer-security.insecureAPI.rand,-clang-analyzer-alpha.*,-readability-magic-numbers,-readability-non-const-parameter' +Checks: 'clang-diagnostic-*,clang-analyzer-*,readability-*,modernize-*,bugprone-*,misc-*,google-runtime-int,llvm-header-guard,fuchsia-restrict-system-includes,-clang-analyzer-valist.Uninitialized,-clang-analyzer-security.insecureAPI.rand,-clang-analyzer-alpha.*,-readability-magic-numbers,-readability-non-const-parameter,-modernize-use-trailing-return-type' WarningsAsErrors: '*' HeaderFilterRegex: '.*(? void operator()(AlternativeT &&value) const { + (void)value; using PlaintT = typename std::remove_reference::type; value.~PlaintT(); } diff --git a/include/aws/crt/mqtt/Mqtt5Client.h b/include/aws/crt/mqtt/Mqtt5Client.h index 02bf48d2e..3eafc161a 100644 --- a/include/aws/crt/mqtt/Mqtt5Client.h +++ b/include/aws/crt/mqtt/Mqtt5Client.h @@ -435,6 +435,8 @@ namespace Aws virtual ~Mqtt5Client(); + struct aws_mqtt5_client *GetUnderlyingHandle() const noexcept; + private: Mqtt5Client(const Mqtt5ClientOptions &options, Allocator *allocator = ApiAllocator()) noexcept; diff --git a/include/aws/crt/mqtt/MqttConnection.h b/include/aws/crt/mqtt/MqttConnection.h index 670dad35d..cd8049425 100644 --- a/include/aws/crt/mqtt/MqttConnection.h +++ b/include/aws/crt/mqtt/MqttConnection.h @@ -263,7 +263,7 @@ namespace Aws bool Disconnect() noexcept; /// @private - aws_mqtt_client_connection *GetUnderlyingConnection() noexcept; + aws_mqtt_client_connection *GetUnderlyingConnection() const noexcept; /** * Subscribes to topicFilter. OnMessageReceivedHandler will be invoked from an event-loop diff --git a/include/aws/crt/mqtt/private/Mqtt5ClientCore.h b/include/aws/crt/mqtt/private/Mqtt5ClientCore.h index 69dac4d77..3e9a0a346 100644 --- a/include/aws/crt/mqtt/private/Mqtt5ClientCore.h +++ b/include/aws/crt/mqtt/private/Mqtt5ClientCore.h @@ -109,6 +109,8 @@ namespace Aws virtual ~Mqtt5ClientCore(); + struct aws_mqtt5_client *GetUnderlyingHandle() const noexcept { return m_client; } + private: Mqtt5ClientCore(const Mqtt5ClientOptions &options, Allocator *allocator = ApiAllocator()) noexcept; diff --git a/include/aws/crt/mqtt/private/MqttConnectionCore.h b/include/aws/crt/mqtt/private/MqttConnectionCore.h index 8b0d503f8..827cc9db4 100644 --- a/include/aws/crt/mqtt/private/MqttConnectionCore.h +++ b/include/aws/crt/mqtt/private/MqttConnectionCore.h @@ -151,7 +151,7 @@ namespace Aws bool Disconnect() noexcept; /// @private - aws_mqtt_client_connection *GetUnderlyingConnection() noexcept; + aws_mqtt_client_connection *GetUnderlyingConnection() const noexcept; /** * @internal diff --git a/include/aws/iot/MqttRequestResponseClient.h b/include/aws/iot/MqttRequestResponseClient.h new file mode 100644 index 000000000..805db22c3 --- /dev/null +++ b/include/aws/iot/MqttRequestResponseClient.h @@ -0,0 +1,550 @@ +#pragma once +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include + +#include +#include +#include +#include +#include + +#include + +namespace Aws +{ + + namespace Crt + { + namespace Mqtt + { + class MqttConnection; + } + + namespace Mqtt5 + { + class Mqtt5Client; + } + } // namespace Crt + + namespace Iot + { + namespace RequestResponse + { + /** + * The type of change to the state of a streaming operation subscription + */ + enum class SubscriptionStatusEventType + { + + /** + * The streaming operation is successfully subscribed to its topic (filter) + */ + SubscriptionEstablished = ARRSSET_SUBSCRIPTION_ESTABLISHED, + + /** + * The streaming operation has temporarily lost its subscription to its topic (filter) + */ + SubscriptionLost = ARRSSET_SUBSCRIPTION_LOST, + + /** + * The streaming operation has entered a terminal state where it has given up trying to subscribe + * to its topic (filter). This is always due to user error (bad topic filter or IoT Core permission + * policy). + */ + SubscriptionHalted = ARRSSET_SUBSCRIPTION_HALTED, + }; + + /** + * An event that describes a change in subscription status for a streaming operation. + */ + class AWS_CRT_CPP_API SubscriptionStatusEvent + { + public: + /** + * Sets the type of the event + * + * @param type kind of subscription status event this is + * @return reference to this + */ + SubscriptionStatusEvent &WithType(SubscriptionStatusEventType type) + { + m_type = type; + return *this; + } + + /** + * Sets an optional error code associated with the event + * + * @param errorCode CRT error code corresponding to the event + * @return reference to this + */ + SubscriptionStatusEvent &WithErrorCode(int errorCode) + { + m_errorCode = errorCode; + return *this; + } + + /** + * Gets the type of event + * @return the type of the event + */ + SubscriptionStatusEventType GetType() const { return m_type; } + + /** + * Get the error code associated with this event + * @return the error code associated with this event + */ + int GetErrorCode() const { return m_errorCode; } + + private: + SubscriptionStatusEventType m_type = SubscriptionStatusEventType::SubscriptionEstablished; + int m_errorCode = 0; + }; + + /** + * Function signature of a SubscriptionStatusEvent event handler + */ + using SubscriptionStatusEventHandler = std::function; + + /** + * An event that describes an incoming publish message received on a streaming operation. + * + * @internal + */ + class AWS_CRT_CPP_API IncomingPublishEvent + { + public: + /** + * Default constructor + */ + IncomingPublishEvent() : m_payload() { AWS_ZERO_STRUCT(m_payload); } + + /** + * Sets the message payload associated with this event. The event does not own this payload. + * + * @param payload he message payload associated with this event + * @return reference to this + */ + IncomingPublishEvent &WithPayload(Aws::Crt::ByteCursor payload) + { + m_payload = payload; + return *this; + } + + /** + * Gets the message payload associated with this event. + * + * @return the message payload associated with this event + */ + Aws::Crt::ByteCursor GetPayload() const { return m_payload; } + + private: + Aws::Crt::ByteCursor m_payload; + }; + + /** + * Function signature of an IncomingPublishEvent event handler + * + * @internal + */ + using IncomingPublishEventHandler = std::function; + + /** + * Encapsulates a response to an AWS IoT Core MQTT-based service request + * + * @internal + */ + class AWS_CRT_CPP_API UnmodeledResponse + { + public: + /** + * Default constructor + */ + UnmodeledResponse() : m_topic(), m_payload() + { + AWS_ZERO_STRUCT(m_payload); + AWS_ZERO_STRUCT(m_topic); + } + + /** + * Sets the payload of the response that correlates to a submitted request. + * + * @param payload the payload of the response that correlates to a submitted request + * @return reference to this + */ + UnmodeledResponse &WithPayload(Aws::Crt::ByteCursor payload) + { + m_payload = payload; + return *this; + } + + /** + * Sets the MQTT Topic that the response was received on. + * + * @param topic the MQTT Topic that the response was received on + * @return reference to this + */ + UnmodeledResponse &WithTopic(Aws::Crt::ByteCursor topic) + { + m_topic = topic; + return *this; + } + + /** + * Gets the payload of the response that correlates to a submitted request. + * + * @return the payload of the response that correlates to a submitted request + */ + Aws::Crt::ByteCursor GetPayload() const { return m_payload; } + + /** + * Gets the MQTT Topic that the response was received on. + * + * @return the MQTT Topic that the response was received on + */ + Aws::Crt::ByteCursor GetTopic() const { return m_topic; } + + private: + /** + * MQTT Topic that the response was received on. Different topics map to different types within the + * service model, so we need this value in order to know what to deserialize the payload into. + */ + Aws::Crt::ByteCursor m_topic; + + /** + * Payload of the response that correlates to a submitted request. + */ + Aws::Crt::ByteCursor m_payload; + }; + + /** + * Either-or type that models the result of a carrying out a request - a response or an error. + * + * @tparam R type of a successful response + * @tparam E type of an error + */ + template class Result + { + public: + Result() = delete; + + explicit Result(const R &response) : m_rawResult(response) {} + explicit Result(R &&response) : m_rawResult(std::move(response)) {} + explicit Result(const E &error) : m_rawResult(error) {} + explicit Result(E &&error) : m_rawResult(std::move(error)) {} + + Result &operator=(const R &response) + { + this->m_rawResult = response; + + return *this; + } + + Result &operator=(R &&response) + { + this->m_rawResult = std::move(response); + + return *this; + } + + Result &operator=(const E &error) + { + this->m_rawResult = error; + return *this; + } + + Result &operator=(E &&error) + { + this->m_rawResult = std::move(error); + + return *this; + } + + bool IsSuccess() const { return m_rawResult.template holds_alternative(); } + + const R &GetResponse() const + { + AWS_FATAL_ASSERT(IsSuccess()); + + return m_rawResult.template get(); + } + + const E &GetError() const + { + AWS_FATAL_ASSERT(!IsSuccess()); + + return m_rawResult.template get(); + } + + private: + Aws::Crt::Variant m_rawResult; + }; + + /** + * Type definition for a request result where a response has not yet been deserialized into a specific + * response type. + */ + using UnmodeledResult = Result; + + /** + * Signature of a function object that handles unmodeled results. In general, these handlers will + * be built by service clients and are responsible for transforming an unmodeled response into a + * modeled response. + */ + using UnmodeledResultHandler = std::function; + + /** + * Generic configuration options for streaming operations + * + * @tparam T modeled message type emitted/handled by a particular stream + */ + template class StreamingOperationOptions + { + public: + /** + * Sets the handler function a streaming operation will use for subscription status events. + * + * @param handler the handler function a streaming operation will use for subscription status events + * @return reference to this + */ + StreamingOperationOptions &WithSubscriptionStatusEventHandler( + const SubscriptionStatusEventHandler &handler) + { + m_subscriptionStatusEventHandler = handler; + return *this; + } + + /** + * Sets the handler function a streaming operation will use for the modeled message type. + * + * @param handler the handler function a streaming operation will use for the modeled message type + * @return reference to this + */ + StreamingOperationOptions &WithStreamHandler(const std::function &handler) + { + m_streamHandler = handler; + return *this; + } + + /** + * Gets the handler function a streaming operation will use for subscription status events. + * + * @return the handler function a streaming operation will use for subscription status events + */ + const SubscriptionStatusEventHandler &GetSubscriptionStatusEventHandler() const + { + return m_subscriptionStatusEventHandler; + } + + /** + * Gets the handler function a streaming operation will use for the modeled message type. + * + * @return the handler function a streaming operation will use for the modeled message type + */ + const std::function &GetStreamHandler() const { return m_streamHandler; } + + private: + SubscriptionStatusEventHandler m_subscriptionStatusEventHandler; + + std::function m_streamHandler; + }; + + /** + * Streaming operation configuration options used internally by a service client's request response + * client. + * + * @internal + */ + struct AWS_CRT_CPP_API StreamingOperationOptionsInternal + { + public: + StreamingOperationOptionsInternal() + : subscriptionTopicFilter(), subscriptionStatusEventHandler(), incomingPublishEventHandler() + { + AWS_ZERO_STRUCT(subscriptionTopicFilter); + } + + Aws::Crt::ByteCursor subscriptionTopicFilter; + + SubscriptionStatusEventHandler subscriptionStatusEventHandler; + + IncomingPublishEventHandler incomingPublishEventHandler; + }; + + /** + * Base type for all streaming operations + */ + class AWS_CRT_CPP_API IStreamingOperation + { + public: + /** + * A streaming operation is automatically closed (and an MQTT unsubscribe triggered) when its + * destructor is invoked. + */ + virtual ~IStreamingOperation() = default; + + /** + * Opens a streaming operation by making the appropriate MQTT subscription with the broker. + */ + virtual void Open() = 0; + }; + + /** + * MQTT-based request-response client configuration options + */ + class AWS_CRT_CPP_API RequestResponseClientOptions + { + public: + /** + * Sets the maximum number of request-response subscriptions the client allows to be concurrently active + * at any one point in time. When the client hits this threshold, requests will be delayed until + * earlier requests complete and release their subscriptions. Each in-progress request will use either + * 1 or 2 MQTT subscriptions until completion. + * + * @param maxRequestResponseSubscriptions maximum number of concurrent subscriptions that the client + * will use for request-response operations + * @return reference to this + */ + RequestResponseClientOptions &WithMaxRequestResponseSubscriptions( + uint32_t maxRequestResponseSubscriptions) + { + m_maxRequestResponseSubscriptions = maxRequestResponseSubscriptions; + return *this; + } + + /** + * Sets the maximum number of concurrent streaming operation subscriptions that the client will allow. + * Each "unique" (different topic filter) streaming operation will use 1 MQTT subscription. When the + * client hits this threshold, attempts to open new streaming operations will fail. + * + * @param maxStreamingSubscriptions maximum number of current subscriptions that the client will + * use for streaming operations + * @return reference to this + */ + RequestResponseClientOptions &WithMaxStreamingSubscriptions(uint32_t maxStreamingSubscriptions) + { + m_maxStreamingSubscriptions = maxStreamingSubscriptions; + return *this; + } + + /** + * Sets the timeout value, in seconds, for a request-response operation. If a request is not complete + * by this time interval, the client will complete it as failed. This time interval starts the instant + * the request is submitted to the client. + * + * @param operationTimeoutInSeconds request timeout in seconds + * @return reference to this + */ + RequestResponseClientOptions &WithOperationTimeoutInSeconds(uint32_t operationTimeoutInSeconds) + { + m_operationTimeoutInSeconds = operationTimeoutInSeconds; + return *this; + } + + /** + * Gets the maximum number of request-response subscriptions the client allows to be concurrently + * active. + * + * @return the maximum number of request-response subscriptions the client allows to be concurrently + * active + */ + uint32_t GetMaxRequestResponseSubscriptions() const { return m_maxRequestResponseSubscriptions; } + + /** + * Gets the maximum number of concurrent streaming operation subscriptions that the client will allow. + * + * @return the maximum number of concurrent streaming operation subscriptions that the client will allow + */ + uint32_t GetMaxStreamingSubscriptions() const { return m_maxStreamingSubscriptions; } + + /** + * Gets the timeout value, in seconds, for a request-response operation. + * + * @return the timeout value, in seconds, for a request-response operation + */ + uint32_t GetOperationTimeoutInSeconds() const { return m_operationTimeoutInSeconds; } + + private: + /** + * Maximum number of subscriptions that the client will concurrently use for request-response operations + */ + uint32_t m_maxRequestResponseSubscriptions = 0; + + /** + * Maximum number of subscriptions that the client will concurrently use for streaming operations + */ + uint32_t m_maxStreamingSubscriptions = 0; + + /** + * Duration, in seconds, that a request-response operation will wait for completion before giving up + */ + uint32_t m_operationTimeoutInSeconds = 0; + }; + + /** + * Generic interface for the request-response client + */ + class AWS_CRT_CPP_API IMqttRequestResponseClient + { + public: + /** + * There is no close operation for the client. When the destructor is invoked, the underlying client + * will be closed. + */ + virtual ~IMqttRequestResponseClient() = default; + + /** + * Submits a generic request to the request-response client. + * + * @param requestOptions description of the request the client should perform + * @param resultHandler function object to invoke when the request is completed + * @return success (AWS_OP_SUCCESS) or failure (AWS_OP_ERR) + */ + virtual int SubmitRequest( + const aws_mqtt_request_operation_options &requestOptions, + UnmodeledResultHandler &&resultHandler) = 0; + + /** + * Creates a new streaming operation. Streaming operations "listen" to a specific kind of service + * event and invoke handlers every time one is received. + * + * @param options configuration options for the streaming operation to construct + * @return + */ + virtual std::shared_ptr CreateStream( + const StreamingOperationOptionsInternal &options) = 0; + }; + + /** + * Creates a new request-response client using an MQTT5 client for protocol transport + * + * @param protocolClient MQTT client to use for transport + * @param options request-response client configuration options + * @param allocator allocator to use to create the client + * @return a new request-response client if successful, otherwise nullptr + */ + AWS_CRT_CPP_API std::shared_ptr NewClientFrom5( + const Aws::Crt::Mqtt5::Mqtt5Client &protocolClient, + const RequestResponseClientOptions &options, + Aws::Crt::Allocator *allocator = Aws::Crt::ApiAllocator()); + + /** + * Creates a new request-response client using an MQTT311 client for protocol transport + * + * @param protocolClient MQTT client to use for transport + * @param options request-response client configuration options + * @param allocator allocator to use to create the client + * @return a new request-response client if successful, otherwise nullptr + */ + AWS_CRT_CPP_API std::shared_ptr NewClientFrom311( + const Aws::Crt::Mqtt::MqttConnection &protocolClient, + const RequestResponseClientOptions &options, + Aws::Crt::Allocator *allocator = Aws::Crt::ApiAllocator()); + + } // namespace RequestResponse + } // namespace Iot +} // namespace Aws diff --git a/source/iot/MqttRequestResponseClient.cpp b/source/iot/MqttRequestResponseClient.cpp new file mode 100644 index 000000000..2bdcb960f --- /dev/null +++ b/source/iot/MqttRequestResponseClient.cpp @@ -0,0 +1,508 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include + +#include +#include + +#include +#include + +namespace Aws +{ + namespace Iot + { + namespace RequestResponse + { + + /* + * RAII wrapper around taking a read lock for a referenced read-write lock. + * + * Used to protect the stream from destruction while in a callback or Open() call. Protects the + * m_closed field of StreamingOperationImpl. + */ + class StreamReadLock + { + public: + StreamReadLock(struct aws_rw_lock *lock) : m_lock(lock) { aws_rw_lock_rlock(lock); } + + ~StreamReadLock() { aws_rw_lock_runlock(m_lock); } + + private: + struct aws_rw_lock *m_lock; + }; + + /* + * RAII wrapper around taking a *conditional* write lock for a referenced read-write lock. Protects the + * m_closed field of StreamingOperationImpl. + * + * Used to block callbacks while destruction is triggered. Only ever used by the stream destructor. + * We conditionally take the lock because if we're already in the event loop thread we're safe and we + * are probably (but not guaranteed to be) in a callback. This prevents deadlock from trying to upgrade + * an already taken read lock to a write lock, which is not supported by the underlying read-write lock. + */ + class StreamWriteLock + { + public: + StreamWriteLock(struct aws_rw_lock *lock, struct aws_event_loop *protocolLoop) + : m_lock(lock), m_taken(false) + { + if (!aws_event_loop_thread_is_callers_thread(protocolLoop)) + { + m_taken = true; + aws_rw_lock_wlock(lock); + } + } + + ~StreamWriteLock() + { + if (m_taken) + { + aws_rw_lock_wunlock(m_lock); + } + } + + private: + struct aws_rw_lock *m_lock; + + bool m_taken; + }; + + class StreamingOperationImpl + { + public: + StreamingOperationImpl( + struct aws_mqtt_rr_client_operation *stream, + const StreamingOperationOptionsInternal &options, + struct aws_event_loop *protocolLoop); + virtual ~StreamingOperationImpl(); + + void Open(); + + void Close(); + + static void OnSubscriptionStatusCallback( + enum aws_rr_streaming_subscription_event_type status, + int error_code, + void *user_data); + + static void OnIncomingPublishCallback(struct aws_byte_cursor payload, void *user_data); + + static void OnTerminatedCallback(void *user_data); + + private: + StreamingOperationOptionsInternal m_config; + + struct aws_mqtt_rr_client_operation *m_stream; + + struct aws_event_loop *m_protocolLoop; + + struct aws_rw_lock m_lock; + + bool m_closed; + }; + + struct StreamingOperationImplHandle + { + StreamingOperationImplHandle() : m_allocator(nullptr), m_impl(nullptr) {} + + Aws::Crt::Allocator *m_allocator; + + std::shared_ptr m_impl; + }; + + StreamingOperationImpl::StreamingOperationImpl( + struct aws_mqtt_rr_client_operation *stream, + const StreamingOperationOptionsInternal &options, + struct aws_event_loop *protocolLoop) + : m_config(options), m_stream(stream), m_protocolLoop(protocolLoop), m_lock(), m_closed(false) + { + aws_rw_lock_init(&m_lock); + } + + StreamingOperationImpl::~StreamingOperationImpl() + { + AWS_FATAL_ASSERT(m_stream == nullptr); + AWS_FATAL_ASSERT(m_closed); + + aws_rw_lock_clean_up(&m_lock); + } + + void StreamingOperationImpl::Open() + { + { + StreamReadLock rlock(&m_lock); + + if (!m_closed) + { + aws_mqtt_rr_client_operation_activate(m_stream); + } + } + } + + void StreamingOperationImpl::Close() + { + struct aws_mqtt_rr_client_operation *toRelease = nullptr; + + { + StreamWriteLock wlock(&m_lock, m_protocolLoop); + + if (!m_closed) + { + m_closed = true; + toRelease = m_stream; + m_stream = nullptr; + } + } + + if (nullptr != toRelease) + { + aws_mqtt_rr_client_operation_release(toRelease); + } + } + + void StreamingOperationImpl::OnSubscriptionStatusCallback( + enum aws_rr_streaming_subscription_event_type status, + int error_code, + void *user_data) + { + + auto *handle = static_cast(user_data); + StreamingOperationImpl *impl = handle->m_impl.get(); + + { + StreamReadLock readLock(&impl->m_lock); + + if (!impl->m_closed && impl->m_config.subscriptionStatusEventHandler) + { + SubscriptionStatusEvent event; + event.WithType(SubscriptionStatusEventType(status)); + event.WithErrorCode(error_code); + + impl->m_config.subscriptionStatusEventHandler(std::move(event)); + } + } + } + + void StreamingOperationImpl::OnIncomingPublishCallback(struct aws_byte_cursor payload, void *user_data) + { + auto *handle = static_cast(user_data); + StreamingOperationImpl *impl = handle->m_impl.get(); + + { + StreamReadLock readLock(&impl->m_lock); + + if (!impl->m_closed && impl->m_config.incomingPublishEventHandler) + { + IncomingPublishEvent event; + event.WithPayload(payload); + + impl->m_config.incomingPublishEventHandler(std::move(event)); + } + } + } + + void StreamingOperationImpl::OnTerminatedCallback(void *user_data) + { + auto *handle = static_cast(user_data); + + Aws::Crt::Delete(handle, handle->m_allocator); + } + + ////////////////////////////////////////////////////////// + + class StreamingOperation : public IStreamingOperation + { + public: + static std::shared_ptr Create( + Aws::Crt::Allocator *allocator, + const StreamingOperationOptionsInternal &options, + struct aws_mqtt_request_response_client *client); + + explicit StreamingOperation(const std::shared_ptr &impl); + virtual ~StreamingOperation(); + + virtual void Open(); + + private: + std::shared_ptr m_impl; + }; + + StreamingOperation::StreamingOperation(const std::shared_ptr &impl) : m_impl(impl) + { + } + + std::shared_ptr StreamingOperation::Create( + Aws::Crt::Allocator *allocator, + const StreamingOperationOptionsInternal &options, + struct aws_mqtt_request_response_client *client) + { + auto *implHandle = Aws::Crt::New(allocator); + + struct aws_mqtt_streaming_operation_options streamingOptions; + AWS_ZERO_STRUCT(streamingOptions); + streamingOptions.topic_filter = options.subscriptionTopicFilter; + streamingOptions.subscription_status_callback = StreamingOperationImpl::OnSubscriptionStatusCallback; + streamingOptions.incoming_publish_callback = StreamingOperationImpl::OnIncomingPublishCallback; + streamingOptions.terminated_callback = StreamingOperationImpl::OnTerminatedCallback; + streamingOptions.user_data = implHandle; + + struct aws_mqtt_rr_client_operation *stream = + aws_mqtt_request_response_client_create_streaming_operation(client, &streamingOptions); + if (nullptr == stream) + { + Aws::Crt::Delete(implHandle, allocator); + return nullptr; + } + + auto impl = Aws::Crt::MakeShared( + allocator, stream, options, aws_mqtt_request_response_client_get_event_loop(client)); + auto streamingOperation = Aws::Crt::MakeShared(allocator, impl); + + implHandle->m_allocator = allocator; + implHandle->m_impl = impl; + + return streamingOperation; + } + + StreamingOperation::~StreamingOperation() + { + m_impl->Close(); + } + + void StreamingOperation::Open() + { + m_impl->Open(); + } + + ////////////////////////////////////////////////////////// + + struct IncompleteRequest + { + IncompleteRequest() : m_allocator(nullptr), m_handler() {} + + struct aws_allocator *m_allocator; + + UnmodeledResultHandler m_handler; + }; + + static void s_completeRequestWithError(struct IncompleteRequest *incompleteRequest, int errorCode) + { + UnmodeledResult result(errorCode); + incompleteRequest->m_handler(std::move(result)); + } + + static void s_completeRequestWithSuccess( + struct IncompleteRequest *incompleteRequest, + const struct aws_byte_cursor *response_topic, + const struct aws_byte_cursor *payload) + { + UnmodeledResponse response; + response.WithTopic(*response_topic); + response.WithPayload(*payload); + + UnmodeledResult result(response); + incompleteRequest->m_handler(std::move(result)); + } + + static void s_onRequestComplete( + const struct aws_byte_cursor *response_topic, + const struct aws_byte_cursor *payload, + int error_code, + void *user_data) + { + auto *incompleteRequest = static_cast(user_data); + + if (error_code != AWS_ERROR_SUCCESS) + { + s_completeRequestWithError(incompleteRequest, error_code); + } + else + { + s_completeRequestWithSuccess(incompleteRequest, response_topic, payload); + } + + Aws::Crt::Delete(incompleteRequest, incompleteRequest->m_allocator); + } + + class MqttRequestResponseClientImpl + { + public: + explicit MqttRequestResponseClientImpl(Aws::Crt::Allocator *allocator) noexcept; + ~MqttRequestResponseClientImpl(); + + void SeatClient(struct aws_mqtt_request_response_client *client); + + void Close() noexcept; + + int SubmitRequest( + const aws_mqtt_request_operation_options &requestOptions, + UnmodeledResultHandler &&resultHandler) noexcept; + + std::shared_ptr CreateStream(const StreamingOperationOptionsInternal &options); + + Aws::Crt::Allocator *GetAllocator() const { return m_allocator; } + + private: + Aws::Crt::Allocator *m_allocator; + + struct aws_mqtt_request_response_client *m_client; + }; + + MqttRequestResponseClientImpl::MqttRequestResponseClientImpl(Aws::Crt::Allocator *allocator) noexcept + : m_allocator(allocator), m_client(nullptr) + { + } + + MqttRequestResponseClientImpl::~MqttRequestResponseClientImpl() + { + AWS_FATAL_ASSERT(m_client == nullptr); + } + + void MqttRequestResponseClientImpl::SeatClient(struct aws_mqtt_request_response_client *client) + { + m_client = client; + } + + void MqttRequestResponseClientImpl::Close() noexcept + { + aws_mqtt_request_response_client_release(m_client); + m_client = nullptr; + } + + int MqttRequestResponseClientImpl::SubmitRequest( + const aws_mqtt_request_operation_options &requestOptions, + UnmodeledResultHandler &&resultHandler) noexcept + { + auto *incompleteRequest = Aws::Crt::New(m_allocator); + incompleteRequest->m_allocator = m_allocator; + incompleteRequest->m_handler = std::move(resultHandler); + + struct aws_mqtt_request_operation_options rawOptions = requestOptions; + rawOptions.completion_callback = s_onRequestComplete; + rawOptions.user_data = incompleteRequest; + + int result = aws_mqtt_request_response_client_submit_request(m_client, &rawOptions); + if (result != AWS_OP_SUCCESS) + { + Aws::Crt::Delete(incompleteRequest, incompleteRequest->m_allocator); + } + + return result; + } + + std::shared_ptr MqttRequestResponseClientImpl::CreateStream( + const StreamingOperationOptionsInternal &options) + { + return StreamingOperation::Create(m_allocator, options, m_client); + } + + ////////////////////////////////////////////////////////// + + static void s_onClientTermination(void *user_data) + { + auto *impl = static_cast(user_data); + + Aws::Crt::Delete(impl, impl->GetAllocator()); + } + + class MqttRequestResponseClient : public IMqttRequestResponseClient + { + public: + explicit MqttRequestResponseClient(MqttRequestResponseClientImpl *impl); + virtual ~MqttRequestResponseClient(); + + int SubmitRequest( + const aws_mqtt_request_operation_options &requestOptions, + UnmodeledResultHandler &&resultHandler) override; + + std::shared_ptr CreateStream( + const StreamingOperationOptionsInternal &options) override; + + private: + MqttRequestResponseClientImpl *m_impl; + }; + + int MqttRequestResponseClient::SubmitRequest( + const aws_mqtt_request_operation_options &requestOptions, + UnmodeledResultHandler &&resultHandler) + { + return m_impl->SubmitRequest(requestOptions, std::move(resultHandler)); + } + + std::shared_ptr MqttRequestResponseClient::CreateStream( + const StreamingOperationOptionsInternal &options) + { + return m_impl->CreateStream(options); + } + + MqttRequestResponseClient::MqttRequestResponseClient(MqttRequestResponseClientImpl *impl) : m_impl(impl) {} + + MqttRequestResponseClient::~MqttRequestResponseClient() + { + m_impl->Close(); + } + + std::shared_ptr NewClientFrom5( + const Aws::Crt::Mqtt5::Mqtt5Client &protocolClient, + const RequestResponseClientOptions &options, + Aws::Crt::Allocator *allocator) + { + auto *clientImpl = Aws::Crt::New(allocator, allocator); + + struct aws_mqtt_request_response_client_options rrClientOptions; + AWS_ZERO_STRUCT(rrClientOptions); + rrClientOptions.max_request_response_subscriptions = options.GetMaxRequestResponseSubscriptions(); + rrClientOptions.max_streaming_subscriptions = options.GetMaxStreamingSubscriptions(); + rrClientOptions.operation_timeout_seconds = options.GetOperationTimeoutInSeconds(); + rrClientOptions.terminated_callback = s_onClientTermination; + rrClientOptions.user_data = clientImpl; + + struct aws_mqtt_request_response_client *rrClient = + aws_mqtt_request_response_client_new_from_mqtt5_client( + allocator, protocolClient.GetUnderlyingHandle(), &rrClientOptions); + if (nullptr == rrClient) + { + Aws::Crt::Delete(clientImpl, clientImpl->GetAllocator()); + return nullptr; + } + + clientImpl->SeatClient(rrClient); + + return Aws::Crt::MakeShared(allocator, clientImpl); + } + + std::shared_ptr NewClientFrom311( + const Aws::Crt::Mqtt::MqttConnection &protocolClient, + const RequestResponseClientOptions &options, + Aws::Crt::Allocator *allocator) + { + auto *clientImpl = Aws::Crt::New(allocator, allocator); + + struct aws_mqtt_request_response_client_options rrClientOptions; + AWS_ZERO_STRUCT(rrClientOptions); + rrClientOptions.max_request_response_subscriptions = options.GetMaxRequestResponseSubscriptions(); + rrClientOptions.max_streaming_subscriptions = options.GetMaxStreamingSubscriptions(); + rrClientOptions.operation_timeout_seconds = options.GetOperationTimeoutInSeconds(); + rrClientOptions.terminated_callback = s_onClientTermination; + rrClientOptions.user_data = clientImpl; + + struct aws_mqtt_request_response_client *rrClient = + aws_mqtt_request_response_client_new_from_mqtt311_client( + allocator, protocolClient.GetUnderlyingConnection(), &rrClientOptions); + if (nullptr == rrClient) + { + Aws::Crt::Delete(clientImpl, clientImpl->GetAllocator()); + return nullptr; + } + + clientImpl->SeatClient(rrClient); + + return Aws::Crt::MakeShared(allocator, clientImpl); + } + } // namespace RequestResponse + } // namespace Iot +} // namespace Aws diff --git a/source/mqtt/Mqtt5Client.cpp b/source/mqtt/Mqtt5Client.cpp index fbc75c098..4d40eb7f1 100644 --- a/source/mqtt/Mqtt5Client.cpp +++ b/source/mqtt/Mqtt5Client.cpp @@ -174,6 +174,11 @@ namespace Aws return m_operationStatistics; } + struct aws_mqtt5_client *Mqtt5Client::GetUnderlyingHandle() const noexcept + { + return m_client_core->GetUnderlyingHandle(); + } + /***************************************************** * * Mqtt5ClientOptions diff --git a/source/mqtt/MqttConnection.cpp b/source/mqtt/MqttConnection.cpp index c65729289..043c3123a 100644 --- a/source/mqtt/MqttConnection.cpp +++ b/source/mqtt/MqttConnection.cpp @@ -194,7 +194,7 @@ namespace Aws return m_connectionCore->Disconnect(); } - aws_mqtt_client_connection *MqttConnection::GetUnderlyingConnection() noexcept + aws_mqtt_client_connection *MqttConnection::GetUnderlyingConnection() const noexcept { AWS_ASSERT(m_connectionCore != nullptr); return m_connectionCore->GetUnderlyingConnection(); diff --git a/source/mqtt/MqttConnectionCore.cpp b/source/mqtt/MqttConnectionCore.cpp index 96b0f46dd..a360dfd04 100644 --- a/source/mqtt/MqttConnectionCore.cpp +++ b/source/mqtt/MqttConnectionCore.cpp @@ -669,7 +669,7 @@ namespace Aws m_underlyingConnection, MqttConnectionCore::s_onDisconnect, this) == AWS_OP_SUCCESS; } - aws_mqtt_client_connection *MqttConnectionCore::GetUnderlyingConnection() noexcept + aws_mqtt_client_connection *MqttConnectionCore::GetUnderlyingConnection() const noexcept { return m_underlyingConnection; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index dfdc36083..66be8d9e7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -260,6 +260,38 @@ if(NOT BYO_CRYPTO) add_net_test_case(Mqtt5to3AdapterOperations) add_net_test_case(Mqtt5to3AdapterNullPubAck) add_net_test_case(Mqtt5to3AdapterMultipleAdapters) + + # Mqtt Request-Response + add_net_test_case(MqttRequestResponse_CreateDestroy5) + add_net_test_case(MqttRequestResponse_CreateDestroy311) + add_net_test_case(MqttRequestResponse_GetNamedShadowSuccessRejected311) + add_net_test_case(MqttRequestResponse_GetNamedShadowSuccessRejected5) + add_net_test_case(MqttRequestResponse_GetNamedShadowSuccessRejectedNoCorrelationToken311) + add_net_test_case(MqttRequestResponse_GetNamedShadowSuccessRejectedNoCorrelationToken5) + add_net_test_case(MqttRequestResponse_UpdateNamedShadowSuccessAccepted311) + add_net_test_case(MqttRequestResponse_UpdateNamedShadowSuccessAccepted5) + add_net_test_case(MqttRequestResponse_UpdateNamedShadowSuccessAcceptedNoCorrelationToken311) + add_net_test_case(MqttRequestResponse_UpdateNamedShadowSuccessAcceptedNoCorrelationToken5) + add_net_test_case(MqttRequestResponse_GetNamedShadowTimeout311) + add_net_test_case(MqttRequestResponse_GetNamedShadowTimeout5) + add_net_test_case(MqttRequestResponse_GetNamedShadowTimeoutNoCorrelationToken311) + add_net_test_case(MqttRequestResponse_GetNamedShadowTimeoutNoCorrelationToken5) + add_net_test_case(MqttRequestResponse_GetNamedShadowFailureOnClose311) + add_net_test_case(MqttRequestResponse_GetNamedShadowFailureOnClose5) + add_net_test_case(MqttRequestResponse_GetNamedShadowFailureOnCloseNoCorrelationToken311) + add_net_test_case(MqttRequestResponse_GetNamedShadowFailureOnCloseNoCorrelationToken5) + + add_net_test_case(MqttRequestResponse_ShadowUpdatedStreamOpenCloseSuccess5) + add_net_test_case(MqttRequestResponse_ShadowUpdatedStreamOpenCloseSuccess311) + add_net_test_case(MqttRequestResponse_ShadowUpdatedStreamClientClosed5) + add_net_test_case(MqttRequestResponse_ShadowUpdatedStreamClientClosed311) + add_net_test_case(MqttRequestResponse_ShadowUpdatedStreamIncomingPublishSuccess5) + add_net_test_case(MqttRequestResponse_ShadowUpdatedStreamIncomingPublishSuccess311) + + + + + endif() add_test_case(RuleEngine) diff --git a/tests/MqttRequestResponse.cpp b/tests/MqttRequestResponse.cpp new file mode 100644 index 000000000..bf02f29fc --- /dev/null +++ b/tests/MqttRequestResponse.cpp @@ -0,0 +1,1099 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +enum ProtocolType +{ + Mqtt5, + Mqtt311 +}; + +AWS_STATIC_STRING_FROM_LITERAL(s_rrEnvVariableHost, "AWS_TEST_MQTT5_IOT_CORE_HOST"); +AWS_STATIC_STRING_FROM_LITERAL(s_rrEnvVariableCertificatePath, "AWS_TEST_MQTT5_IOT_CORE_RSA_CERT"); +AWS_STATIC_STRING_FROM_LITERAL(s_rrEnvVariablePrivateKeyPath, "AWS_TEST_MQTT5_IOT_CORE_RSA_KEY"); + +struct TestState; + +struct ResponseTracker +{ + ResponseTracker() : state(nullptr), topic(), payload(), errorCode(AWS_ERROR_SUCCESS), complete(false) {} + + TestState *state; + Aws::Crt::String topic; + Aws::Crt::String payload; + int errorCode; + bool complete; +}; + +struct TestState +{ + TestState(Aws::Crt::Allocator *allocator) : allocator(allocator) {} + + Aws::Crt::Allocator *allocator; + + std::mutex lock; + std::condition_variable signal; + + bool connected = false; + + Aws::Crt::Vector> responseTrackers; + + Aws::Crt::Vector subscriptionStatusEvents; + Aws::Crt::Vector incomingPublishEvents; +}; + +static void s_waitForConnected(struct TestState *state) +{ + { + std::unique_lock lock(state->lock); + state->signal.wait(lock, [state] { return state->connected; }); + } +} + +static void s_updateConnected(struct TestState *state, bool connected) +{ + { + std::lock_guard lock(state->lock); + state->connected = connected; + } + state->signal.notify_one(); +} + +static std::shared_ptr s_addResponseTracker(TestState *state) +{ + std::shared_ptr tracker = Aws::Crt::MakeShared(state->allocator); + tracker->state = state; + { + std::unique_lock lock(state->lock); + state->responseTrackers.push_back(tracker); + } + + return tracker; +} + +static void s_waitForResponse(ResponseTracker *responseTracker) +{ + TestState *state = responseTracker->state; + { + std::unique_lock lock(state->lock); + state->signal.wait(lock, [responseTracker] { return responseTracker->complete; }); + } +} + +static void s_completeResponseWithSuccess( + ResponseTracker *responseTracker, + Aws::Crt::ByteCursor topic, + Aws::Crt::ByteCursor payload) +{ + TestState *state = responseTracker->state; + { + std::unique_lock lock(state->lock); + responseTracker->topic = Aws::Crt::String((const char *)topic.ptr, topic.len); + responseTracker->payload.assign((const uint8_t *)payload.ptr, (const uint8_t *)payload.ptr + payload.len); + responseTracker->complete = true; + } + state->signal.notify_one(); +} + +static void s_completeResponseWithError(ResponseTracker *responseTracker, int errorCode) +{ + TestState *state = responseTracker->state; + { + std::unique_lock lock(state->lock); + responseTracker->errorCode = errorCode; + responseTracker->complete = true; + } + state->signal.notify_one(); +} + +static void s_onRequestComplete(Aws::Iot::RequestResponse::UnmodeledResult &&result, ResponseTracker *responseTracker) +{ + if (result.IsSuccess()) + { + const auto &response = result.GetResponse(); + s_completeResponseWithSuccess(responseTracker, response.GetTopic(), response.GetPayload()); + } + else + { + s_completeResponseWithError(responseTracker, result.GetError()); + } +} + +static void s_onSubscriptionStatusEvent(Aws::Iot::RequestResponse::SubscriptionStatusEvent &&event, TestState *state) +{ + { + std::unique_lock lock(state->lock); + state->subscriptionStatusEvents.push_back(event); + } + state->signal.notify_one(); +} + +static void s_waitForSubscriptionStatusEvent( + TestState *state, + Aws::Iot::RequestResponse::SubscriptionStatusEventType type, + int errorCode) +{ + { + std::unique_lock lock(state->lock); + state->signal.wait( + lock, + [=]() + { + return std::any_of( + state->subscriptionStatusEvents.cbegin(), + state->subscriptionStatusEvents.cend(), + [=](const Aws::Iot::RequestResponse::SubscriptionStatusEvent &event) + { return event.GetType() == type && event.GetErrorCode() == errorCode; }); + }); + } +} + +static void s_onIncomingPublishEvent(Aws::Iot::RequestResponse::IncomingPublishEvent &&event, TestState *state) +{ + { + std::unique_lock lock(state->lock); + + auto payloadCursor = event.GetPayload(); + Aws::Crt::String payloadAsString((const char *)payloadCursor.ptr, payloadCursor.len); + + state->incomingPublishEvents.push_back(payloadAsString); + } + state->signal.notify_one(); +} + +static void s_waitForIncomingPublishWithPredicate( + TestState *state, + const std::function &predicate) +{ + { + std::unique_lock lock(state->lock); + state->signal.wait( + lock, + [=]() + { + return std::any_of( + state->incomingPublishEvents.cbegin(), + state->incomingPublishEvents.cend(), + [=](const Aws::Crt::String &payload) { return predicate(payload); }); + }); + } +} + +struct TestContext +{ + std::shared_ptr client; + std::shared_ptr protocolClient5; + std::shared_ptr protocolClient311; +}; + +static void s_startProtocolClient(TestContext &context) +{ + if (context.protocolClient5) + { + context.protocolClient5->Start(); + } + else + { + auto uuid = Aws::Crt::UUID().ToString(); + context.protocolClient311->Connect(uuid.c_str(), true, 30, 15000, 5000); + } +} + +static TestContext s_CreateClient( + Aws::Crt::Allocator *allocator, + ProtocolType protocol, + struct TestState *state, + Aws::Iot::RequestResponse::RequestResponseClientOptions *options = NULL) +{ + TestContext context; + Aws::Iot::RequestResponse::RequestResponseClientOptions finalOptions; + + struct aws_string *host = NULL; + struct aws_string *certificatePath = NULL; + struct aws_string *privateKeyPath = NULL; + + if (aws_get_environment_value(allocator, s_rrEnvVariableHost, &host) || !host) + { + goto done; + } + + if (aws_get_environment_value(allocator, s_rrEnvVariableCertificatePath, &certificatePath) || !certificatePath) + { + goto done; + } + + if (aws_get_environment_value(allocator, s_rrEnvVariablePrivateKeyPath, &privateKeyPath) || !privateKeyPath) + { + goto done; + } + + if (options != nullptr) + { + finalOptions = *options; + } + else + { + finalOptions.WithMaxRequestResponseSubscriptions(4); + finalOptions.WithMaxStreamingSubscriptions(2); + finalOptions.WithOperationTimeoutInSeconds(5); + } + + if (protocol == ProtocolType::Mqtt5) + { + Aws::Crt::Io::TlsContextOptions tlsCtxOptions = Aws::Crt::Io::TlsContextOptions::InitClientWithMtls( + aws_string_c_str(certificatePath), aws_string_c_str(privateKeyPath), allocator); + Aws::Crt::Io::TlsContext tlsContext(tlsCtxOptions, Aws::Crt::Io::TlsMode::CLIENT, allocator); + + Aws::Crt::Mqtt5::Mqtt5ClientOptions mqtt5Options(allocator); + mqtt5Options.WithHostName(Aws::Crt::String(aws_string_c_str(host))); + mqtt5Options.WithPort(8883); + mqtt5Options.WithTlsConnectionOptions(tlsContext.NewConnectionOptions()); + + mqtt5Options.WithClientConnectionSuccessCallback( + [state](const Aws::Crt::Mqtt5::OnConnectionSuccessEventData &event) + { + (void)event; + s_updateConnected(state, true); + }); + mqtt5Options.WithClientDisconnectionCallback( + [state](const Aws::Crt::Mqtt5::OnDisconnectionEventData &event) + { + (void)event; + s_updateConnected(state, false); + }); + + context.protocolClient5 = Aws::Crt::Mqtt5::Mqtt5Client::NewMqtt5Client(mqtt5Options, allocator); + context.client = Aws::Iot::RequestResponse::NewClientFrom5(*context.protocolClient5, finalOptions, allocator); + } + else + { + Aws::Crt::Io::TlsContextOptions tlsCtxOptions = Aws::Crt::Io::TlsContextOptions::InitClientWithMtls( + aws_string_c_str(certificatePath), aws_string_c_str(privateKeyPath), allocator); + Aws::Crt::Io::TlsContext tlsContext(tlsCtxOptions, Aws::Crt::Io::TlsMode::CLIENT, allocator); + + Aws::Crt::Io::SocketOptions socketOptions; + socketOptions.SetConnectTimeoutMs(3000); + + Aws::Crt::Mqtt::MqttClient client; + context.protocolClient311 = + client.NewConnection(aws_string_c_str(host), 8883, socketOptions, tlsContext, false); + + context.protocolClient311->OnConnectionSuccess = + [state](Aws::Crt::Mqtt::MqttConnection &connection, Aws::Crt::Mqtt::OnConnectionSuccessData *callbackData) + { + (void)connection; + (void)callbackData; + s_updateConnected(state, true); + }; + context.protocolClient311->OnDisconnect = [state](Aws::Crt::Mqtt::MqttConnection &connection) + { + (void)connection; + s_updateConnected(state, false); + }; + + context.client = + Aws::Iot::RequestResponse::NewClientFrom311(*context.protocolClient311, finalOptions, allocator); + } + +done: + + aws_string_destroy(host); + aws_string_destroy(certificatePath); + aws_string_destroy(privateKeyPath); + + return context; +} + +void s_publishToProtocolClient( + TestContext &context, + Aws::Crt::String topic, + Aws::Crt::String payload, + Aws::Crt::Allocator *allocator) +{ + if (context.protocolClient5) + { + auto packet = Aws::Crt::MakeShared( + allocator, + topic, + Aws::Crt::ByteCursorFromString(payload), + Aws::Crt::Mqtt5::QOS::AWS_MQTT5_QOS_AT_MOST_ONCE); + context.protocolClient5->Publish(packet); + } + else + { + Aws::Crt::ByteCursor payloadCursor = Aws::Crt::ByteCursorFromString(payload); + Aws::Crt::ByteBuf payloadBuffer; + aws_byte_buf_init_copy_from_cursor(&payloadBuffer, allocator, payloadCursor); + + context.protocolClient311->Publish( + topic.c_str(), + AWS_MQTT_QOS_AT_MOST_ONCE, + false, + payloadBuffer, + [](Aws::Crt::Mqtt::MqttConnection &connection, uint16_t packetId, int errorCode) + { + (void)connection; + (void)packetId; + (void)errorCode; + }); + aws_byte_buf_clean_up(&payloadBuffer); + } +} + +static int s_MqttRequestResponse_CreateDestroy5(Aws::Crt::Allocator *allocator, void *) +{ + { + Aws::Crt::ApiHandle handle; + struct TestState state(allocator); + + auto context = s_CreateClient(allocator, ProtocolType::Mqtt5, &state); + if (!context.client) + { + return AWS_OP_SKIP; + } + } + + return AWS_OP_SUCCESS; +} +AWS_TEST_CASE(MqttRequestResponse_CreateDestroy5, s_MqttRequestResponse_CreateDestroy5) + +static int s_MqttRequestResponse_CreateDestroy311(Aws::Crt::Allocator *allocator, void *) +{ + { + Aws::Crt::ApiHandle handle; + struct TestState state(allocator); + + auto context = s_CreateClient(allocator, ProtocolType::Mqtt311, &state); + if (!context.client) + { + return AWS_OP_SKIP; + } + } + + return AWS_OP_SUCCESS; +} +AWS_TEST_CASE(MqttRequestResponse_CreateDestroy311, s_MqttRequestResponse_CreateDestroy311) + +static int s_SubmitGetNamedShadowRejectedRequest(TestContext &context, TestState *state, bool useCorrelationToken) +{ + std::shared_ptr tracker = s_addResponseTracker(state); + ResponseTracker *rawResponseTracker = tracker.get(); + + Aws::Crt::JsonObject jsonObject; + auto uuid = Aws::Crt::UUID().ToString(); + jsonObject.WithString("clientToken", uuid); + Aws::Crt::String payloadWithCorrelationToken = jsonObject.View().WriteCompact(true); + + auto shadowName = Aws::Crt::UUID().ToString(); + + char subscriptionTopicFilter[256]; + snprintf( + subscriptionTopicFilter, + AWS_ARRAY_SIZE(subscriptionTopicFilter), + "$aws/things/NoSuchThing/shadow/name/%s/get/+", + shadowName.c_str()); + + char acceptedTopic[256]; + snprintf( + acceptedTopic, + AWS_ARRAY_SIZE(acceptedTopic), + "$aws/things/NoSuchThing/shadow/name/%s/get/accepted", + shadowName.c_str()); + + char rejectedTopic[256]; + snprintf( + rejectedTopic, + AWS_ARRAY_SIZE(rejectedTopic), + "$aws/things/NoSuchThing/shadow/name/%s/get/rejected", + shadowName.c_str()); + + char publishTopic[256]; + snprintf( + publishTopic, AWS_ARRAY_SIZE(publishTopic), "$aws/things/NoSuchThing/shadow/name/%s/get", shadowName.c_str()); + + struct aws_mqtt_request_operation_options requestOptions; + AWS_ZERO_STRUCT(requestOptions); + + struct aws_byte_cursor subscription_topic_filters[1] = { + aws_byte_cursor_from_c_str(subscriptionTopicFilter), + }; + requestOptions.subscription_topic_filters = subscription_topic_filters; + requestOptions.subscription_topic_filter_count = 1; + + struct aws_mqtt_request_operation_response_path responsePaths[2]; + AWS_ZERO_STRUCT(responsePaths[0]); + AWS_ZERO_STRUCT(responsePaths[1]); + responsePaths[0].topic = aws_byte_cursor_from_c_str(acceptedTopic); + responsePaths[1].topic = aws_byte_cursor_from_c_str(rejectedTopic); + if (useCorrelationToken) + { + responsePaths[0].correlation_token_json_path = aws_byte_cursor_from_c_str("clientToken"); + responsePaths[1].correlation_token_json_path = aws_byte_cursor_from_c_str("clientToken"); + requestOptions.correlation_token = Aws::Crt::ByteCursorFromString(uuid); + requestOptions.serialized_request = Aws::Crt::ByteCursorFromString(payloadWithCorrelationToken); + } + else + { + requestOptions.serialized_request = aws_byte_cursor_from_c_str("{}"); + } + + requestOptions.response_paths = responsePaths; + requestOptions.response_path_count = 2; + requestOptions.publish_topic = aws_byte_cursor_from_c_str(publishTopic); + requestOptions.user_data = rawResponseTracker; + + int result = context.client->SubmitRequest( + requestOptions, + [rawResponseTracker](Aws::Iot::RequestResponse::UnmodeledResult &&result) + { s_onRequestComplete(std::move(result), rawResponseTracker); }); + ASSERT_INT_EQUALS(AWS_OP_SUCCESS, result); + + s_waitForResponse(rawResponseTracker); + + { + std::lock_guard lock(state->lock); + ASSERT_INT_EQUALS(AWS_ERROR_SUCCESS, tracker->errorCode); + + ASSERT_TRUE( + tracker->topic == Aws::Crt::String((const char *)responsePaths[1].topic.ptr, responsePaths[1].topic.len)); + ASSERT_TRUE(tracker->payload.find("No shadow exists with name") != std::string::npos); + } + + return AWS_OP_SUCCESS; +} + +static int s_doGetNamedShadowSuccessRejectedTest( + Aws::Crt::Allocator *allocator, + ProtocolType protocol, + bool useCorrelationToken) +{ + + Aws::Crt::ApiHandle handle; + struct TestState state(allocator); + + auto context = s_CreateClient(allocator, protocol, &state); + if (!context.client) + { + return AWS_OP_SKIP; + } + + s_startProtocolClient(context); + s_waitForConnected(&state); + + return s_SubmitGetNamedShadowRejectedRequest(context, &state, useCorrelationToken); +} + +static int s_MqttRequestResponse_GetNamedShadowSuccessRejected311(Aws::Crt::Allocator *allocator, void *) +{ + return s_doGetNamedShadowSuccessRejectedTest(allocator, ProtocolType::Mqtt311, true); +} +AWS_TEST_CASE( + MqttRequestResponse_GetNamedShadowSuccessRejected311, + s_MqttRequestResponse_GetNamedShadowSuccessRejected311) + +static int s_MqttRequestResponse_GetNamedShadowSuccessRejected5(Aws::Crt::Allocator *allocator, void *) +{ + return s_doGetNamedShadowSuccessRejectedTest(allocator, ProtocolType::Mqtt5, true); +} +AWS_TEST_CASE(MqttRequestResponse_GetNamedShadowSuccessRejected5, s_MqttRequestResponse_GetNamedShadowSuccessRejected5) + +static int s_MqttRequestResponse_GetNamedShadowSuccessRejectedNoCorrelationToken311( + Aws::Crt::Allocator *allocator, + void *) +{ + return s_doGetNamedShadowSuccessRejectedTest(allocator, ProtocolType::Mqtt311, false); +} +AWS_TEST_CASE( + MqttRequestResponse_GetNamedShadowSuccessRejectedNoCorrelationToken311, + s_MqttRequestResponse_GetNamedShadowSuccessRejectedNoCorrelationToken311) + +static int s_MqttRequestResponse_GetNamedShadowSuccessRejectedNoCorrelationToken5( + Aws::Crt::Allocator *allocator, + void *) +{ + return s_doGetNamedShadowSuccessRejectedTest(allocator, ProtocolType::Mqtt5, false); +} +AWS_TEST_CASE( + MqttRequestResponse_GetNamedShadowSuccessRejectedNoCorrelationToken5, + s_MqttRequestResponse_GetNamedShadowSuccessRejectedNoCorrelationToken5) + +static int s_SubmitUpdateNamedShadowAcceptedRequest(TestContext &context, TestState *state, bool useCorrelationToken) +{ + std::shared_ptr tracker = s_addResponseTracker(state); + ResponseTracker *rawResponseTracker = tracker.get(); + + auto shadowName = Aws::Crt::UUID().ToString(); + char acceptedTopic[128]; + snprintf( + acceptedTopic, + AWS_ARRAY_SIZE(acceptedTopic), + "$aws/things/NoSuchThing/shadow/name/%s/update/accepted", + shadowName.c_str()); + char rejectedTopic[128]; + snprintf( + rejectedTopic, + AWS_ARRAY_SIZE(rejectedTopic), + "$aws/things/NoSuchThing/shadow/name/%s/update/rejected", + shadowName.c_str()); + + auto clientToken = Aws::Crt::UUID().ToString(); + auto stateToken = Aws::Crt::UUID().ToString(); + char desiredState[256]; + snprintf(desiredState, AWS_ARRAY_SIZE(desiredState), "{\"magic\":\"%s\"}", stateToken.c_str()); + + char payload[512]; + + struct aws_mqtt_request_operation_options requestOptions; + AWS_ZERO_STRUCT(requestOptions); + + struct aws_byte_cursor subscription_topic_filters[2] = { + aws_byte_cursor_from_c_str(acceptedTopic), + aws_byte_cursor_from_c_str(rejectedTopic), + }; + requestOptions.subscription_topic_filters = subscription_topic_filters; + requestOptions.subscription_topic_filter_count = 2; + + struct aws_mqtt_request_operation_response_path responsePaths[2]; + AWS_ZERO_STRUCT(responsePaths[0]); + AWS_ZERO_STRUCT(responsePaths[1]); + responsePaths[0].topic = aws_byte_cursor_from_c_str(acceptedTopic); + responsePaths[1].topic = aws_byte_cursor_from_c_str(rejectedTopic); + if (useCorrelationToken) + { + responsePaths[0].correlation_token_json_path = aws_byte_cursor_from_c_str("clientToken"); + responsePaths[1].correlation_token_json_path = aws_byte_cursor_from_c_str("clientToken"); + requestOptions.correlation_token = Aws::Crt::ByteCursorFromString(clientToken); + snprintf( + payload, + AWS_ARRAY_SIZE(payload), + "{\"clientToken\":\"%s\",\"state\":{\"desired\":%s}}", + clientToken.c_str(), + desiredState); + } + else + { + snprintf(payload, AWS_ARRAY_SIZE(payload), "{\"state\":{\"desired\":%s}}", desiredState); + } + + requestOptions.serialized_request = aws_byte_cursor_from_c_str(payload); + + requestOptions.response_paths = responsePaths; + requestOptions.response_path_count = 2; + + char publishTopic[128]; + snprintf( + publishTopic, + AWS_ARRAY_SIZE(publishTopic), + "$aws/things/NoSuchThing/shadow/name/%s/update", + shadowName.c_str()); + + requestOptions.publish_topic = aws_byte_cursor_from_c_str(publishTopic); + requestOptions.user_data = rawResponseTracker; + + int result = context.client->SubmitRequest( + requestOptions, + [rawResponseTracker](Aws::Iot::RequestResponse::UnmodeledResult &&result) + { s_onRequestComplete(std::move(result), rawResponseTracker); }); + ASSERT_INT_EQUALS(AWS_OP_SUCCESS, result); + + s_waitForResponse(rawResponseTracker); + + { + std::lock_guard lock(state->lock); + ASSERT_INT_EQUALS(AWS_ERROR_SUCCESS, tracker->errorCode); + + ASSERT_TRUE( + tracker->topic == Aws::Crt::String((const char *)responsePaths[0].topic.ptr, responsePaths[0].topic.len)); + ASSERT_TRUE(tracker->payload.length() > 0); + } + + return AWS_OP_SUCCESS; +} + +static int s_doUpdateNamedShadowSuccessAcceptedTest( + Aws::Crt::Allocator *allocator, + ProtocolType protocol, + bool useCorrelationToken) +{ + + Aws::Crt::ApiHandle handle; + struct TestState state(allocator); + + auto context = s_CreateClient(allocator, protocol, &state); + if (!context.client) + { + return AWS_OP_SKIP; + } + + s_startProtocolClient(context); + s_waitForConnected(&state); + + return s_SubmitUpdateNamedShadowAcceptedRequest(context, &state, useCorrelationToken); +} + +static int s_MqttRequestResponse_UpdateNamedShadowSuccessAccepted311(Aws::Crt::Allocator *allocator, void *) +{ + return s_doUpdateNamedShadowSuccessAcceptedTest(allocator, ProtocolType::Mqtt311, true); +} +AWS_TEST_CASE( + MqttRequestResponse_UpdateNamedShadowSuccessAccepted311, + s_MqttRequestResponse_UpdateNamedShadowSuccessAccepted311) + +static int s_MqttRequestResponse_UpdateNamedShadowSuccessAccepted5(Aws::Crt::Allocator *allocator, void *) +{ + return s_doUpdateNamedShadowSuccessAcceptedTest(allocator, ProtocolType::Mqtt5, true); +} +AWS_TEST_CASE( + MqttRequestResponse_UpdateNamedShadowSuccessAccepted5, + s_MqttRequestResponse_UpdateNamedShadowSuccessAccepted5) + +static int s_MqttRequestResponse_UpdateNamedShadowSuccessAcceptedNoCorrelationToken311( + Aws::Crt::Allocator *allocator, + void *) +{ + return s_doUpdateNamedShadowSuccessAcceptedTest(allocator, ProtocolType::Mqtt311, false); +} +AWS_TEST_CASE( + MqttRequestResponse_UpdateNamedShadowSuccessAcceptedNoCorrelationToken311, + s_MqttRequestResponse_UpdateNamedShadowSuccessAcceptedNoCorrelationToken311) + +static int s_MqttRequestResponse_UpdateNamedShadowSuccessAcceptedNoCorrelationToken5( + Aws::Crt::Allocator *allocator, + void *) +{ + return s_doUpdateNamedShadowSuccessAcceptedTest(allocator, ProtocolType::Mqtt5, false); +} +AWS_TEST_CASE( + MqttRequestResponse_UpdateNamedShadowSuccessAcceptedNoCorrelationToken5, + s_MqttRequestResponse_UpdateNamedShadowSuccessAcceptedNoCorrelationToken5) + +static int s_SubmitGetNamedShadowTimeoutRequest(TestContext &context, TestState *state, bool useCorrelationToken) +{ + std::shared_ptr tracker = s_addResponseTracker(state); + ResponseTracker *rawResponseTracker = tracker.get(); + + Aws::Crt::JsonObject jsonObject; + auto uuid = Aws::Crt::UUID().ToString(); + jsonObject.WithString("clientToken", uuid); + Aws::Crt::String payloadWithCorrelationToken = jsonObject.View().WriteCompact(true); + + auto shadowName = Aws::Crt::UUID().ToString(); + + char subscriptionTopicFilter[256]; + snprintf( + subscriptionTopicFilter, + AWS_ARRAY_SIZE(subscriptionTopicFilter), + "$aws/things/NoSuchThing/shadow/name/%s/get/+", + shadowName.c_str()); + + char acceptedTopic[256]; + snprintf( + acceptedTopic, + AWS_ARRAY_SIZE(acceptedTopic), + "$aws/things/NoSuchThing/shadow/name/%s/get/accepted", + shadowName.c_str()); + + char rejectedTopic[256]; + snprintf( + rejectedTopic, + AWS_ARRAY_SIZE(rejectedTopic), + "$aws/things/NoSuchThing/shadow/name/%s/get/rejected", + shadowName.c_str()); + + struct aws_mqtt_request_operation_options requestOptions; + AWS_ZERO_STRUCT(requestOptions); + + struct aws_byte_cursor subscription_topic_filters[1] = { + aws_byte_cursor_from_c_str(subscriptionTopicFilter), + }; + requestOptions.subscription_topic_filters = subscription_topic_filters; + requestOptions.subscription_topic_filter_count = 1; + + struct aws_mqtt_request_operation_response_path responsePaths[2]; + AWS_ZERO_STRUCT(responsePaths[0]); + AWS_ZERO_STRUCT(responsePaths[1]); + responsePaths[0].topic = aws_byte_cursor_from_c_str(acceptedTopic); + responsePaths[1].topic = aws_byte_cursor_from_c_str(rejectedTopic); + if (useCorrelationToken) + { + responsePaths[0].correlation_token_json_path = aws_byte_cursor_from_c_str("clientToken"); + responsePaths[1].correlation_token_json_path = aws_byte_cursor_from_c_str("clientToken"); + requestOptions.correlation_token = Aws::Crt::ByteCursorFromString(uuid); + requestOptions.serialized_request = Aws::Crt::ByteCursorFromString(payloadWithCorrelationToken); + } + else + { + requestOptions.serialized_request = aws_byte_cursor_from_c_str("{}"); + } + + requestOptions.response_paths = responsePaths; + requestOptions.response_path_count = 2; + requestOptions.publish_topic = aws_byte_cursor_from_c_str("wrong/publish/topic"); + requestOptions.user_data = rawResponseTracker; + + int result = context.client->SubmitRequest( + requestOptions, + [rawResponseTracker](Aws::Iot::RequestResponse::UnmodeledResult &&result) + { s_onRequestComplete(std::move(result), rawResponseTracker); }); + ASSERT_INT_EQUALS(AWS_OP_SUCCESS, result); + + s_waitForResponse(rawResponseTracker); + + { + std::lock_guard lock(state->lock); + ASSERT_INT_EQUALS(AWS_ERROR_MQTT_REQUEST_RESPONSE_TIMEOUT, tracker->errorCode); + ASSERT_TRUE(tracker->topic.empty()); + ASSERT_TRUE(tracker->payload.empty()); + } + + return AWS_OP_SUCCESS; +} + +static int s_doGetNamedShadowTimeoutTest( + Aws::Crt::Allocator *allocator, + ProtocolType protocol, + bool useCorrelationToken) +{ + Aws::Iot::RequestResponse::RequestResponseClientOptions clientOptions; + clientOptions.WithMaxRequestResponseSubscriptions(4); + clientOptions.WithMaxStreamingSubscriptions(2); + clientOptions.WithOperationTimeoutInSeconds(3); + + Aws::Crt::ApiHandle handle; + struct TestState state(allocator); + + auto context = s_CreateClient(allocator, protocol, &state, &clientOptions); + if (!context.client) + { + return AWS_OP_SKIP; + } + + s_startProtocolClient(context); + s_waitForConnected(&state); + + return s_SubmitGetNamedShadowTimeoutRequest(context, &state, useCorrelationToken); +} + +static int s_MqttRequestResponse_GetNamedShadowTimeout311(Aws::Crt::Allocator *allocator, void *) +{ + return s_doGetNamedShadowTimeoutTest(allocator, ProtocolType::Mqtt311, true); +} +AWS_TEST_CASE(MqttRequestResponse_GetNamedShadowTimeout311, s_MqttRequestResponse_GetNamedShadowTimeout311) + +static int s_MqttRequestResponse_GetNamedShadowTimeout5(Aws::Crt::Allocator *allocator, void *) +{ + return s_doGetNamedShadowTimeoutTest(allocator, ProtocolType::Mqtt5, true); +} +AWS_TEST_CASE(MqttRequestResponse_GetNamedShadowTimeout5, s_MqttRequestResponse_GetNamedShadowTimeout5) + +static int s_MqttRequestResponse_GetNamedShadowTimeoutNoCorrelationToken311(Aws::Crt::Allocator *allocator, void *) +{ + return s_doGetNamedShadowTimeoutTest(allocator, ProtocolType::Mqtt311, false); +} +AWS_TEST_CASE( + MqttRequestResponse_GetNamedShadowTimeoutNoCorrelationToken311, + s_MqttRequestResponse_GetNamedShadowTimeoutNoCorrelationToken311) + +static int s_MqttRequestResponse_GetNamedShadowTimeoutNoCorrelationToken5(Aws::Crt::Allocator *allocator, void *) +{ + return s_doGetNamedShadowTimeoutTest(allocator, ProtocolType::Mqtt5, false); +} +AWS_TEST_CASE( + MqttRequestResponse_GetNamedShadowTimeoutNoCorrelationToken5, + s_MqttRequestResponse_GetNamedShadowTimeoutNoCorrelationToken5) + +static int s_SubmitGetNamedShadowFailureOnCloseRequest(TestContext &context, TestState *state, bool useCorrelationToken) +{ + std::shared_ptr tracker = s_addResponseTracker(state); + ResponseTracker *rawResponseTracker = tracker.get(); + + Aws::Crt::JsonObject jsonObject; + auto uuid = Aws::Crt::UUID().ToString(); + jsonObject.WithString("clientToken", uuid); + Aws::Crt::String payloadWithCorrelationToken = jsonObject.View().WriteCompact(true); + + struct aws_mqtt_request_operation_options requestOptions; + AWS_ZERO_STRUCT(requestOptions); + + struct aws_byte_cursor subscription_topic_filters[1] = { + aws_byte_cursor_from_c_str("$aws/things/NoSuchThing/shadow/name/Derp/get/+"), + }; + requestOptions.subscription_topic_filters = subscription_topic_filters; + requestOptions.subscription_topic_filter_count = 1; + + struct aws_mqtt_request_operation_response_path responsePaths[2]; + AWS_ZERO_STRUCT(responsePaths[0]); + AWS_ZERO_STRUCT(responsePaths[1]); + responsePaths[0].topic = aws_byte_cursor_from_c_str("$aws/things/NoSuchThing/shadow/name/Derp/get/accepted"); + responsePaths[1].topic = aws_byte_cursor_from_c_str("$aws/things/NoSuchThing/shadow/name/Derp/get/rejected"); + if (useCorrelationToken) + { + responsePaths[0].correlation_token_json_path = aws_byte_cursor_from_c_str("clientToken"); + responsePaths[1].correlation_token_json_path = aws_byte_cursor_from_c_str("clientToken"); + requestOptions.correlation_token = Aws::Crt::ByteCursorFromString(uuid); + requestOptions.serialized_request = Aws::Crt::ByteCursorFromString(payloadWithCorrelationToken); + } + else + { + requestOptions.serialized_request = aws_byte_cursor_from_c_str("{}"); + } + + requestOptions.response_paths = responsePaths; + requestOptions.response_path_count = 2; + requestOptions.publish_topic = aws_byte_cursor_from_c_str("wrong/publish/topic"); + requestOptions.user_data = rawResponseTracker; + + int result = context.client->SubmitRequest( + requestOptions, + [rawResponseTracker](Aws::Iot::RequestResponse::UnmodeledResult &&result) + { s_onRequestComplete(std::move(result), rawResponseTracker); }); + ASSERT_INT_EQUALS(AWS_OP_SUCCESS, result); + + context.client = nullptr; + + s_waitForResponse(rawResponseTracker); + + { + std::lock_guard lock(state->lock); + ASSERT_INT_EQUALS(AWS_ERROR_MQTT_REQUEST_RESPONSE_CLIENT_SHUT_DOWN, tracker->errorCode); + ASSERT_TRUE(tracker->topic.empty()); + ASSERT_TRUE(tracker->payload.empty()); + } + + return AWS_OP_SUCCESS; +} + +static int s_doGetNamedShadowFailureOnClosedTest( + Aws::Crt::Allocator *allocator, + ProtocolType protocol, + bool useCorrelationToken) +{ + Aws::Crt::ApiHandle handle; + struct TestState state(allocator); + + auto context = s_CreateClient(allocator, protocol, &state); + if (!context.client) + { + return AWS_OP_SKIP; + } + + s_startProtocolClient(context); + s_waitForConnected(&state); + + return s_SubmitGetNamedShadowFailureOnCloseRequest(context, &state, useCorrelationToken); +} + +static int s_MqttRequestResponse_GetNamedShadowFailureOnClose311(Aws::Crt::Allocator *allocator, void *) +{ + return s_doGetNamedShadowFailureOnClosedTest(allocator, ProtocolType::Mqtt311, true); +} +AWS_TEST_CASE( + MqttRequestResponse_GetNamedShadowFailureOnClose311, + s_MqttRequestResponse_GetNamedShadowFailureOnClose311) + +static int s_MqttRequestResponse_GetNamedShadowFailureOnClose5(Aws::Crt::Allocator *allocator, void *) +{ + return s_doGetNamedShadowFailureOnClosedTest(allocator, ProtocolType::Mqtt5, true); +} +AWS_TEST_CASE(MqttRequestResponse_GetNamedShadowFailureOnClose5, s_MqttRequestResponse_GetNamedShadowFailureOnClose5) + +static int s_MqttRequestResponse_GetNamedShadowFailureOnCloseNoCorrelationToken311( + Aws::Crt::Allocator *allocator, + void *) +{ + return s_doGetNamedShadowFailureOnClosedTest(allocator, ProtocolType::Mqtt311, false); +} +AWS_TEST_CASE( + MqttRequestResponse_GetNamedShadowFailureOnCloseNoCorrelationToken311, + s_MqttRequestResponse_GetNamedShadowFailureOnCloseNoCorrelationToken311) + +static int s_MqttRequestResponse_GetNamedShadowFailureOnCloseNoCorrelationToken5(Aws::Crt::Allocator *allocator, void *) +{ + return s_doGetNamedShadowFailureOnClosedTest(allocator, ProtocolType::Mqtt5, false); +} +AWS_TEST_CASE( + MqttRequestResponse_GetNamedShadowFailureOnCloseNoCorrelationToken5, + s_MqttRequestResponse_GetNamedShadowFailureOnCloseNoCorrelationToken5) + +static std::shared_ptr s_CreateValidStream( + TestContext &context, + TestState *state, + const Aws::Crt::String &topicFilter) +{ + Aws::Iot::RequestResponse::StreamingOperationOptionsInternal config; + + config.subscriptionStatusEventHandler = [state](Aws::Iot::RequestResponse::SubscriptionStatusEvent &&event) + { s_onSubscriptionStatusEvent(std::move(event), state); }; + config.incomingPublishEventHandler = [state](Aws::Iot::RequestResponse::IncomingPublishEvent &&event) + { s_onIncomingPublishEvent(std::move(event), state); }; + + config.subscriptionTopicFilter = aws_byte_cursor_from_c_str(topicFilter.c_str()); + + return context.client->CreateStream(config); +} + +static int s_doShadowUpdatedStreamOpenCloseSuccessTest(Aws::Crt::Allocator *allocator, ProtocolType protocol) +{ + Aws::Crt::ApiHandle handle; + struct TestState state(allocator); + + auto context = s_CreateClient(allocator, protocol, &state); + if (!context.client) + { + return AWS_OP_SKIP; + } + + s_startProtocolClient(context); + s_waitForConnected(&state); + + auto uuid = Aws::Crt::UUID().ToString(); + auto stream = s_CreateValidStream(context, &state, uuid); + ASSERT_NOT_NULL(stream.get()); + + stream->Open(); + + s_waitForSubscriptionStatusEvent( + &state, Aws::Iot::RequestResponse::SubscriptionStatusEventType::SubscriptionEstablished, AWS_ERROR_SUCCESS); + + stream = nullptr; + + return AWS_OP_SUCCESS; +} + +static int s_MqttRequestResponse_ShadowUpdatedStreamOpenCloseSuccess5(Aws::Crt::Allocator *allocator, void *) +{ + return s_doShadowUpdatedStreamOpenCloseSuccessTest(allocator, ProtocolType::Mqtt5); +} +AWS_TEST_CASE( + MqttRequestResponse_ShadowUpdatedStreamOpenCloseSuccess5, + s_MqttRequestResponse_ShadowUpdatedStreamOpenCloseSuccess5) + +static int s_MqttRequestResponse_ShadowUpdatedStreamOpenCloseSuccess311(Aws::Crt::Allocator *allocator, void *) +{ + return s_doShadowUpdatedStreamOpenCloseSuccessTest(allocator, ProtocolType::Mqtt311); +} +AWS_TEST_CASE( + MqttRequestResponse_ShadowUpdatedStreamOpenCloseSuccess311, + s_MqttRequestResponse_ShadowUpdatedStreamOpenCloseSuccess311) + +static int s_doShadowUpdatedStreamOpenCloseClientTest(Aws::Crt::Allocator *allocator, ProtocolType protocol) +{ + Aws::Crt::ApiHandle handle; + std::shared_ptr stream = nullptr; + + struct TestState state(allocator); + + auto context = s_CreateClient(allocator, protocol, &state); + if (!context.client) + { + return AWS_OP_SKIP; + } + + s_startProtocolClient(context); + s_waitForConnected(&state); + + auto uuid = Aws::Crt::UUID().ToString(); + stream = s_CreateValidStream(context, &state, uuid); + ASSERT_NOT_NULL(stream.get()); + + stream->Open(); + + s_waitForSubscriptionStatusEvent( + &state, Aws::Iot::RequestResponse::SubscriptionStatusEventType::SubscriptionEstablished, AWS_ERROR_SUCCESS); + + // Close all the clients. We should get a subscription halted event. + context.client = nullptr; + context.protocolClient311 = nullptr; + context.protocolClient5 = nullptr; + + s_waitForSubscriptionStatusEvent( + &state, + Aws::Iot::RequestResponse::SubscriptionStatusEventType::SubscriptionHalted, + AWS_ERROR_MQTT_REQUEST_RESPONSE_CLIENT_SHUT_DOWN); + + stream = nullptr; + + return AWS_OP_SUCCESS; +} + +static int s_MqttRequestResponse_ShadowUpdatedStreamClientClosed5(Aws::Crt::Allocator *allocator, void *) +{ + return s_doShadowUpdatedStreamOpenCloseClientTest(allocator, ProtocolType::Mqtt5); +} +AWS_TEST_CASE( + MqttRequestResponse_ShadowUpdatedStreamClientClosed5, + s_MqttRequestResponse_ShadowUpdatedStreamClientClosed5) + +static int s_MqttRequestResponse_ShadowUpdatedStreamClientClosed311(Aws::Crt::Allocator *allocator, void *) +{ + return s_doShadowUpdatedStreamOpenCloseClientTest(allocator, ProtocolType::Mqtt311); +} +AWS_TEST_CASE( + MqttRequestResponse_ShadowUpdatedStreamClientClosed311, + s_MqttRequestResponse_ShadowUpdatedStreamClientClosed311) + +static const char *s_publishPayload = "IncomingPublish"; + +static int s_doShadowUpdatedStreamIncomingPublishTest(Aws::Crt::Allocator *allocator, ProtocolType protocol) +{ + Aws::Crt::ApiHandle handle; + std::shared_ptr stream = nullptr; + + struct TestState state(allocator); + + auto context = s_CreateClient(allocator, protocol, &state); + if (!context.client) + { + return AWS_OP_SKIP; + } + + s_startProtocolClient(context); + s_waitForConnected(&state); + + auto uuid = Aws::Crt::UUID().ToString(); + stream = s_CreateValidStream(context, &state, uuid); + ASSERT_NOT_NULL(stream.get()); + + stream->Open(); + + s_waitForSubscriptionStatusEvent( + &state, Aws::Iot::RequestResponse::SubscriptionStatusEventType::SubscriptionEstablished, AWS_ERROR_SUCCESS); + + s_publishToProtocolClient(context, uuid, s_publishPayload, allocator); + + s_waitForIncomingPublishWithPredicate( + &state, [](const Aws::Crt::String &payload) { return payload == Aws::Crt::String(s_publishPayload); }); + + return AWS_OP_SUCCESS; +} + +static int s_MqttRequestResponse_ShadowUpdatedStreamIncomingPublishSuccess5(Aws::Crt::Allocator *allocator, void *) +{ + return s_doShadowUpdatedStreamIncomingPublishTest(allocator, ProtocolType::Mqtt5); +} +AWS_TEST_CASE( + MqttRequestResponse_ShadowUpdatedStreamIncomingPublishSuccess5, + s_MqttRequestResponse_ShadowUpdatedStreamIncomingPublishSuccess5) + +static int s_MqttRequestResponse_ShadowUpdatedStreamIncomingPublishSuccess311(Aws::Crt::Allocator *allocator, void *) +{ + return s_doShadowUpdatedStreamIncomingPublishTest(allocator, ProtocolType::Mqtt311); +} +AWS_TEST_CASE( + MqttRequestResponse_ShadowUpdatedStreamIncomingPublishSuccess311, + s_MqttRequestResponse_ShadowUpdatedStreamIncomingPublishSuccess311) From 827b178c64a9d3df9684f8b75f819f08f67119f6 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Thu, 14 Nov 2024 09:38:19 -0800 Subject: [PATCH 034/126] AutoTag PR for v0.29.4 (#683) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 5540b6e00..35b1b3d1d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.29.3 +0.29.4 From 7f3046461f31b3dfbbb118c59a4751b7a92c9602 Mon Sep 17 00:00:00 2001 From: Vera Xia Date: Wed, 20 Nov 2024 09:02:01 -0800 Subject: [PATCH 035/126] Update submodule (#684) --- crt/aws-c-common | 2 +- crt/aws-c-http | 2 +- crt/aws-c-io | 2 +- crt/aws-c-s3 | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crt/aws-c-common b/crt/aws-c-common index f41b772f0..63187b976 160000 --- a/crt/aws-c-common +++ b/crt/aws-c-common @@ -1 +1 @@ -Subproject commit f41b772f0de9454a4e7a65750b58c2379533bbf1 +Subproject commit 63187b976a482309e23296c5f967fc19c4131746 diff --git a/crt/aws-c-http b/crt/aws-c-http index 74b3a0dd1..fc3eded24 160000 --- a/crt/aws-c-http +++ b/crt/aws-c-http @@ -1 +1 @@ -Subproject commit 74b3a0dd1396b72f701c8bdf24e5c6f41e52cf87 +Subproject commit fc3eded2465c37d07fd9cc15e9b5b011224c9c9a diff --git a/crt/aws-c-io b/crt/aws-c-io index e247ef89c..fcb38c804 160000 --- a/crt/aws-c-io +++ b/crt/aws-c-io @@ -1 +1 @@ -Subproject commit e247ef89cdf170cadcb4c665fb0146e82cd6e135 +Subproject commit fcb38c804364dd627c335da752a99a125a88f6e9 diff --git a/crt/aws-c-s3 b/crt/aws-c-s3 index 8c1969bce..5877f40f8 160000 --- a/crt/aws-c-s3 +++ b/crt/aws-c-s3 @@ -1 +1 @@ -Subproject commit 8c1969bce5bfe0e063cbc719182dbe344342b880 +Subproject commit 5877f40f87c77ccf2b278839995a6ee91983080f From 9ffe4ef8df4dcfdccb6eba7fa79590a84b29f29e Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Wed, 20 Nov 2024 09:05:40 -0800 Subject: [PATCH 036/126] AutoTag PR for v0.29.5 (#685) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 35b1b3d1d..88f8ee85d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.29.4 +0.29.5 From 5478ce2cf9f2a36b3493b1dccd7b4487e17dc2a0 Mon Sep 17 00:00:00 2001 From: Michael Graeb Date: Wed, 27 Nov 2024 16:39:35 -0800 Subject: [PATCH 037/126] Fix crash when building with _GLIBCXX_USE_CXX11_ABI=0 (#686) **Issue:** A user had been building aws-crt-cpp with `CXXFLAGS=-D_GLIBCXX_USE_CXX11_ABI=0`, and that worked fine until the recent change where we started hiding symbols by default (PR https://github.com/awslabs/aws-crt-cpp/pull/666) With symbols hidden by default, and `_GLIBCXX_USE_CXX11_ABI=0`, tests would crash in the destructor of `Aws::Crt::String` (which is `std::string` with a custom allocator). **Description of changes:** Don't hide symbols when building for the ancient glibcxx ABI. I don't 100% understand why this fixes the issue, but the situation is esoteric enough that it doesn't seem worth spending more days on this problem. **Background** See: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html GCC had to introduce a new ABI for C++11 which removed the copy-on-write optimization for strings, which is forbidden in C++11 and later (new ABI uses a small-string optimization instead). But GCC let users manually set `_GLIBCXX_USE_CXX11_ABI=0` so they could opt back into the old ABI and continue working with libraries compiled for C++03. I don't think GCC intended devs to continue using this 10 years later, but some people are, because the old copy-on-write optimization has less memory usage. --- .github/workflows/ci.yml | 10 +++++++++- CMakeLists.txt | 16 +++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 37879946f..6b7a4bf16 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ env: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true - + jobs: linux-compat-use-openssl: runs-on: ubuntu-22.04 # latest @@ -143,6 +143,14 @@ jobs: aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh ./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --compiler=${{ matrix.compiler }} --cmake-extra=-DBUILD_SHARED_LIBS=ON + linux-glibcxx-ancient-abi: + runs-on: ubuntu-24.04 # latest + steps: + - name: Build ${{ env.PACKAGE_NAME }} + run: | + aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh + ./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --compiler=gcc-11 --cmake-extra=-DBUILD_SHARED_LIBS=ON --cmake-extra=-DCMAKE_CXX_FLAGS=-D_GLIBCXX_USE_CXX11_ABI=0 + linux-openssl-static: runs-on: ubuntu-22.04 # latest steps: diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f062caa6..4127d0714 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -298,9 +298,19 @@ set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX) set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD ${CMAKE_CXX_STANDARD}) # Hide symbols by default -# Except for ancient GCC, because it leads to crashes in shared-lib builds -# see: https://github.com/awslabs/aws-crt-cpp/pull/675 -if(NOT (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0")) +# Except where it causes problems, and the situation is weird enough that it's not worth investigating further. +# +# We've seen people set _GLIBCXX_USE_CXX11_ABI=0 which forces GCC to use it's pre-C++11 string implementation, +# which leads to crashes on shared-lib builds. Search every variant of CXX_FLAGS to see if it's set. +string(FIND "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${CMAKE_CXX_FLAGS_MINSIZEREL}" + "-D_GLIBCXX_USE_CXX11_ABI=0" found_ancient_abi_flag) +if(found_ancient_abi_flag GREATER -1) + message(WARNING "_GLIBCXX_USE_CXX11_ABI=0 is set. Making all symbols visible to prevent weird crashes") +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0") + # Ancient GCC leads to crashes in shared-lib builds + # see: https://github.com/awslabs/aws-crt-cpp/pull/675 + message(WARNING "Ancient compiler (${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}). Making all symbols visible to prevent weird crashes") +else() set_target_properties(${PROJECT_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON) endif() From 57a0b8f03e11dc34b2c423519934e492ed96fa96 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Wed, 27 Nov 2024 17:18:22 -0800 Subject: [PATCH 038/126] AutoTag PR for v0.29.6 (#687) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 88f8ee85d..476163a9f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.29.5 +0.29.6 From 19f25dc94e5a730cd4350b2d9e1526e753e78ed2 Mon Sep 17 00:00:00 2001 From: Dmitriy Musatkin <63878209+DmitriyMusatkin@users.noreply.github.com> Date: Fri, 6 Dec 2024 14:46:32 -0800 Subject: [PATCH 039/126] Switch CI to using roles (#688) --- .github/workflows/ci.yml | 178 ++++++++++++++++++++++++++-------- .github/workflows/docs.yml | 2 +- .github/workflows/release.yml | 2 +- 3 files changed, 139 insertions(+), 43 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6b7a4bf16..7939a891c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,15 +7,17 @@ on: - 'docs' env: - BUILDER_VERSION: v0.9.63 + BUILDER_VERSION: v0.9.73 BUILDER_SOURCE: releases BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net PACKAGE_NAME: aws-crt-cpp LINUX_BASE_IMAGE: ubuntu-18-x64 RUN: ${{ github.run_id }}-${{ github.run_number }} - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - AWS_REGION: us-east-1 + CRT_CI_ROLE: ${{ secrets.CRT_CI_ROLE_ARN }} + AWS_DEFAULT_REGION: us-east-1 + +permissions: + id-token: write # This is required for requesting the JWT # cancel in-progress builds after a new commit concurrency: @@ -24,7 +26,7 @@ concurrency: jobs: linux-compat-use-openssl: - runs-on: ubuntu-22.04 # latest + runs-on: ubuntu-24.04 # latest strategy: matrix: image: @@ -32,6 +34,10 @@ jobs: - opensuse-leap - rhel8-x64 steps: + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Install qemu/docker run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - name: Build ${{ env.PACKAGE_NAME }} @@ -43,7 +49,7 @@ jobs: # that are up-to-date (AL2) or don't provide OpenSSL development packages that is found in CMake (alpine) # or are not able to connect on the socket even with the correct setup (manylinux2014) linux-compat: - runs-on: ubuntu-22.04 # latest + runs-on: ubuntu-24.04 # latest strategy: fail-fast: false matrix: @@ -57,6 +63,10 @@ jobs: - alpine-3.16-armv7 - alpine-3.16-arm64 steps: + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Install qemu/docker run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - name: Build ${{ env.PACKAGE_NAME }} @@ -65,7 +75,7 @@ jobs: ./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ matrix.image }} build -p ${{ env.PACKAGE_NAME }} linux-compiler-compat: - runs-on: ubuntu-22.04 # latest + runs-on: ubuntu-24.04 # latest strategy: matrix: compiler: @@ -76,6 +86,8 @@ jobs: - clang-10 - clang-11 - clang-12 + - clang-15 + - clang-17 - gcc-4.8 - gcc-5 - gcc-6 @@ -85,20 +97,28 @@ jobs: - gcc-10 - gcc-11 steps: - # We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages - - name: Build ${{ env.PACKAGE_NAME }} - run: | - aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh - ./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --compiler=${{ matrix.compiler }} --cmake-extra=-DUSE_OPENSSL=ON + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} + # We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages + - name: Build ${{ env.PACKAGE_NAME }} + run: | + aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh + ./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --compiler=${{ matrix.compiler }} --cmake-extra=-DUSE_OPENSSL=ON raspberry: - runs-on: ubuntu-22.04 # latest + runs-on: ubuntu-24.04 # latest strategy: fail-fast: false matrix: image: - raspbian-bullseye steps: + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} # set arm arch - name: Install qemu/docker run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes @@ -109,13 +129,17 @@ jobs: ./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ matrix.image }} build -p ${{ env.PACKAGE_NAME }} std-compat: - runs-on: ubuntu-22.04 # latest + runs-on: ubuntu-24.04 # latest strategy: matrix: compiler: [gcc-8, clang-9] std: [c++11, c++14, c++17, c++2a] steps: - # We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} + # We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages - name: Build ${{ env.PACKAGE_NAME }} with ${{ matrix.std }} run: | export CXXFLAGS=-std=${{ matrix.std }} @@ -123,21 +147,29 @@ jobs: ./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --compiler=${{ matrix.compiler }} --cmake-extra=-DUSE_OPENSSL=ON byo-crypto: - runs-on: ubuntu-22.04 # latest + runs-on: ubuntu-24.04 # latest steps: - # We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} + # We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages - name: Build ${{ env.PACKAGE_NAME }} run: | aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh ./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --cmake-extra=-DBYO_CRYPTO=ON --cmake-extra=-DUSE_OPENSSL=ON linux-shared-libs: - runs-on: ubuntu-22.04 # latest + runs-on: ubuntu-24.04 # latest strategy: matrix: compiler: [gcc-4.8, gcc-11] # oldest, latest steps: - # We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} + # We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages - name: Build ${{ env.PACKAGE_NAME }} run: | aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh @@ -146,33 +178,49 @@ jobs: linux-glibcxx-ancient-abi: runs-on: ubuntu-24.04 # latest steps: + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Build ${{ env.PACKAGE_NAME }} run: | aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh ./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --compiler=gcc-11 --cmake-extra=-DBUILD_SHARED_LIBS=ON --cmake-extra=-DCMAKE_CXX_FLAGS=-D_GLIBCXX_USE_CXX11_ABI=0 linux-openssl-static: - runs-on: ubuntu-22.04 # latest + runs-on: ubuntu-24.04 # latest steps: - # We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} + # We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages - name: Build ${{ env.PACKAGE_NAME }} run: | aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh ./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --variant=openssl --cmake-extra=-DUSE_OPENSSL=ON linux-openssl-shared: - runs-on: ubuntu-22.04 # latest + runs-on: ubuntu-24.04 # latest steps: - # We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} + # We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages - name: Build ${{ env.PACKAGE_NAME }} run: | aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh ./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --variant=openssl --cmake-extra=-DUSE_OPENSSL=ON --cmake-extra=-DBUILD_SHARED_LIBS=ON linux-no-cpu-extensions: - runs-on: ubuntu-22.04 # latest + runs-on: ubuntu-24.04 # latest steps: - # We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} + # We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages - name: Build ${{ env.PACKAGE_NAME }} run: | aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh @@ -181,6 +229,10 @@ jobs: windows: runs-on: windows-2022 # latest steps: + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Build ${{ env.PACKAGE_NAME }} + consumers run: | md D:\a\work @@ -194,6 +246,10 @@ jobs: matrix: arch: [x86, x64] steps: + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Build ${{ env.PACKAGE_NAME }} + consumers run: | md D:\a\work @@ -204,6 +260,10 @@ jobs: windows-shared-libs: runs-on: windows-2022 # latest steps: + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Build ${{ env.PACKAGE_NAME }} + consumers run: | md D:\a\work @@ -220,6 +280,10 @@ jobs: env: LDFLAGS: /DELAYLOAD:aws-crt-cpp.dll steps: + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Build ${{ env.PACKAGE_NAME }} + consumers run: | md D:\a\work @@ -230,6 +294,10 @@ jobs: windows-no-cpu-extensions: runs-on: windows-2022 # latest steps: + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Build ${{ env.PACKAGE_NAME }} + consumers run: | md D:\a\work @@ -240,6 +308,10 @@ jobs: macos: runs-on: macos-14 # latest steps: + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Build ${{ env.PACKAGE_NAME }} + consumers run: | python3 -c "from urllib.request import urlretrieve; urlretrieve('${{ env.BUILDER_HOST }}/${{ env.BUILDER_SOURCE }}/${{ env.BUILDER_VERSION }}/builder.pyz?run=${{ env.RUN }}', 'builder')" @@ -249,6 +321,10 @@ jobs: macos-x64: runs-on: macos-14-large # latest steps: + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Build ${{ env.PACKAGE_NAME }} + consumers run: | python3 -c "from urllib.request import urlretrieve; urlretrieve('${{ env.BUILDER_HOST }}/${{ env.BUILDER_SOURCE }}/${{ env.BUILDER_VERSION }}/builder.pyz?run=${{ env.RUN }}', 'builder')" @@ -261,6 +337,10 @@ jobs: ios-cross-compile: runs-on: macos-14 # latest steps: + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Build ${{ env.PACKAGE_NAME }} + consumers run: | python3 -c "from urllib.request import urlretrieve; urlretrieve('${{ env.BUILDER_HOST }}/${{ env.BUILDER_SOURCE }}/${{ env.BUILDER_VERSION }}/builder.pyz?run=${{ env.RUN }}', 'builder')" @@ -269,12 +349,16 @@ jobs: cross_compile: name: Cross Compile ${{matrix.arch}} - runs-on: ubuntu-22.04 # latest + runs-on: ubuntu-24.04 # latest strategy: matrix: arch: [linux-armv6, linux-armv7, linux-arm64, android-armv7] steps: + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Build ${{ env.PACKAGE_NAME }} + consumers run: | python3 -c "from urllib.request import urlretrieve; urlretrieve('${{ env.BUILDER_HOST }}/${{ env.BUILDER_SOURCE }}/${{ env.BUILDER_VERSION }}/builder.pyz?run=${{ env.RUN }}', 'builder')" @@ -283,19 +367,27 @@ jobs: # check that docs can still build check-docs: - runs-on: ubuntu-22.04 # latest + runs-on: ubuntu-24.04 # latest steps: - - uses: actions/checkout@v4 - with: - submodules: true - - name: Check docs - run: | - sudo apt-get install -y doxygen - ./make-docs.py + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} + - uses: actions/checkout@v4 + with: + submodules: true + - name: Check docs + run: | + sudo apt-get install -y doxygen + ./make-docs.py check-submodules: - runs-on: ubuntu-22.04 # latest + runs-on: ubuntu-24.04 # latest steps: + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Checkout Source uses: actions/checkout@v4 with: @@ -307,13 +399,17 @@ jobs: uses: awslabs/aws-crt-builder/.github/actions/check-submodules@main clang-sanitizers: - runs-on: ubuntu-22.04 # latest + runs-on: ubuntu-24.04 # latest strategy: matrix: sanitizers: ["thread", "address,undefined"] steps: - # We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages - - name: Build ${{ env.PACKAGE_NAME }} - run: | - aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh - ./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --compiler=clang-12 --cmake-extra=-DENABLE_SANITIZERS=ON --cmake-extra=-DSANITIZERS="${{ matrix.sanitizers }}" + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} + # We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages + - name: Build ${{ env.PACKAGE_NAME }} + run: | + aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh + ./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --compiler=clang-12 --cmake-extra=-DENABLE_SANITIZERS=ON --cmake-extra=-DSANITIZERS="${{ matrix.sanitizers }}" diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index f54eb8475..0243c1908 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -9,7 +9,7 @@ on: jobs: update-docs-branch: - runs-on: ubuntu-22.04 # latest + runs-on: ubuntu-24.04 # latest permissions: contents: write # allow push steps: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9055c4330..98cfbf0f9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,7 +6,7 @@ on: jobs: update-version: - runs-on: ubuntu-22.04 # latest + runs-on: ubuntu-24.04 # latest permissions: contents: write # allow push From 726ea9afcd4795ef96af227347416cd5d395d666 Mon Sep 17 00:00:00 2001 From: Dmitriy Musatkin <63878209+DmitriyMusatkin@users.noreply.github.com> Date: Fri, 6 Dec 2024 16:42:17 -0800 Subject: [PATCH 040/126] Bump crt deps (#689) --- crt/aws-c-cal | 2 +- crt/aws-c-common | 2 +- crt/aws-c-s3 | 2 +- crt/aws-c-sdkutils | 2 +- crt/aws-checksums | 2 +- crt/aws-lc | 2 +- crt/s2n | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crt/aws-c-cal b/crt/aws-c-cal index 656762aef..fbbe2612a 160000 --- a/crt/aws-c-cal +++ b/crt/aws-c-cal @@ -1 +1 @@ -Subproject commit 656762aefbee2bc8f509cb23cd107abff20a72bb +Subproject commit fbbe2612a3385d1ded02a52d20ad7fd2da4501f4 diff --git a/crt/aws-c-common b/crt/aws-c-common index 63187b976..fadfef492 160000 --- a/crt/aws-c-common +++ b/crt/aws-c-common @@ -1 +1 @@ -Subproject commit 63187b976a482309e23296c5f967fc19c4131746 +Subproject commit fadfef492042ae53387d4369a6de652c930a5be4 diff --git a/crt/aws-c-s3 b/crt/aws-c-s3 index 5877f40f8..337155f6c 160000 --- a/crt/aws-c-s3 +++ b/crt/aws-c-s3 @@ -1 +1 @@ -Subproject commit 5877f40f87c77ccf2b278839995a6ee91983080f +Subproject commit 337155f6c07d39e61234e705ed6e58c31d4841eb diff --git a/crt/aws-c-sdkutils b/crt/aws-c-sdkutils index 0818f28ee..ce09f7976 160000 --- a/crt/aws-c-sdkutils +++ b/crt/aws-c-sdkutils @@ -1 +1 @@ -Subproject commit 0818f28ee436b892f09fbe8e3a6ae37ff40e9436 +Subproject commit ce09f79768653dbdc810fc14cad8685dd90acba1 diff --git a/crt/aws-checksums b/crt/aws-checksums index 0d2f5521f..3e4101b9f 160000 --- a/crt/aws-checksums +++ b/crt/aws-checksums @@ -1 +1 @@ -Subproject commit 0d2f5521f61215f38f791d106ae304402208112d +Subproject commit 3e4101b9f85a2c090774d27ae2131fca1082f522 diff --git a/crt/aws-lc b/crt/aws-lc index 8ffe277c2..59828538a 160000 --- a/crt/aws-lc +++ b/crt/aws-lc @@ -1 +1 @@ -Subproject commit 8ffe277c21915ca82dc78a3bdc6a92e10c284b92 +Subproject commit 59828538a790094113eacd5dd23d01be2885b36a diff --git a/crt/s2n b/crt/s2n index 9f4baecc7..493b77167 160000 --- a/crt/s2n +++ b/crt/s2n @@ -1 +1 @@ -Subproject commit 9f4baecc753d6fe01c13e4f422d2e327c64d06b8 +Subproject commit 493b77167dc367c394de23cfe78a029298e2a254 From b5577fa39c3a11f09c06db10ac6eaaca3910cbe2 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Fri, 6 Dec 2024 16:42:49 -0800 Subject: [PATCH 041/126] AutoTag PR for v0.29.7 (#690) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 476163a9f..f95b08708 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.29.6 +0.29.7 From a4dac5367ea0d3e916ed03203e215615cc82b3e6 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Tue, 10 Dec 2024 16:14:40 -0800 Subject: [PATCH 042/126] Update CRT dependencies (#692) --- crt/aws-c-common | 2 +- crt/aws-lc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crt/aws-c-common b/crt/aws-c-common index fadfef492..7a6f5df20 160000 --- a/crt/aws-c-common +++ b/crt/aws-c-common @@ -1 +1 @@ -Subproject commit fadfef492042ae53387d4369a6de652c930a5be4 +Subproject commit 7a6f5df201cb4b1910932ea3221de83edaa39880 diff --git a/crt/aws-lc b/crt/aws-lc index 59828538a..1be42a3e1 160000 --- a/crt/aws-lc +++ b/crt/aws-lc @@ -1 +1 @@ -Subproject commit 59828538a790094113eacd5dd23d01be2885b36a +Subproject commit 1be42a3e16a53c229690ae8215f0de8e2a1a54e7 From a947367807498c7d9f40b8402a021271da7426f3 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Thu, 19 Dec 2024 12:42:36 -0800 Subject: [PATCH 043/126] AutoTag PR for v0.29.8 (#694) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index f95b08708..d79749aa1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.29.7 +0.29.8 From 9ad3311737fcbeeb9a95bcfb3448e592f1bc1437 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Mon, 6 Jan 2025 11:59:57 -0800 Subject: [PATCH 044/126] Flaky test pass1 (#693) * Update shared subscription test to remove invalid assertions on a property that does not necessarily hold (all subscriptions receive messages) * Increase socket timeout on request-response 311 tests * Update 311 will test to work around broker race condition wrt which connection gets terminated on duplicate client id Co-authored-by: Bret Ambrose --- tests/IotServiceTest.cpp | 27 +++++++++-- tests/Mqtt5ClientTest.cpp | 87 +++++++++++------------------------ tests/MqttRequestResponse.cpp | 2 +- 3 files changed, 49 insertions(+), 67 deletions(-) diff --git a/tests/IotServiceTest.cpp b/tests/IotServiceTest.cpp index 1945d7dfc..7f3f5c8c1 100644 --- a/tests/IotServiceTest.cpp +++ b/tests/IotServiceTest.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -599,13 +600,19 @@ static int s_TestIotWillTest(Aws::Crt::Allocator *allocator, void *ctx) subscriberCv.wait(lock, [&]() { return subscriberSubscribed; }); } + // there appears to be a race condition broker-side in IoT Core such that the interrupter is occasionally + // rejected rather than the existing connection. We try and work around this in two ways: + // (1) Wait a couple seconds to let things settle in terms of eventual consistency. + // (2) Have the interrupter make connection attempts in a loop until a successful interruption occurs. + std::this_thread::sleep_for(std::chrono::seconds(2)); + // Disconnect the client by interrupting it with another client with the same ID // which will cause the will to be sent auto interruptConnection = mqttClient.NewConnection(envVars.inputHost.c_str(), 8883, socketOptions, tlsContext); - interruptConnection->SetWill(topicStr.c_str(), QOS::AWS_MQTT_QOS_AT_LEAST_ONCE, false, payload); std::mutex interruptMutex; std::condition_variable interruptCv; bool interruptConnected = false; + bool interruptConnectionAttemptComplete = false; auto interruptOnConnectionCompleted = [&](MqttConnection &, int errorCode, ReturnCode returnCode, bool sessionPresent) { @@ -614,7 +621,11 @@ static int s_TestIotWillTest(Aws::Crt::Allocator *allocator, void *ctx) (void)sessionPresent; { std::lock_guard lock(interruptMutex); - interruptConnected = true; + interruptConnectionAttemptComplete = true; + if (errorCode == AWS_ERROR_SUCCESS && returnCode == AWS_MQTT_CONNECT_ACCEPTED) + { + interruptConnected = true; + } } interruptCv.notify_one(); }; @@ -628,10 +639,16 @@ static int s_TestIotWillTest(Aws::Crt::Allocator *allocator, void *ctx) }; interruptConnection->OnConnectionCompleted = interruptOnConnectionCompleted; interruptConnection->OnDisconnect = interruptOnDisconnect; - interruptConnection->Connect((Aws::Crt::String("test-01-") + uuidStr).c_str(), true); + + bool continueConnecting = true; + while (continueConnecting) { - std::unique_lock lock(interruptMutex); - interruptCv.wait(lock, [&]() { return interruptConnected; }); + interruptConnection->Connect((Aws::Crt::String("test-01-") + uuidStr).c_str(), true); + { + std::unique_lock lock(interruptMutex); + interruptCv.wait(lock, [&]() { return interruptConnectionAttemptComplete; }); + continueConnecting = !interruptConnected; + } } // wait for message received callback - meaning the will was sent diff --git a/tests/Mqtt5ClientTest.cpp b/tests/Mqtt5ClientTest.cpp index ad14dfcc0..5d721a7b1 100644 --- a/tests/Mqtt5ClientTest.cpp +++ b/tests/Mqtt5ClientTest.cpp @@ -1974,16 +1974,10 @@ static int s_TestMqtt5SharedSubscriptionTest(Aws::Crt::Allocator *allocator, voi const String TEST_TOPIC = "test/MQTT5_Binding_CPP_" + currentUUID; const String sharedTopicFilter = "$share/crttest/test/MQTT5_Binding_CPP_" + currentUUID; - const int MESSAGE_NUMBER = 10; - std::atomic client_messages(0); - bool client1_received = false; - bool client2_received = false; - - std::vector receivedMessages(MESSAGE_NUMBER); - for (int i = 0; i < MESSAGE_NUMBER; i++) - { - receivedMessages.push_back(0); - } + static const int MESSAGE_COUNT = 10; + std::mutex receivedMessagesLock; + std::condition_variable receivedMessagesSignal; + std::vector receivedMessages; Aws::Iot::Mqtt5ClientBuilder *subscribe_builder = Aws::Iot::Mqtt5ClientBuilder::NewMqtt5ClientBuilderWithMtlsFromPath( @@ -1993,39 +1987,29 @@ static int s_TestMqtt5SharedSubscriptionTest(Aws::Crt::Allocator *allocator, voi allocator); ASSERT_TRUE(subscribe_builder); - std::promise client_received; - - auto get_on_message_callback = [&](bool &received) + auto on_message_callback1 = [&](const PublishReceivedEventData &eventData) { - return [&](const PublishReceivedEventData &eventData) -> int + String topic = eventData.publishPacket->getTopic(); + if (topic == TEST_TOPIC) { - String topic = eventData.publishPacket->getTopic(); - if (topic == TEST_TOPIC) + ByteCursor payload = eventData.publishPacket->getPayload(); + String message_string = String((const char *)payload.ptr, payload.len); + int message_int = atoi(message_string.c_str()); + { - ByteCursor payload = eventData.publishPacket->getPayload(); - String message_string = String((const char *)payload.ptr, payload.len); - int message_int = atoi(message_string.c_str()); - ASSERT_TRUE(message_int < MESSAGE_NUMBER); - ++receivedMessages[message_int]; - received = true; // this line has changed - - bool exchanged = false; - int desired = 11; - int tested = 10; - client_messages++; - exchanged = client_messages.compare_exchange_strong(tested, desired); - if (exchanged == true) + std::lock_guard guard(receivedMessagesLock); + receivedMessages.push_back(message_int); + + if (receivedMessages.size() == MESSAGE_COUNT) { - client_received.set_value(); + receivedMessagesSignal.notify_all(); } } - return 0; - }; + } }; - auto onMessage_client1 = get_on_message_callback(client1_received); - auto onMessage_client2 = get_on_message_callback(client2_received); + auto on_message_callback2 = on_message_callback1; - subscribe_builder->WithPublishReceivedCallback(onMessage_client1); + subscribe_builder->WithPublishReceivedCallback(on_message_callback1); Aws::Iot::Mqtt5ClientBuilder *subscribe_builder2 = Aws::Iot::Mqtt5ClientBuilder::NewMqtt5ClientBuilderWithMtlsFromPath( @@ -2034,8 +2018,7 @@ static int s_TestMqtt5SharedSubscriptionTest(Aws::Crt::Allocator *allocator, voi mqtt5TestVars.m_private_key_path_string.c_str(), allocator); ASSERT_TRUE(subscribe_builder2); - - subscribe_builder2->WithPublishReceivedCallback(onMessage_client2); + subscribe_builder2->WithPublishReceivedCallback(on_message_callback2); Aws::Iot::Mqtt5ClientBuilder *publish_builder = Aws::Iot::Mqtt5ClientBuilder::NewMqtt5ClientBuilderWithMtlsFromPath( mqtt5TestVars.m_hostname_string, @@ -2113,7 +2096,7 @@ static int s_TestMqtt5SharedSubscriptionTest(Aws::Crt::Allocator *allocator, voi suback.get_future().wait(); /* Publish message 10 to test topic */ - for (int i = 0; i < MESSAGE_NUMBER; i++) + for (int i = 0; i < MESSAGE_COUNT; i++) { std::string payload = std::to_string(i); std::shared_ptr publish = std::make_shared( @@ -2122,32 +2105,14 @@ static int s_TestMqtt5SharedSubscriptionTest(Aws::Crt::Allocator *allocator, voi } /* Wait for all packets to be received on both clients */ - client_received.get_future().wait(); - - /* Unsubscribe from the topic from both clients*/ - Vector unsubList; - unsubList.push_back(TEST_TOPIC); - std::shared_ptr unsubscribe_client1 = - std::make_shared(allocator); - unsubscribe_client1->WithTopicFilters(unsubList); - ASSERT_TRUE(mqtt5Client->Unsubscribe(unsubscribe_client1)); - - std::shared_ptr unsubscribe_client2 = - std::make_shared(allocator); - unsubscribe_client2->WithTopicFilters(unsubList); - ASSERT_TRUE(mqtt5Client2->Unsubscribe(unsubscribe_client2)); - - /* make sure all messages are received */ - ASSERT_INT_EQUALS(MESSAGE_NUMBER + 1, client_messages); /* We are adding one at the end, so 10 messages received */ - - /* makes sure both clients received at least one message */ - ASSERT_TRUE(client1_received); - ASSERT_TRUE(client2_received); + std::unique_lock receivedLock(receivedMessagesLock); + receivedMessagesSignal.wait(receivedLock, [&]() { return receivedMessages.size() == MESSAGE_COUNT; }); + std::sort(receivedMessages.begin(), receivedMessages.end()); /* make sure all messages are received with no duplicates*/ - for (int i = 0; i < MESSAGE_NUMBER; i++) + for (int i = 0; i < MESSAGE_COUNT; i++) { - ASSERT_TRUE(receivedMessages[i] > 0); + ASSERT_INT_EQUALS(i, receivedMessages[i]); } /* Stop all clients */ ASSERT_TRUE(mqtt5Client->Stop()); diff --git a/tests/MqttRequestResponse.cpp b/tests/MqttRequestResponse.cpp index bf02f29fc..f701d208d 100644 --- a/tests/MqttRequestResponse.cpp +++ b/tests/MqttRequestResponse.cpp @@ -287,7 +287,7 @@ static TestContext s_CreateClient( Aws::Crt::Io::TlsContext tlsContext(tlsCtxOptions, Aws::Crt::Io::TlsMode::CLIENT, allocator); Aws::Crt::Io::SocketOptions socketOptions; - socketOptions.SetConnectTimeoutMs(3000); + socketOptions.SetConnectTimeoutMs(10000); Aws::Crt::Mqtt::MqttClient client; context.protocolClient311 = From b71dadc94fda5020499f86724a381e17acaf0c96 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Tue, 14 Jan 2025 11:41:10 -0800 Subject: [PATCH 045/126] Latest submodules copy_source_uri Change (#696) --- crt/aws-c-s3 | 2 +- crt/aws-c-sdkutils | 2 +- crt/aws-lc | 2 +- crt/s2n | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crt/aws-c-s3 b/crt/aws-c-s3 index 337155f6c..a3b401bfb 160000 --- a/crt/aws-c-s3 +++ b/crt/aws-c-s3 @@ -1 +1 @@ -Subproject commit 337155f6c07d39e61234e705ed6e58c31d4841eb +Subproject commit a3b401bfb53c28c88a930d496b481311dd76a4f5 diff --git a/crt/aws-c-sdkutils b/crt/aws-c-sdkutils index ce09f7976..1ae8664f9 160000 --- a/crt/aws-c-sdkutils +++ b/crt/aws-c-sdkutils @@ -1 +1 @@ -Subproject commit ce09f79768653dbdc810fc14cad8685dd90acba1 +Subproject commit 1ae8664f90cb5ab5e23b161a31e021c6d3a28e72 diff --git a/crt/aws-lc b/crt/aws-lc index 1be42a3e1..697acc661 160000 --- a/crt/aws-lc +++ b/crt/aws-lc @@ -1 +1 @@ -Subproject commit 1be42a3e16a53c229690ae8215f0de8e2a1a54e7 +Subproject commit 697acc6616736ad07539fda1e0726cc043e1097a diff --git a/crt/s2n b/crt/s2n index 493b77167..2e79e7efe 160000 --- a/crt/s2n +++ b/crt/s2n @@ -1 +1 @@ -Subproject commit 493b77167dc367c394de23cfe78a029298e2a254 +Subproject commit 2e79e7efeb26f06eb59a1d4f3444ea63fc3e20c3 From e65a61d0fc85888d84c105e90f33115813273d0f Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Tue, 14 Jan 2025 11:41:48 -0800 Subject: [PATCH 046/126] AutoTag PR for v0.29.9 (#697) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index d79749aa1..0fca64ce4 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.29.8 +0.29.9 From 6a55ecc055e3bcbdcae188276f562177ac86f3e9 Mon Sep 17 00:00:00 2001 From: Dengke Tang Date: Mon, 27 Jan 2025 17:36:41 -0800 Subject: [PATCH 047/126] Fix segfaults -- CRC64NVME on machines with disabled AVX and uri parsing corner case. (#700) --- .github/workflows/ci.yml | 2 +- crt/aws-c-auth | 2 +- crt/aws-c-common | 2 +- crt/aws-c-s3 | 2 +- crt/aws-lc | 2 +- crt/s2n | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7939a891c..9928d06c1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,7 @@ jobs: # that are up-to-date (AL2) or don't provide OpenSSL development packages that is found in CMake (alpine) # or are not able to connect on the socket even with the correct setup (manylinux2014) linux-compat: - runs-on: ubuntu-24.04 # latest + runs-on: ubuntu-22.04 # temporarily downgrade to old ubuntu until https://github.com/actions/runner-images/issues/11471 resolves strategy: fail-fast: false matrix: diff --git a/crt/aws-c-auth b/crt/aws-c-auth index 3982bd75f..8927de4dc 160000 --- a/crt/aws-c-auth +++ b/crt/aws-c-auth @@ -1 +1 @@ -Subproject commit 3982bd75fea74efd8f9b462b27fedd4599db4f53 +Subproject commit 8927de4dcff6faab948e801aeeca3ac9a57caab7 diff --git a/crt/aws-c-common b/crt/aws-c-common index 7a6f5df20..5e6c08186 160000 --- a/crt/aws-c-common +++ b/crt/aws-c-common @@ -1 +1 @@ -Subproject commit 7a6f5df201cb4b1910932ea3221de83edaa39880 +Subproject commit 5e6c08186fa5d8c7679acf95b86ada4119ca23b8 diff --git a/crt/aws-c-s3 b/crt/aws-c-s3 index a3b401bfb..aef075b7d 160000 --- a/crt/aws-c-s3 +++ b/crt/aws-c-s3 @@ -1 +1 @@ -Subproject commit a3b401bfb53c28c88a930d496b481311dd76a4f5 +Subproject commit aef075b7db620cd32fbe1ec19a819c1b0acd2e79 diff --git a/crt/aws-lc b/crt/aws-lc index 697acc661..ffd6fb71b 160000 --- a/crt/aws-lc +++ b/crt/aws-lc @@ -1 +1 @@ -Subproject commit 697acc6616736ad07539fda1e0726cc043e1097a +Subproject commit ffd6fb71b1e1582a620149337b77706f2391578d diff --git a/crt/s2n b/crt/s2n index 2e79e7efe..6cc9f53d7 160000 --- a/crt/s2n +++ b/crt/s2n @@ -1 +1 @@ -Subproject commit 2e79e7efeb26f06eb59a1d4f3444ea63fc3e20c3 +Subproject commit 6cc9f53d7ab5f0427ae5f838891fff57844a9e3f From 11fb6c0936013d6c36e44cdef265548822034d59 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Wed, 29 Jan 2025 15:48:50 -0800 Subject: [PATCH 048/126] Add topic argument to publish callback in request-response stream client (#703) --- crt/aws-c-mqtt | 2 +- include/aws/iot/MqttRequestResponseClient.h | 28 +++++++++++++++++++-- source/iot/MqttRequestResponseClient.cpp | 12 ++++++--- tests/MqttRequestResponse.cpp | 21 ++++++++++++---- 4 files changed, 52 insertions(+), 11 deletions(-) diff --git a/crt/aws-c-mqtt b/crt/aws-c-mqtt index 627c3334e..9c093c403 160000 --- a/crt/aws-c-mqtt +++ b/crt/aws-c-mqtt @@ -1 +1 @@ -Subproject commit 627c3334e52021aa8d5772b6ca076884610f3219 +Subproject commit 9c093c4039478c04c7e55a1825c391dd4742fd61 diff --git a/include/aws/iot/MqttRequestResponseClient.h b/include/aws/iot/MqttRequestResponseClient.h index 805db22c3..35123d6c6 100644 --- a/include/aws/iot/MqttRequestResponseClient.h +++ b/include/aws/iot/MqttRequestResponseClient.h @@ -121,12 +121,28 @@ namespace Aws /** * Default constructor */ - IncomingPublishEvent() : m_payload() { AWS_ZERO_STRUCT(m_payload); } + IncomingPublishEvent() : m_topic(), m_payload() + { + AWS_ZERO_STRUCT(m_topic); + AWS_ZERO_STRUCT(m_payload); + } + + /** + * Sets the message response topic associated with this event. The event does not own this topic. + * + * @param topic the message response topic associated with this event + * @return reference to this + */ + IncomingPublishEvent &WithTopic(Aws::Crt::ByteCursor topic) + { + m_topic = topic; + return *this; + } /** * Sets the message payload associated with this event. The event does not own this payload. * - * @param payload he message payload associated with this event + * @param payload the message payload associated with this event * @return reference to this */ IncomingPublishEvent &WithPayload(Aws::Crt::ByteCursor payload) @@ -135,6 +151,13 @@ namespace Aws return *this; } + /** + * Gets the message response topic associated with this event. + * + * @return the message response topic associated with this event + */ + Aws::Crt::ByteCursor GetTopic() const { return m_topic; } + /** * Gets the message payload associated with this event. * @@ -143,6 +166,7 @@ namespace Aws Aws::Crt::ByteCursor GetPayload() const { return m_payload; } private: + Aws::Crt::ByteCursor m_topic; Aws::Crt::ByteCursor m_payload; }; diff --git a/source/iot/MqttRequestResponseClient.cpp b/source/iot/MqttRequestResponseClient.cpp index 2bdcb960f..cb142797b 100644 --- a/source/iot/MqttRequestResponseClient.cpp +++ b/source/iot/MqttRequestResponseClient.cpp @@ -89,7 +89,10 @@ namespace Aws int error_code, void *user_data); - static void OnIncomingPublishCallback(struct aws_byte_cursor payload, void *user_data); + static void OnIncomingPublishCallback( + struct aws_byte_cursor payload, + struct aws_byte_cursor topic, + void *user_data); static void OnTerminatedCallback(void *user_data); @@ -187,7 +190,10 @@ namespace Aws } } - void StreamingOperationImpl::OnIncomingPublishCallback(struct aws_byte_cursor payload, void *user_data) + void StreamingOperationImpl::OnIncomingPublishCallback( + struct aws_byte_cursor payload, + struct aws_byte_cursor topic, + void *user_data) { auto *handle = static_cast(user_data); StreamingOperationImpl *impl = handle->m_impl.get(); @@ -198,7 +204,7 @@ namespace Aws if (!impl->m_closed && impl->m_config.incomingPublishEventHandler) { IncomingPublishEvent event; - event.WithPayload(payload); + event.WithTopic(topic).WithPayload(payload); impl->m_config.incomingPublishEventHandler(std::move(event)); } diff --git a/tests/MqttRequestResponse.cpp b/tests/MqttRequestResponse.cpp index f701d208d..0658713be 100644 --- a/tests/MqttRequestResponse.cpp +++ b/tests/MqttRequestResponse.cpp @@ -40,6 +40,12 @@ struct ResponseTracker bool complete; }; +struct TestPublishEvent +{ + Aws::Crt::String topic; + Aws::Crt::String payload; +}; + struct TestState { TestState(Aws::Crt::Allocator *allocator) : allocator(allocator) {} @@ -54,7 +60,7 @@ struct TestState Aws::Crt::Vector> responseTrackers; Aws::Crt::Vector subscriptionStatusEvents; - Aws::Crt::Vector incomingPublishEvents; + Aws::Crt::Vector incomingPublishEvents; }; static void s_waitForConnected(struct TestState *state) @@ -168,17 +174,20 @@ static void s_onIncomingPublishEvent(Aws::Iot::RequestResponse::IncomingPublishE { std::unique_lock lock(state->lock); + auto topicCursor = event.GetTopic(); + Aws::Crt::String topicAsString((const char *)topicCursor.ptr, topicCursor.len); + auto payloadCursor = event.GetPayload(); Aws::Crt::String payloadAsString((const char *)payloadCursor.ptr, payloadCursor.len); - state->incomingPublishEvents.push_back(payloadAsString); + state->incomingPublishEvents.push_back({std::move(topicAsString), std::move(payloadAsString)}); } state->signal.notify_one(); } static void s_waitForIncomingPublishWithPredicate( TestState *state, - const std::function &predicate) + const std::function &predicate) { { std::unique_lock lock(state->lock); @@ -189,7 +198,7 @@ static void s_waitForIncomingPublishWithPredicate( return std::any_of( state->incomingPublishEvents.cbegin(), state->incomingPublishEvents.cend(), - [=](const Aws::Crt::String &payload) { return predicate(payload); }); + [=](const TestPublishEvent &publishEvent) { return predicate(publishEvent); }); }); } } @@ -1077,7 +1086,9 @@ static int s_doShadowUpdatedStreamIncomingPublishTest(Aws::Crt::Allocator *alloc s_publishToProtocolClient(context, uuid, s_publishPayload, allocator); s_waitForIncomingPublishWithPredicate( - &state, [](const Aws::Crt::String &payload) { return payload == Aws::Crt::String(s_publishPayload); }); + &state, + [&uuid](const TestPublishEvent &publishEvent) + { return publishEvent.topic == uuid && publishEvent.payload == Aws::Crt::String(s_publishPayload); }); return AWS_OP_SUCCESS; } From ca3a2a65418f8c568189f5316a317ded27319364 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Thu, 30 Jan 2025 10:32:12 -0800 Subject: [PATCH 049/126] Cmake modules (#702) --- CMakeLists.txt | 63 ++++++++++--------------------- bin/elasticurl_cpp/CMakeLists.txt | 4 +- bin/mqtt5_app/CMakeLists.txt | 4 +- bin/mqtt5_canary/CMakeLists.txt | 4 +- crt/aws-c-auth | 2 +- crt/aws-c-cal | 2 +- crt/aws-c-common | 2 +- crt/aws-c-compression | 2 +- crt/aws-c-event-stream | 2 +- crt/aws-c-http | 2 +- crt/aws-c-io | 2 +- crt/aws-c-mqtt | 2 +- crt/aws-c-s3 | 2 +- crt/aws-c-sdkutils | 2 +- crt/aws-checksums | 2 +- 15 files changed, 33 insertions(+), 64 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4127d0714..b0409fc9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,4 @@ -cmake_minimum_required(VERSION 3.9) - -if(POLICY CMP0077) - cmake_policy(SET CMP0077 NEW) -endif() +cmake_minimum_required(VERSION 3.9...3.31) option(BUILD_DEPS "Builds aws common runtime dependencies as part of build. Turn off if you want to control your dependency chain." ON) option(BYO_CRYPTO "Don't build a tls implementation or link against a crypto interface. This feature is only for unix builds currently" OFF) @@ -30,24 +26,7 @@ project("aws-crt-cpp" VERSION ${SIMPLE_VERSION}) include(CTest) - -if(DEFINED CMAKE_PREFIX_PATH) - file(TO_CMAKE_PATH "${CMAKE_PREFIX_PATH}" CMAKE_PREFIX_PATH) -endif() - -if(DEFINED CMAKE_INSTALL_PREFIX) - file(TO_CMAKE_PATH "${CMAKE_INSTALL_PREFIX}" CMAKE_INSTALL_PREFIX) -endif() - -if(UNIX AND NOT APPLE) - include(GNUInstallDirs) -elseif(NOT DEFINED CMAKE_INSTALL_LIBDIR) - set(CMAKE_INSTALL_LIBDIR "lib") -endif() - -if(${CMAKE_INSTALL_LIBDIR} STREQUAL "lib64") - set(FIND_LIBRARY_USE_LIB64_PATHS true) -endif() +include(GNUInstallDirs) if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 11) @@ -65,13 +44,6 @@ set(GENERATED_INCLUDE_DIR "${GENERATED_ROOT_DIR}/include") set(GENERATED_CONFIG_HEADER "${GENERATED_INCLUDE_DIR}/aws/crt/Config.h") configure_file(include/aws/crt/Config.h.in ${GENERATED_CONFIG_HEADER} @ONLY) -# This is required in order to append /lib/cmake to each element in CMAKE_PREFIX_PATH -set(AWS_MODULE_DIR "/${CMAKE_INSTALL_LIBDIR}/cmake") -string(REPLACE ";" "${AWS_MODULE_DIR};" AWS_MODULE_PATH "${CMAKE_PREFIX_PATH}${AWS_MODULE_DIR}") - -# Append that generated list to the module search path -list(APPEND CMAKE_MODULE_PATH ${AWS_MODULE_PATH}) - if(BUILD_DEPS) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/crt/aws-c-common/cmake") @@ -132,6 +104,9 @@ if(BUILD_DEPS) add_subdirectory(crt/aws-c-s3) set(BUILD_TESTING ${BUILD_TESTING_PREV}) else() + # this is required so we can use aws-c-common's CMake modules + find_package(aws-c-common REQUIRED) + include(AwsFindPackage) set(IN_SOURCE_BUILD OFF) endif() @@ -356,23 +331,23 @@ aws_add_sanitizers(${PROJECT_NAME}) target_link_libraries(${PROJECT_NAME} PUBLIC ${DEP_AWS_LIBS}) -install(FILES ${AWS_CRT_HEADERS} DESTINATION "include/aws/crt" COMPONENT Development) -install(FILES ${AWS_CRT_AUTH_HEADERS} DESTINATION "include/aws/crt/auth" COMPONENT Development) -install(FILES ${AWS_CRT_CHECKSUM_HEADERS} DESTINATION "include/aws/crt/checksum" COMPONENT Development) -install(FILES ${AWS_CRT_CRYPTO_HEADERS} DESTINATION "include/aws/crt/crypto" COMPONENT Development) -install(FILES ${AWS_CRT_IO_HEADERS} DESTINATION "include/aws/crt/io" COMPONENT Development) -install(FILES ${AWS_CRT_IOT_HEADERS} DESTINATION "include/aws/iot" COMPONENT Development) -install(FILES ${AWS_CRT_MQTT_HEADERS} DESTINATION "include/aws/crt/mqtt" COMPONENT Development) -install(FILES ${AWS_CRT_HTTP_HEADERS} DESTINATION "include/aws/crt/http" COMPONENT Development) -install(FILES ${AWS_CRT_ENDPOINT_HEADERS} DESTINATION "include/aws/crt/endpoints" COMPONENT Development) -install(FILES ${AWS_CRT_CBOR_HEADERS} DESTINATION "include/aws/crt/cbor" COMPONENT Development) +install(FILES ${AWS_CRT_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt" COMPONENT Development) +install(FILES ${AWS_CRT_AUTH_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt/auth" COMPONENT Development) +install(FILES ${AWS_CRT_CHECKSUM_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt/checksum" COMPONENT Development) +install(FILES ${AWS_CRT_CRYPTO_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt/crypto" COMPONENT Development) +install(FILES ${AWS_CRT_IO_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt/io" COMPONENT Development) +install(FILES ${AWS_CRT_IOT_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/iot" COMPONENT Development) +install(FILES ${AWS_CRT_MQTT_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt/mqtt" COMPONENT Development) +install(FILES ${AWS_CRT_HTTP_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt/http" COMPONENT Development) +install(FILES ${AWS_CRT_ENDPOINT_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt/endpoints" COMPONENT Development) +install(FILES ${AWS_CRT_CBOR_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt/cbor" COMPONENT Development) install( TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}-targets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development - RUNTIME DESTINATION bin COMPONENT Runtime + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime ) if(BUILD_SHARED_LIBS) @@ -382,7 +357,7 @@ else() endif() install(EXPORT "${PROJECT_NAME}-targets" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}/cmake/${TARGET_DIR}" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/${TARGET_DIR}" NAMESPACE AWS:: COMPONENT Development) @@ -398,11 +373,11 @@ write_basic_package_version_file( ) install(FILES "${GENERATED_ROOT_DIR}/${PROJECT_NAME}-config.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}/cmake/" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/" COMPONENT Development) install(FILES "${GENERATED_ROOT_DIR}/${PROJECT_NAME}-config-version.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}/cmake/" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/" COMPONENT Development) if(NOT CMAKE_CROSSCOMPILING) diff --git a/bin/elasticurl_cpp/CMakeLists.txt b/bin/elasticurl_cpp/CMakeLists.txt index 36185c15c..a96f94e8b 100644 --- a/bin/elasticurl_cpp/CMakeLists.txt +++ b/bin/elasticurl_cpp/CMakeLists.txt @@ -1,7 +1,5 @@ project(elasticurl_cpp CXX) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_PREFIX_PATH}/lib/cmake") - file(GLOB ELASTICURL_CPP_SRC "*.cpp" ) @@ -43,5 +41,5 @@ install(TARGETS ${ELASTICURL_CPP_PROJECT_NAME} EXPORT ${ELASTICURL_CPP_PROJECT_NAME}-targets COMPONENT Runtime RUNTIME - DESTINATION bin + DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime) diff --git a/bin/mqtt5_app/CMakeLists.txt b/bin/mqtt5_app/CMakeLists.txt index e4637d6d1..931e07e7c 100644 --- a/bin/mqtt5_app/CMakeLists.txt +++ b/bin/mqtt5_app/CMakeLists.txt @@ -1,7 +1,5 @@ project(mqtt5_app CXX) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_PREFIX_PATH}/lib/cmake") - file(GLOB MQTT5_APP_SRC "*.cpp" ) @@ -43,5 +41,5 @@ install(TARGETS ${MQTT5_APP_PROJECT_NAME} EXPORT ${MQTT5_APP_PROJECT_NAME}-targets COMPONENT Runtime RUNTIME - DESTINATION bin + DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime) diff --git a/bin/mqtt5_canary/CMakeLists.txt b/bin/mqtt5_canary/CMakeLists.txt index 87c594cc5..4426053d4 100644 --- a/bin/mqtt5_canary/CMakeLists.txt +++ b/bin/mqtt5_canary/CMakeLists.txt @@ -1,7 +1,5 @@ project(mqtt5_canary CXX) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_PREFIX_PATH}/lib/cmake") - file(GLOB MQTT5_CANARY_SRC "*.cpp" ) @@ -43,5 +41,5 @@ install(TARGETS ${MQTT5_CANARY_PROJECT_NAME} EXPORT ${MQTT5_CANARY_PROJECT_NAME}-targets COMPONENT Runtime RUNTIME - DESTINATION bin + DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime) diff --git a/crt/aws-c-auth b/crt/aws-c-auth index 8927de4dc..b513db4bf 160000 --- a/crt/aws-c-auth +++ b/crt/aws-c-auth @@ -1 +1 @@ -Subproject commit 8927de4dcff6faab948e801aeeca3ac9a57caab7 +Subproject commit b513db4bf82429a1134fecbd6d12e5fda45255a6 diff --git a/crt/aws-c-cal b/crt/aws-c-cal index fbbe2612a..7299c6ab9 160000 --- a/crt/aws-c-cal +++ b/crt/aws-c-cal @@ -1 +1 @@ -Subproject commit fbbe2612a3385d1ded02a52d20ad7fd2da4501f4 +Subproject commit 7299c6ab9244595b140d604475cdd6c6921be8ae diff --git a/crt/aws-c-common b/crt/aws-c-common index 5e6c08186..0e7637fa8 160000 --- a/crt/aws-c-common +++ b/crt/aws-c-common @@ -1 +1 @@ -Subproject commit 5e6c08186fa5d8c7679acf95b86ada4119ca23b8 +Subproject commit 0e7637fa852a472bd4c37fc07a325a09c942a5fc diff --git a/crt/aws-c-compression b/crt/aws-c-compression index c6c1191e5..f951ab2b8 160000 --- a/crt/aws-c-compression +++ b/crt/aws-c-compression @@ -1 +1 @@ -Subproject commit c6c1191e525e5aa6ead9e1afc392e35d3b50331e +Subproject commit f951ab2b819fc6993b6e5e6cfef64b1a1554bfc8 diff --git a/crt/aws-c-event-stream b/crt/aws-c-event-stream index d2dcc9344..9422ef78a 160000 --- a/crt/aws-c-event-stream +++ b/crt/aws-c-event-stream @@ -1 +1 @@ -Subproject commit d2dcc9344dae24de320866045d85166d8a91a0d1 +Subproject commit 9422ef78aac566414d1bebb1a5431a4c53a7547c diff --git a/crt/aws-c-http b/crt/aws-c-http index fc3eded24..590c7b597 160000 --- a/crt/aws-c-http +++ b/crt/aws-c-http @@ -1 +1 @@ -Subproject commit fc3eded2465c37d07fd9cc15e9b5b011224c9c9a +Subproject commit 590c7b597f87e5edc080b8b77418690c30319832 diff --git a/crt/aws-c-io b/crt/aws-c-io index fcb38c804..3041dabfc 160000 --- a/crt/aws-c-io +++ b/crt/aws-c-io @@ -1 +1 @@ -Subproject commit fcb38c804364dd627c335da752a99a125a88f6e9 +Subproject commit 3041dabfc13fe9bc9a0467e15aa1d5a09c7fc06f diff --git a/crt/aws-c-mqtt b/crt/aws-c-mqtt index 9c093c403..83247bde8 160000 --- a/crt/aws-c-mqtt +++ b/crt/aws-c-mqtt @@ -1 +1 @@ -Subproject commit 9c093c4039478c04c7e55a1825c391dd4742fd61 +Subproject commit 83247bde8268905018327891fcf0147f3e438a80 diff --git a/crt/aws-c-s3 b/crt/aws-c-s3 index aef075b7d..6eb8be530 160000 --- a/crt/aws-c-s3 +++ b/crt/aws-c-s3 @@ -1 +1 @@ -Subproject commit aef075b7db620cd32fbe1ec19a819c1b0acd2e79 +Subproject commit 6eb8be530b100fed5c6d24ca48a57ee2e6098fbf diff --git a/crt/aws-c-sdkutils b/crt/aws-c-sdkutils index 1ae8664f9..ba6a28fab 160000 --- a/crt/aws-c-sdkutils +++ b/crt/aws-c-sdkutils @@ -1 +1 @@ -Subproject commit 1ae8664f90cb5ab5e23b161a31e021c6d3a28e72 +Subproject commit ba6a28fab7ed5d7f1b3b1d12eb672088be093824 diff --git a/crt/aws-checksums b/crt/aws-checksums index 3e4101b9f..fb8bd0b8c 160000 --- a/crt/aws-checksums +++ b/crt/aws-checksums @@ -1 +1 @@ -Subproject commit 3e4101b9f85a2c090774d27ae2131fca1082f522 +Subproject commit fb8bd0b8cff00c8c24a35d601fce1b4c611df6da From 89078a6ebd79a1dd124faddf53855a843c6f1bf4 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Thu, 30 Jan 2025 10:57:43 -0800 Subject: [PATCH 050/126] AutoTag PR for v0.30.0 (#704) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 0fca64ce4..c25c8e5b7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.29.9 +0.30.0 From dcb6cce418bd5826e4eb060d863431dc740b31af Mon Sep 17 00:00:00 2001 From: Dmitriy Musatkin <63878209+DmitriyMusatkin@users.noreply.github.com> Date: Thu, 30 Jan 2025 13:24:20 -0800 Subject: [PATCH 051/126] Temporarily rollback s2n (#705) --- crt/s2n | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crt/s2n b/crt/s2n index 6cc9f53d7..493b77167 160000 --- a/crt/s2n +++ b/crt/s2n @@ -1 +1 @@ -Subproject commit 6cc9f53d7ab5f0427ae5f838891fff57844a9e3f +Subproject commit 493b77167dc367c394de23cfe78a029298e2a254 From 9a820b302264b2bfe2e3f61a443fb1c652e6bd79 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Thu, 30 Jan 2025 13:25:12 -0800 Subject: [PATCH 052/126] AutoTag PR for v0.30.1 (#706) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index c25c8e5b7..1a44cad74 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.30.0 +0.30.1 From 39f027799c90d25ddfa26a8749247a1d1d879a73 Mon Sep 17 00:00:00 2001 From: sbera87 Date: Thu, 6 Feb 2025 12:52:20 -0500 Subject: [PATCH 053/126] Support IPv6 endpoint (#707) --- include/aws/crt/DnsUtils.h | 17 +++++++++++++++++ source/DnsUtils.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 include/aws/crt/DnsUtils.h create mode 100644 source/DnsUtils.cpp diff --git a/include/aws/crt/DnsUtils.h b/include/aws/crt/DnsUtils.h new file mode 100644 index 000000000..c2271bca9 --- /dev/null +++ b/include/aws/crt/DnsUtils.h @@ -0,0 +1,17 @@ +#pragma once +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include + +namespace Aws +{ + namespace Crt + { + namespace DnsUtils + { + AWS_CRT_CPP_API bool IsValidIpV6(const char *host, bool is_uri_encoded); + } // namespace DnsUtils + } // namespace Crt +} // namespace Aws diff --git a/source/DnsUtils.cpp b/source/DnsUtils.cpp new file mode 100644 index 000000000..ba345bb57 --- /dev/null +++ b/source/DnsUtils.cpp @@ -0,0 +1,24 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include +#include +#include + +namespace Aws +{ + namespace Crt + { + namespace DnsUtils + { + + bool IsValidIpV6(const char *host, bool is_uri_encoded) + { + return aws_host_utils_is_ipv6(Aws::Crt::ByteCursorFromCString(host), is_uri_encoded); + } + + } // namespace DnsUtils + } // namespace Crt +} // namespace Aws From bd62b5609c0b2d7a57ba9b72ac9f92109c547681 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Wed, 12 Feb 2025 09:03:52 -0800 Subject: [PATCH 054/126] AutoTag PR for v0.30.2 (#709) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 1a44cad74..0f7217737 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.30.1 +0.30.2 From 9390cb899f137e306505880a3f974e811b6d03f0 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Tue, 25 Feb 2025 13:21:26 -0800 Subject: [PATCH 055/126] Update submodules (#711) --- crt/aws-c-auth | 2 +- crt/aws-c-common | 2 +- crt/aws-c-event-stream | 2 +- crt/aws-c-io | 2 +- crt/aws-c-mqtt | 2 +- crt/aws-lc | 2 +- crt/s2n | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crt/aws-c-auth b/crt/aws-c-auth index b513db4bf..2d85beff9 160000 --- a/crt/aws-c-auth +++ b/crt/aws-c-auth @@ -1 +1 @@ -Subproject commit b513db4bf82429a1134fecbd6d12e5fda45255a6 +Subproject commit 2d85beff96bee7ee4734c21c7fc6b15e9d07b85e diff --git a/crt/aws-c-common b/crt/aws-c-common index 0e7637fa8..6401c830f 160000 --- a/crt/aws-c-common +++ b/crt/aws-c-common @@ -1 +1 @@ -Subproject commit 0e7637fa852a472bd4c37fc07a325a09c942a5fc +Subproject commit 6401c830ffcd82ee9c9e26255f2fadf7092c7321 diff --git a/crt/aws-c-event-stream b/crt/aws-c-event-stream index 9422ef78a..4bd476bd0 160000 --- a/crt/aws-c-event-stream +++ b/crt/aws-c-event-stream @@ -1 +1 @@ -Subproject commit 9422ef78aac566414d1bebb1a5431a4c53a7547c +Subproject commit 4bd476bd0c629e8fab4ec0ace92830efc6a79e6c diff --git a/crt/aws-c-io b/crt/aws-c-io index 3041dabfc..5fcecfc62 160000 --- a/crt/aws-c-io +++ b/crt/aws-c-io @@ -1 +1 @@ -Subproject commit 3041dabfc13fe9bc9a0467e15aa1d5a09c7fc06f +Subproject commit 5fcecfc621059e254f2dc0dcac46265fcba0bf3a diff --git a/crt/aws-c-mqtt b/crt/aws-c-mqtt index 83247bde8..f0cc34cb6 160000 --- a/crt/aws-c-mqtt +++ b/crt/aws-c-mqtt @@ -1 +1 @@ -Subproject commit 83247bde8268905018327891fcf0147f3e438a80 +Subproject commit f0cc34cb6f54e050275e3c859594c62776d46d83 diff --git a/crt/aws-lc b/crt/aws-lc index ffd6fb71b..becf5785c 160000 --- a/crt/aws-lc +++ b/crt/aws-lc @@ -1 +1 @@ -Subproject commit ffd6fb71b1e1582a620149337b77706f2391578d +Subproject commit becf5785c131012bb5a64f3da6cdb117ddc0f431 diff --git a/crt/s2n b/crt/s2n index 493b77167..21cefc109 160000 --- a/crt/s2n +++ b/crt/s2n @@ -1 +1 @@ -Subproject commit 493b77167dc367c394de23cfe78a029298e2a254 +Subproject commit 21cefc1091b3953ef543c9e72b932b6431fadc6e From c776ab5b38036662ebd0569d2483b98a176f9819 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Tue, 25 Feb 2025 13:44:05 -0800 Subject: [PATCH 056/126] AutoTag PR for v0.31.0 (#712) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 0f7217737..26bea73e8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.30.2 +0.31.0 From ba27ca51c9e187231cf69cc5b7482493174917dd Mon Sep 17 00:00:00 2001 From: Dmitriy Musatkin <63878209+DmitriyMusatkin@users.noreply.github.com> Date: Fri, 28 Feb 2025 14:28:29 -0800 Subject: [PATCH 057/126] Fix Arm based ci steps (#713) --- .github/workflows/ci.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9928d06c1..f2039f271 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,8 +38,6 @@ jobs: with: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} - - name: Install qemu/docker - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - name: Build ${{ env.PACKAGE_NAME }} run: | aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh @@ -49,7 +47,7 @@ jobs: # that are up-to-date (AL2) or don't provide OpenSSL development packages that is found in CMake (alpine) # or are not able to connect on the socket even with the correct setup (manylinux2014) linux-compat: - runs-on: ubuntu-22.04 # temporarily downgrade to old ubuntu until https://github.com/actions/runner-images/issues/11471 resolves + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: @@ -68,7 +66,7 @@ jobs: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Install qemu/docker - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + run: docker run --privileged --rm tonistiigi/binfmt --install all - name: Build ${{ env.PACKAGE_NAME }} run: | aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh @@ -121,7 +119,7 @@ jobs: aws-region: ${{ env.AWS_DEFAULT_REGION }} # set arm arch - name: Install qemu/docker - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + run: docker run --privileged --rm tonistiigi/binfmt --install linux/arm/v7 - name: Build ${{ env.PACKAGE_NAME }} run: | From 0a27f7412660aeb2cbb0e8c2f08fdf2d8768c918 Mon Sep 17 00:00:00 2001 From: Michael Graeb Date: Mon, 17 Mar 2025 09:23:39 -0700 Subject: [PATCH 058/126] HTTP/1: Support streaming requests of unknown length (#714) **Issue:** aws-sdk-cpp needs to send streaming requests of unknown content length. This isn't currently supported in our HTTP/1 client. **Description of changes:** - Update submodules: aws-c-auth v0.8.5 -> v0.8.6 aws-c-cal v0.8.3 -> v0.8.7 aws-c-common v0.11.1 -> v0.12.0 aws-c-event-stream v0.5.2 -> v0.5.4 aws-c-http v0.9.3 -> v0.9.5 aws-c-io v0.16.0 -> v0.17.0 aws-c-s3 v0.7.11 -> v0.7.13 aws-lc v1.46.1 -> v1.48.4 s2n v1.5.13 -> v1.5.14 - Bring in change that allows HTTP/1 streams of unknown length: - https://github.com/awslabs/aws-c-http/pull/506 - Remove hack in Base64 decoded logic, which is no longer necessary due to this change: - https://github.com/awslabs/aws-c-common/pull/1188 --- crt/aws-c-auth | 2 +- crt/aws-c-cal | 2 +- crt/aws-c-common | 2 +- crt/aws-c-event-stream | 2 +- crt/aws-c-http | 2 +- crt/aws-c-io | 2 +- crt/aws-c-s3 | 2 +- crt/aws-lc | 2 +- crt/s2n | 2 +- source/Types.cpp | 8 ++------ 10 files changed, 11 insertions(+), 15 deletions(-) diff --git a/crt/aws-c-auth b/crt/aws-c-auth index 2d85beff9..01dd06acd 160000 --- a/crt/aws-c-auth +++ b/crt/aws-c-auth @@ -1 +1 @@ -Subproject commit 2d85beff96bee7ee4734c21c7fc6b15e9d07b85e +Subproject commit 01dd06acd2b8865a4a6bc232380ee69a042af47d diff --git a/crt/aws-c-cal b/crt/aws-c-cal index 7299c6ab9..d59c198db 160000 --- a/crt/aws-c-cal +++ b/crt/aws-c-cal @@ -1 +1 @@ -Subproject commit 7299c6ab9244595b140d604475cdd6c6921be8ae +Subproject commit d59c198db17c42a48e3ee105d12357f5a9efecf3 diff --git a/crt/aws-c-common b/crt/aws-c-common index 6401c830f..7fb0071ab 160000 --- a/crt/aws-c-common +++ b/crt/aws-c-common @@ -1 +1 @@ -Subproject commit 6401c830ffcd82ee9c9e26255f2fadf7092c7321 +Subproject commit 7fb0071ab88182bffcc18a4a09bdb4dd2a5751d8 diff --git a/crt/aws-c-event-stream b/crt/aws-c-event-stream index 4bd476bd0..9312b0525 160000 --- a/crt/aws-c-event-stream +++ b/crt/aws-c-event-stream @@ -1 +1 @@ -Subproject commit 4bd476bd0c629e8fab4ec0ace92830efc6a79e6c +Subproject commit 9312b052583183b98526aaeb91e5c72ec3db9627 diff --git a/crt/aws-c-http b/crt/aws-c-http index 590c7b597..e3a9cabc6 160000 --- a/crt/aws-c-http +++ b/crt/aws-c-http @@ -1 +1 @@ -Subproject commit 590c7b597f87e5edc080b8b77418690c30319832 +Subproject commit e3a9cabc664630120df25c28ec710199b8e8b15b diff --git a/crt/aws-c-io b/crt/aws-c-io index 5fcecfc62..318f7e57e 160000 --- a/crt/aws-c-io +++ b/crt/aws-c-io @@ -1 +1 @@ -Subproject commit 5fcecfc621059e254f2dc0dcac46265fcba0bf3a +Subproject commit 318f7e57e7871e5b0d48a281cc5dcb7f79ccecdd diff --git a/crt/aws-c-s3 b/crt/aws-c-s3 index 6eb8be530..169842b7e 160000 --- a/crt/aws-c-s3 +++ b/crt/aws-c-s3 @@ -1 +1 @@ -Subproject commit 6eb8be530b100fed5c6d24ca48a57ee2e6098fbf +Subproject commit 169842b7e2f81d71d0719d4a77f9c3e186512f99 diff --git a/crt/aws-lc b/crt/aws-lc index becf5785c..d3e6957b9 160000 --- a/crt/aws-lc +++ b/crt/aws-lc @@ -1 +1 @@ -Subproject commit becf5785c131012bb5a64f3da6cdb117ddc0f431 +Subproject commit d3e6957b9db2d9c587e77396d7b428139047ec31 diff --git a/crt/s2n b/crt/s2n index 21cefc109..4ed4f1a65 160000 --- a/crt/s2n +++ b/crt/s2n @@ -1 +1 @@ -Subproject commit 21cefc1091b3953ef543c9e72b932b6431fadc6e +Subproject commit 4ed4f1a658b70559ec4a18e91d1319daa14b0610 diff --git a/source/Types.cpp b/source/Types.cpp index de2ebf256..56de0eb0f 100644 --- a/source/Types.cpp +++ b/source/Types.cpp @@ -110,12 +110,8 @@ namespace Aws return {}; } - // encoding appends a null terminator, and accounts for it in the encoded length, - // which makes the string 1 character too long - if (outputStr.back() == 0) - { - outputStr.pop_back(); - } + AWS_ASSERT(outputStr.length() == tempBuf.len); + return outputStr; } } // namespace Crt From 4c48d1ec9894c44c11265e5c7b059ee35df6e797 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Mon, 17 Mar 2025 09:58:21 -0700 Subject: [PATCH 059/126] AutoTag PR for v0.31.1 (#716) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 26bea73e8..f176c9441 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.31.0 +0.31.1 From e43d14b9bbb029d8f6defd0b02ecf608c00b80ae Mon Sep 17 00:00:00 2001 From: Michael Graeb Date: Tue, 18 Mar 2025 12:00:07 -0700 Subject: [PATCH 060/126] Fix flaky CBOR test (#718) --- tests/CborTest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/CborTest.cpp b/tests/CborTest.cpp index f6fa95370..797b778de 100644 --- a/tests/CborTest.cpp +++ b/tests/CborTest.cpp @@ -184,8 +184,8 @@ static int s_decode_timestamp_helper(Cbor::CborDecoder &decoder, std::chrono::sy { double double_val = decoder.PopNextFloatVal().value(); std::chrono::duration timestamp(double_val); - outTimePoint = - std::chrono::system_clock::time_point(std::chrono::duration_cast(timestamp)); + outTimePoint = std::chrono::system_clock::time_point( + std::chrono::duration_cast(timestamp)); return AWS_OP_SUCCESS; } default: From 743ab3891c4fb015a74713b7b631c720ce0ffe8e Mon Sep 17 00:00:00 2001 From: Alex Weibel Date: Mon, 17 Mar 2025 16:40:01 -0700 Subject: [PATCH 061/126] Use latest PQ TLS Cipher Preference in Tests --- tests/HttpClientConnectionManagerTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/HttpClientConnectionManagerTest.cpp b/tests/HttpClientConnectionManagerTest.cpp index 3be4704d0..ccbd2d8d6 100644 --- a/tests/HttpClientConnectionManagerTest.cpp +++ b/tests/HttpClientConnectionManagerTest.cpp @@ -36,7 +36,7 @@ static int s_TestHttpClientConnectionManagerResourceSafety(struct aws_allocator // Ensure that if PQ TLS ciphers are supported on the current platform, that setting them works when connecting // to S3. This TlsCipherPreference has post quantum ciphers at the top of it's preference list (that will be // ignored if S3 doesn't support them) followed by regular TLS ciphers that can be chosen and negotiated by S3. - aws_tls_cipher_pref tls_cipher_pref = AWS_IO_TLS_CIPHER_PREF_PQ_TLSv1_0_2021_05; + aws_tls_cipher_pref tls_cipher_pref = AWS_IO_TLS_CIPHER_PREF_PQ_DEFAULT; if (aws_tls_is_cipher_pref_supported(tls_cipher_pref)) { From 059ee6dd748fdc47e71204fb5a1495a95e7861ee Mon Sep 17 00:00:00 2001 From: Michael Graeb Date: Mon, 24 Mar 2025 09:11:47 -0700 Subject: [PATCH 062/126] Fix "std-compat" CI to actually test what it's supposed to (#719) **Issue:** The "std-compat" CI isn't doing what it's supposed to: building aws-crt-cpp with different versions of the C++ std. It broke accidentally when [this commit](https://github.com/awslabs/aws-crt-cpp/commit/eaaaa60e3810ae33435c08c515f0be888e1af55d) stopped passing `--env CXXFLAGS` to the container. **Description of changes:** Fix it, so C++ version is passed to the container. Set it via `CMAKE_CXX_STANDARD=11`, instead of via `CXXFLAGS=-std=c++11`, since this is the "more correct" way to tell CMake the C++ standard you want. Doing it via `CXXFLAGS=-std=c++11` can (depending on the version of CMake you're using) force compiler extensions to be disabled. --- .github/workflows/ci.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f2039f271..2a567e50b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: - 'docs' env: - BUILDER_VERSION: v0.9.73 + BUILDER_VERSION: v0.9.76 BUILDER_SOURCE: releases BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net PACKAGE_NAME: aws-crt-cpp @@ -131,18 +131,17 @@ jobs: strategy: matrix: compiler: [gcc-8, clang-9] - std: [c++11, c++14, c++17, c++2a] + cxx-std: ["11", "14", "17", "20"] steps: - uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} # We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages - - name: Build ${{ env.PACKAGE_NAME }} with ${{ matrix.std }} + - name: Build ${{ env.PACKAGE_NAME }} with cxx${{ matrix.cxx-std }} run: | - export CXXFLAGS=-std=${{ matrix.std }} aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh - ./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --compiler=${{ matrix.compiler }} --cmake-extra=-DUSE_OPENSSL=ON + ./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --compiler=${{ matrix.compiler }} --cmake-extra=-DUSE_OPENSSL=ON --cmake-extra=-DCMAKE_CXX_STANDARD=${{ matrix.cxx-std }} byo-crypto: runs-on: ubuntu-24.04 # latest From 9ac418f76e39937cb2de125f2cc3197f8f261755 Mon Sep 17 00:00:00 2001 From: Michael Graeb Date: Thu, 27 Mar 2025 15:27:51 -0700 Subject: [PATCH 063/126] Fix IP address being labelled "bad" for too long (#723) Update submodules, bringing in this notable fix: - https://github.com/awslabs/aws-c-io/pull/718 ``` aws-c-auth v0.8.6 -> v0.9.0 aws-c-cal v0.8.7 -> v0.8.8 aws-c-common v0.12.0 -> v0.12.2 aws-c-io v0.17.0 -> v0.17.1 aws-checksums v0.2.3 -> v0.2.5 aws-lc v1.48.4 -> v1.48.5 s2n v1.5.14 -> v1.5.15 ``` --- crt/aws-c-auth | 2 +- crt/aws-c-cal | 2 +- crt/aws-c-common | 2 +- crt/aws-c-io | 2 +- crt/aws-checksums | 2 +- crt/aws-lc | 2 +- crt/s2n | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crt/aws-c-auth b/crt/aws-c-auth index 01dd06acd..cd9d6afcd 160000 --- a/crt/aws-c-auth +++ b/crt/aws-c-auth @@ -1 +1 @@ -Subproject commit 01dd06acd2b8865a4a6bc232380ee69a042af47d +Subproject commit cd9d6afcd42035d49bb2d0d3bef24b9faed57773 diff --git a/crt/aws-c-cal b/crt/aws-c-cal index d59c198db..4805a96e6 160000 --- a/crt/aws-c-cal +++ b/crt/aws-c-cal @@ -1 +1 @@ -Subproject commit d59c198db17c42a48e3ee105d12357f5a9efecf3 +Subproject commit 4805a96e694b07c89889de696418c429151f647a diff --git a/crt/aws-c-common b/crt/aws-c-common index 7fb0071ab..8ae8f48eb 160000 --- a/crt/aws-c-common +++ b/crt/aws-c-common @@ -1 +1 @@ -Subproject commit 7fb0071ab88182bffcc18a4a09bdb4dd2a5751d8 +Subproject commit 8ae8f48ebddb0ee2624d643952ac33afa5e8859e diff --git a/crt/aws-c-io b/crt/aws-c-io index 318f7e57e..46974e960 160000 --- a/crt/aws-c-io +++ b/crt/aws-c-io @@ -1 +1 @@ -Subproject commit 318f7e57e7871e5b0d48a281cc5dcb7f79ccecdd +Subproject commit 46974e960ab571c86e0711d4d9445e2e684b53bf diff --git a/crt/aws-checksums b/crt/aws-checksums index fb8bd0b8c..66b447c07 160000 --- a/crt/aws-checksums +++ b/crt/aws-checksums @@ -1 +1 @@ -Subproject commit fb8bd0b8cff00c8c24a35d601fce1b4c611df6da +Subproject commit 66b447c0765a2caff2d806111e6ec1db2383e4d2 diff --git a/crt/aws-lc b/crt/aws-lc index d3e6957b9..8a9ebcfdc 160000 --- a/crt/aws-lc +++ b/crt/aws-lc @@ -1 +1 @@ -Subproject commit d3e6957b9db2d9c587e77396d7b428139047ec31 +Subproject commit 8a9ebcfdcf8bb4a685ca83646265ea0aab85c3c8 diff --git a/crt/s2n b/crt/s2n index 4ed4f1a65..bb9c59918 160000 --- a/crt/s2n +++ b/crt/s2n @@ -1 +1 @@ -Subproject commit 4ed4f1a658b70559ec4a18e91d1319daa14b0610 +Subproject commit bb9c5991877c6a749981204131e6e47845adbe3d From 2810db4615613adc612c56425a4796ec4ff25281 Mon Sep 17 00:00:00 2001 From: Dmitriy Musatkin <63878209+DmitriyMusatkin@users.noreply.github.com> Date: Thu, 27 Mar 2025 17:28:31 -0700 Subject: [PATCH 064/126] Initialize checksums explicitly (#722) --- .github/workflows/ci.yml | 2 ++ CMakeLists.txt | 4 ++-- include/aws/crt/Exports.h | 9 ++++----- source/Api.cpp | 3 +++ 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2a567e50b..08e5cbe0b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,6 +65,7 @@ jobs: with: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} + role-duration-seconds: 7200 # 2 hours - name: Install qemu/docker run: docker run --privileged --rm tonistiigi/binfmt --install all - name: Build ${{ env.PACKAGE_NAME }} @@ -117,6 +118,7 @@ jobs: with: role-to-assume: ${{ env.CRT_CI_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} + role-duration-seconds: 7200 # 2 hours # set arm arch - name: Install qemu/docker run: docker run --privileged --rm tonistiigi/binfmt --install linux/arm/v7 diff --git a/CMakeLists.txt b/CMakeLists.txt index b0409fc9e..c7320e90a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,7 +124,7 @@ file(GLOB AWS_CRT_AUTH_HEADERS ) file(GLOB AWS_CRT_CHECKSUM_HEADERS - "include/aws/crt/checksum/*.h" + "include/aws/crt/checksums/*.h" ) file(GLOB AWS_CRT_CRYPTO_HEADERS @@ -333,7 +333,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC ${DEP_AWS_LIBS}) install(FILES ${AWS_CRT_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt" COMPONENT Development) install(FILES ${AWS_CRT_AUTH_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt/auth" COMPONENT Development) -install(FILES ${AWS_CRT_CHECKSUM_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt/checksum" COMPONENT Development) +install(FILES ${AWS_CRT_CHECKSUM_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt/checksums" COMPONENT Development) install(FILES ${AWS_CRT_CRYPTO_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt/crypto" COMPONENT Development) install(FILES ${AWS_CRT_IO_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt/io" COMPONENT Development) install(FILES ${AWS_CRT_IOT_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/iot" COMPONENT Development) diff --git a/include/aws/crt/Exports.h b/include/aws/crt/Exports.h index bd171dc73..61a595635 100644 --- a/include/aws/crt/Exports.h +++ b/include/aws/crt/Exports.h @@ -15,7 +15,7 @@ * permissions and limitations under the License. */ -#if defined(USE_WINDOWS_DLL_SEMANTICS) || defined(WIN32) +#if defined(AWS_CRT_USE_WINDOWS_DLL_SEMANTICS) || defined(_WIN32) # ifdef _MSC_VER # pragma warning(disable : 4251) # endif // _MSC_VER @@ -29,11 +29,10 @@ # define AWS_CRT_CPP_API # endif // AWS_CRT_CPP_USE_IMPORT_EXPORT -#else // defined (USE_WINDOWS_DLL_SEMANTICS) || defined (WIN32) -# if ((__GNUC__ >= 4) || defined(__clang__)) && defined(AWS_CRT_CPP_USE_IMPORT_EXPORT) && \ - defined(AWS_CRT_CPP_EXPORTS) +#else // defined (AWS_CRT_USE_WINDOWS_DLL_SEMANTICS) || defined (_WIN32) +# if defined(AWS_CRT_CPP_USE_IMPORT_EXPORT) && defined(AWS_CRT_CPP_EXPORTS) # define AWS_CRT_CPP_API __attribute__((visibility("default"))) # else # define AWS_CRT_CPP_API -# endif // __GNUC__ >= 4 || defined(__clang__) +# endif #endif diff --git a/source/Api.cpp b/source/Api.cpp index 7d6247512..c22576d8a 100644 --- a/source/Api.cpp +++ b/source/Api.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -48,6 +49,7 @@ namespace Aws aws_s3_library_init(allocator); aws_event_stream_library_init(allocator); aws_sdkutils_library_init(allocator); + aws_checksums_library_init(allocator); JsonObject::OnLibraryInit(); } @@ -78,6 +80,7 @@ namespace Aws aws_mqtt_library_clean_up(); aws_event_stream_library_clean_up(); aws_sdkutils_library_clean_up(); + aws_checksums_library_clean_up(); s_BYOCryptoNewMD5Callback = nullptr; s_BYOCryptoNewSHA256Callback = nullptr; From 4dfe7ebdee6d6c274479bd889a317c9707a9ab78 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Thu, 27 Mar 2025 17:29:11 -0700 Subject: [PATCH 065/126] AutoTag PR for v0.31.2 (#724) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index f176c9441..c415e1c6b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.31.1 +0.31.2 From d46785f1a2da8225885900eddcc70545a6a17a03 Mon Sep 17 00:00:00 2001 From: Dmitriy Musatkin <63878209+DmitriyMusatkin@users.noreply.github.com> Date: Fri, 28 Mar 2025 08:35:05 -0700 Subject: [PATCH 066/126] Revert checksums header install location change (#726) --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c7320e90a..b0409fc9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,7 +124,7 @@ file(GLOB AWS_CRT_AUTH_HEADERS ) file(GLOB AWS_CRT_CHECKSUM_HEADERS - "include/aws/crt/checksums/*.h" + "include/aws/crt/checksum/*.h" ) file(GLOB AWS_CRT_CRYPTO_HEADERS @@ -333,7 +333,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC ${DEP_AWS_LIBS}) install(FILES ${AWS_CRT_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt" COMPONENT Development) install(FILES ${AWS_CRT_AUTH_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt/auth" COMPONENT Development) -install(FILES ${AWS_CRT_CHECKSUM_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt/checksums" COMPONENT Development) +install(FILES ${AWS_CRT_CHECKSUM_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt/checksum" COMPONENT Development) install(FILES ${AWS_CRT_CRYPTO_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt/crypto" COMPONENT Development) install(FILES ${AWS_CRT_IO_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/crt/io" COMPONENT Development) install(FILES ${AWS_CRT_IOT_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/aws/iot" COMPONENT Development) From fca52044cac04906be9d7b99660f7f3c1e371601 Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Fri, 28 Mar 2025 08:35:38 -0700 Subject: [PATCH 067/126] AutoTag PR for v0.32.2 (#727) Co-authored-by: GitHub Actions --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index c415e1c6b..989b29cc3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.31.2 +0.32.2 From 2df6bee0c1775094d1671b92eaec37e30c4511de Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Fri, 28 Mar 2025 11:39:08 -0700 Subject: [PATCH 068/126] Fix assignment operator in Optional (#720) --- include/aws/crt/Optional.h | 147 ++++++++----------- include/aws/crt/TypeTraits.h | 30 ++++ tests/OptionalMemorySafetyTest.cpp | 224 ++++++++++++++++++++++++----- 3 files changed, 275 insertions(+), 126 deletions(-) create mode 100644 include/aws/crt/TypeTraits.h diff --git a/include/aws/crt/Optional.h b/include/aws/crt/Optional.h index 220b652d6..1a7e24a90 100644 --- a/include/aws/crt/Optional.h +++ b/include/aws/crt/Optional.h @@ -3,6 +3,7 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ +#include #include #include @@ -17,6 +18,8 @@ namespace Aws template class Optional { public: + using ValueType = T; + Optional() : m_value(nullptr) {} Optional(const T &val) { @@ -38,7 +41,15 @@ namespace Aws } } - template Optional &operator=(U &&u) + /** + * Assignment operator for a case when the parameter type is not Optional. + */ + template < + typename U = T, + typename std::enable_if< + !IsSpecializationOf::type, Aws::Crt::Optional>::value, + bool>::type = true> + Optional &operator=(U &&u) { if (m_value) { @@ -84,98 +95,11 @@ namespace Aws m_value = reinterpret_cast(m_storage); } - Optional &operator=(const Optional &other) - { - if (this == &other) - { - return *this; - } - - if (m_value) - { - if (other.m_value) - { - *m_value = *other.m_value; - } - else - { - m_value->~T(); - m_value = nullptr; - } - - return *this; - } - - if (other.m_value) - { - new (m_storage) T(*other.m_value); - m_value = reinterpret_cast(m_storage); - } - - return *this; - } - - template Optional &operator=(const Optional &other) - { - if (this == &other) - { - return *this; - } - - if (m_value) - { - if (other.m_value) - { - *m_value = *other.m_value; - } - else - { - m_value->~T(); - m_value = nullptr; - } - - return *this; - } - - if (other.m_value) - { - new (m_storage) T(*other.m_value); - m_value = reinterpret_cast(m_storage); - } - - return *this; - } - - template Optional &operator=(Optional &&other) - { - if (this == &other) - { - return *this; - } - - if (m_value) - { - if (other.m_value) - { - *m_value = std::forward(*other.m_value); - } - else - { - m_value->~T(); - m_value = nullptr; - } - - return *this; - } + Optional &operator=(const Optional &other) { return assign(other); } - if (other.m_value) - { - new (m_storage) T(std::forward(*other.m_value)); - m_value = reinterpret_cast(m_storage); - } + template Optional &operator=(const Optional &other) { return assign(other); } - return *this; - } + template Optional &operator=(Optional &&other) { return assign(std::move(other)); } template T &emplace(Args &&...args) { @@ -213,6 +137,47 @@ namespace Aws } private: + template Optional &assign(Op &&other) + { + // U is an underlying type of the Optional type passed to this function. Depending on constness of Op, + // U will be either value or const ref. + // NOTE: std::is_const == false, that's why std::remove_reference is needed here. + using U = typename std::conditional< + std::is_const::type>::value, + const typename std::decay::type::ValueType &, + typename std::decay::type::ValueType>::type; + + if ((void *)this == (void *)&other) + { + return *this; + } + + if (m_value) + { + // Optional is a completely different class from the C++ specifics pov. So, we can use only + // public members of `other`. + if (other.has_value()) + { + *m_value = std::forward(other.value()); + } + else + { + m_value->~T(); + m_value = nullptr; + } + + return *this; + } + + if (other.has_value()) + { + new (m_storage) T(std::forward(other.value())); + m_value = reinterpret_cast(m_storage); + } + + return *this; + } + alignas(T) char m_storage[sizeof(T)]; T *m_value; }; diff --git a/include/aws/crt/TypeTraits.h b/include/aws/crt/TypeTraits.h new file mode 100644 index 000000000..72ed9d9a6 --- /dev/null +++ b/include/aws/crt/TypeTraits.h @@ -0,0 +1,30 @@ +#pragma once +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include + +namespace Aws +{ + namespace Crt + { + /** + * A type trait for determining if the first template parameter is a template specialization of the second + * template parameter. Based on p2098 (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2098r1.pdf). + * + * @note Known limitations: does not support template classes with non-type template parameter, e.g. std::array. + */ + template class Primary> struct IsSpecializationOf : std::false_type + { + }; + + /* Specialization for the case when the first template parameter is a template specialization of the second + * template parameter. */ + template