Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package aws-crt-cpp for openSUSE:Factory checked in at 2026-04-11 22:26:53 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/aws-crt-cpp (Old) and /work/SRC/openSUSE:Factory/.aws-crt-cpp.new.21863 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "aws-crt-cpp" Sat Apr 11 22:26:53 2026 rev:50 rq:1346082 version:0.38.4 Changes: -------- --- /work/SRC/openSUSE:Factory/aws-crt-cpp/aws-crt-cpp.changes 2026-04-09 16:25:02.947263383 +0200 +++ /work/SRC/openSUSE:Factory/.aws-crt-cpp.new.21863/aws-crt-cpp.changes 2026-04-11 22:32:34.087590434 +0200 @@ -1,0 +2,9 @@ +Fri Apr 10 08:48:06 UTC 2026 - John Paul Adrian Glaubitz <[email protected]> + +- Update to version 0.38.4 + * fix(http): use user-provided ClientBootstrap in HttpConnection + by @abhu85 in (#823) + * Unified write data API binding by @azkrishpy in (#839) + * bump version af aws-c-s3 by @sbiscigl in (#841) + +------------------------------------------------------------------- Old: ---- v0.38.3.tar.gz New: ---- v0.38.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ aws-crt-cpp.spec ++++++ --- /var/tmp/diff_new_pack.6yaM5u/_old 2026-04-11 22:32:34.639613011 +0200 +++ /var/tmp/diff_new_pack.6yaM5u/_new 2026-04-11 22:32:34.643613175 +0200 @@ -20,7 +20,7 @@ %define library_soversion 1 Name: aws-crt-cpp -Version: 0.38.3 +Version: 0.38.4 Release: 0 Summary: AWS C++ wrapper for AWS SDK C libraries License: Apache-2.0 ++++++ v0.38.3.tar.gz -> v0.38.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-crt-cpp-0.38.3/VERSION new/aws-crt-cpp-0.38.4/VERSION --- old/aws-crt-cpp-0.38.3/VERSION 2026-03-30 22:52:19.000000000 +0200 +++ new/aws-crt-cpp-0.38.4/VERSION 2026-04-02 22:17:06.000000000 +0200 @@ -1 +1 @@ -0.38.3 +0.38.4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-crt-cpp-0.38.3/include/aws/crt/http/HttpConnection.h new/aws-crt-cpp-0.38.4/include/aws/crt/http/HttpConnection.h --- old/aws-crt-cpp-0.38.3/include/aws/crt/http/HttpConnection.h 2026-03-30 22:52:19.000000000 +0200 +++ new/aws-crt-cpp-0.38.4/include/aws/crt/http/HttpConnection.h 2026-04-02 22:17:06.000000000 +0200 @@ -10,6 +10,7 @@ #include <aws/crt/Types.h> #include <aws/crt/io/Bootstrap.h> #include <aws/crt/io/SocketOptions.h> +#include <aws/crt/io/Stream.h> #include <aws/crt/io/TlsOptions.h> #include <functional> @@ -118,6 +119,27 @@ * See `OnStreamComplete` for more info. This value can be empty. */ OnStreamComplete onStreamComplete; + + /** + * When true, request body data will be provided over time via `HttpClientStream::WriteData()` + * The stream will only be polled for writing when data has been supplied. + * When false (default), the entire request body is read from the input stream immediately. + * + * HTTP/1.1 requirements: + * - SHOULD have either `Content-Length` OR `Transfer-Encoding: chunked` header (but not both). + * Fails with AWS_ERROR_HTTP_INVALID_HEADER_FIELD if both are set. + * Transfer-Encoding: chunked header will be automatically added if neither header is set. + * - MUST NOT have a body stream set. Fails with AWS_ERROR_HTTP_INVALID_HEADER_FIELD otherwise. + * - With `Content-Length`: total bytes written must exactly match the declared length. + * Fails with AWS_ERROR_HTTP_OUTGOING_STREAM_LENGTH_INCORRECT if data exceeds Content-Length, + * or if `end_stream` is set before enough data is written. + * - With `Transfer-Encoding: chunked`: no length validation, data sent as chunks. + * + * HTTP/2: No `Content-Length` or `Transfer-Encoding` header required. Data sent via DATA frames. + * Note: When this variable is set, we expect request to be ended with a data write with + * end_stream=true. + */ + bool UseManualDataWrites = false; }; /** @@ -191,6 +213,8 @@ std::shared_ptr<HttpStream> stream; }; + using OnWriteDataComplete = std::function<void(std::shared_ptr<HttpStream> &stream, int errorCode)>; + /** * Subclass that represents an http client's view of an HttpStream. */ @@ -216,6 +240,11 @@ */ bool Activate() noexcept; + int WriteData( + std::shared_ptr<Aws::Crt::Io::InputStream> stream, + const OnWriteDataComplete &onComplete, + bool endStream = false) noexcept; + private: HttpClientStream(const std::shared_ptr<HttpClientConnection> &connection) noexcept; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-crt-cpp-0.38.3/source/http/HttpConnection.cpp new/aws-crt-cpp-0.38.4/source/http/HttpConnection.cpp --- old/aws-crt-cpp-0.38.3/source/http/HttpConnection.cpp 2026-03-30 22:52:19.000000000 +0200 +++ new/aws-crt-cpp-0.38.4/source/http/HttpConnection.cpp 2026-04-02 22:17:06.000000000 +0200 @@ -133,7 +133,7 @@ AWS_ZERO_STRUCT(options); options.self_size = sizeof(aws_http_client_connection_options); - if (options.bootstrap != nullptr) + if (connectionOptions.Bootstrap != nullptr) { options.bootstrap = connectionOptions.Bootstrap->GetUnderlyingHandle(); } @@ -202,6 +202,7 @@ options.on_response_headers = HttpStream::s_onIncomingHeaders; options.on_response_header_block_done = HttpStream::s_onIncomingHeaderBlockDone; options.on_complete = HttpStream::s_onStreamComplete; + options.use_manual_data_writes = requestOptions.UseManualDataWrites; /* Do the same ref counting trick we did with HttpClientConnection. We need to maintain a reference * internally (regardless of what the user does), until the Stream shuts down. */ @@ -361,6 +362,35 @@ return true; } + struct OnWriteUserData + { + Aws::Crt::Http::OnWriteDataComplete callback; + Aws::Crt::Http::ClientStreamCallbackData callbackData; + }; + + int HttpClientStream::WriteData( + std::shared_ptr<Aws::Crt::Io::InputStream> stream, + const OnWriteDataComplete &onComplete, + bool endStream) noexcept + { + aws_http_stream_write_data_options options{}; + options.data = stream->GetUnderlyingStream(); + options.end_stream = endStream; + options.on_complete = +[](struct aws_http_stream *, int error_code, void *user_data) + { + auto *userData = static_cast<OnWriteUserData *>(user_data); + userData->callback(userData->callbackData.stream, error_code); + Aws::Crt::Delete(userData, userData->callbackData.allocator); + }; + + auto *data = Aws::Crt::New<OnWriteUserData>(m_callbackData.allocator); + data->callback = onComplete; + data->callbackData = m_callbackData; + options.user_data = data; + + return aws_http_stream_write_data(m_stream, &options); + } + void HttpStream::UpdateWindow(std::size_t incrementSize) noexcept { aws_http_stream_update_window(m_stream, incrementSize); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-crt-cpp-0.38.3/tests/CMakeLists.txt new/aws-crt-cpp-0.38.4/tests/CMakeLists.txt --- old/aws-crt-cpp-0.38.3/tests/CMakeLists.txt 2026-03-30 22:52:19.000000000 +0200 +++ new/aws-crt-cpp-0.38.4/tests/CMakeLists.txt 2026-04-02 22:17:06.000000000 +0200 @@ -82,6 +82,7 @@ add_net_test_case(HttpDownloadNoBackPressureHTTP2) add_net_test_case(HttpStreamUnActivated) add_net_test_case(HttpCreateConnectionInvalidTlsConnectionOptions) + add_net_test_case(HttpCreateConnectionCustomBootstrapRespected) add_net_test_case(IotPublishSubscribe) add_net_test_case(IotConnectionSuccessTest) add_net_test_case(IotConnectionFailureTest) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-crt-cpp-0.38.3/tests/HttpClientTest.cpp new/aws-crt-cpp-0.38.4/tests/HttpClientTest.cpp --- old/aws-crt-cpp-0.38.3/tests/HttpClientTest.cpp 2026-03-30 22:52:19.000000000 +0200 +++ new/aws-crt-cpp-0.38.4/tests/HttpClientTest.cpp 2026-04-02 22:17:06.000000000 +0200 @@ -8,6 +8,7 @@ #include <aws/crt/http/HttpRequestResponse.h> #include <aws/crt/io/Uri.h> +#include <aws/io/event_loop.h> #include <aws/testing/aws_test_harness.h> #include <condition_variable> @@ -391,4 +392,123 @@ AWS_TEST_CASE(HttpCreateConnectionInvalidTlsConnectionOptions, s_TestHttpCreateConnectionInvalidTlsConnectionOptions) +/* + * Verify that CreateConnection uses the user-provided bootstrap, not the static default. + * + * We create a custom bootstrap backed by its own EventLoopGroup, connect, and check + * that the setup callback runs on a thread belonging to our custom ELG. + * + * NOTE: This requires network access because CreateConnection opens a real socket. + * If more tests like this accumulate, consider adding a localhost mock HTTP server + * for the C++ test layer so they can run without network. + */ +static int s_TestHttpCreateConnectionCustomBootstrapRespected(struct aws_allocator *allocator, void *ctx) +{ + (void)ctx; + { + Aws::Crt::ApiHandle apiHandle(allocator); + + Aws::Crt::Io::TlsContextOptions tlsCtxOptions = Aws::Crt::Io::TlsContextOptions::InitDefaultClient(); + Aws::Crt::Io::TlsContext tlsContext(tlsCtxOptions, Aws::Crt::Io::TlsMode::CLIENT, allocator); + ASSERT_TRUE(tlsContext); + + ByteCursor hostName = ByteCursorFromCString("aws-crt-test-stuff.s3.amazonaws.com"); + Aws::Crt::Io::TlsConnectionOptions tlsConnectionOptions = tlsContext.NewConnectionOptions(); + tlsConnectionOptions.SetServerName(hostName); + + Aws::Crt::Io::SocketOptions socketOptions; + socketOptions.SetConnectTimeoutMs(5000); + + Aws::Crt::Io::EventLoopGroup customElg(1, allocator); + ASSERT_TRUE(customElg); + + Aws::Crt::Io::DefaultHostResolver customResolver(customElg, 8, 30, allocator); + ASSERT_TRUE(customResolver); + + Aws::Crt::Io::ClientBootstrap customBootstrap(customElg, customResolver, allocator); + ASSERT_TRUE(customBootstrap); + customBootstrap.EnableBlockingShutdown(); + + ASSERT_TRUE( + customBootstrap.GetUnderlyingHandle() != + ApiHandle::GetOrCreateStaticDefaultClientBootstrap()->GetUnderlyingHandle()); + + std::shared_ptr<Http::HttpClientConnection> connection(nullptr); + bool errorOccured = true; + bool connectionShutdown = false; + bool usedCorrectEventLoop = false; + + std::condition_variable semaphore; + std::mutex semaphoreLock; + + auto onConnectionSetup = [&](const std::shared_ptr<Http::HttpClientConnection> &newConnection, int errorCode) + { + std::lock_guard<std::mutex> lockGuard(semaphoreLock); + + if (!errorCode) + { + connection = newConnection; + errorOccured = false; + + /* Setup callback runs on the connection's event loop thread. + * Verify it belongs to our custom ELG, not the static default. */ + struct aws_event_loop_group *rawElg = customElg.GetUnderlyingHandle(); + size_t loopCount = aws_event_loop_group_get_loop_count(rawElg); + for (size_t i = 0; i < loopCount; i++) + { + if (aws_event_loop_thread_is_callers_thread(aws_event_loop_group_get_loop_at(rawElg, i))) + { + usedCorrectEventLoop = true; + break; + } + } + } + else + { + connectionShutdown = true; + } + + semaphore.notify_one(); + }; + + auto onConnectionShutdown = [&](Http::HttpClientConnection &, int errorCode) + { + std::lock_guard<std::mutex> lockGuard(semaphoreLock); + + connectionShutdown = true; + if (errorCode) + { + errorOccured = true; + } + + semaphore.notify_one(); + }; + + Http::HttpClientConnectionOptions httpClientConnectionOptions; + httpClientConnectionOptions.Bootstrap = &customBootstrap; + httpClientConnectionOptions.OnConnectionSetupCallback = onConnectionSetup; + httpClientConnectionOptions.OnConnectionShutdownCallback = onConnectionShutdown; + httpClientConnectionOptions.SocketOptions = socketOptions; + httpClientConnectionOptions.TlsOptions = tlsConnectionOptions; + httpClientConnectionOptions.HostName = String((const char *)hostName.ptr, hostName.len); + httpClientConnectionOptions.Port = 443; + + std::unique_lock<std::mutex> semaphoreULock(semaphoreLock); + ASSERT_TRUE(Http::HttpClientConnection::CreateConnection(httpClientConnectionOptions, allocator)); + semaphore.wait(semaphoreULock, [&]() { return connection || connectionShutdown; }); + + ASSERT_FALSE(errorOccured); + ASSERT_FALSE(connectionShutdown); + ASSERT_TRUE(connection); + ASSERT_TRUE(usedCorrectEventLoop); + + connection->Close(); + semaphore.wait(semaphoreULock, [&]() { return connectionShutdown; }); + } + + return AWS_OP_SUCCESS; +} + +AWS_TEST_CASE(HttpCreateConnectionCustomBootstrapRespected, s_TestHttpCreateConnectionCustomBootstrapRespected) + #endif // !BYO_CRYPTO
