From a08a1fa5f9355a7d27b618381d3a1e77f3b32a54 Mon Sep 17 00:00:00 2001 From: Lorenzo Mangani Date: Tue, 7 Jul 2026 19:15:10 +0200 Subject: [PATCH 1/2] Port httpserver extension to DuckDB v1.5.4. Update duckdb and extension-ci-tools submodules, pin CI workflows to v1.5.4, and fix a crash in httpserve_start caused by a dangling ExtensionLoader reference. --- .github/workflows/MainDistributionPipeline.yml | 6 +++--- duckdb | 2 +- extension-ci-tools | 2 +- src/httpserver_extension.cpp | 5 +++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/MainDistributionPipeline.yml b/.github/workflows/MainDistributionPipeline.yml index 5150537..a6d8795 100644 --- a/.github/workflows/MainDistributionPipeline.yml +++ b/.github/workflows/MainDistributionPipeline.yml @@ -13,8 +13,8 @@ concurrency: jobs: duckdb-stable-build: name: Build extension binaries - uses: duckdb/extension-ci-tools/.github/workflows/_extension_distribution.yml@main + uses: duckdb/extension-ci-tools/.github/workflows/_extension_distribution.yml@v1.5.4 with: - duckdb_version: main - ci_tools_version: main + duckdb_version: v1.5.4 + ci_tools_version: v1.5.4 extension_name: httpserver diff --git a/duckdb b/duckdb index 7d45b33..08e34c4 160000 --- a/duckdb +++ b/duckdb @@ -1 +1 @@ -Subproject commit 7d45b33a308f787d7e09346ee76ea403bd140da5 +Subproject commit 08e34c447bae34eaee3723cac61f2878b6bdf787 diff --git a/extension-ci-tools b/extension-ci-tools index fccd748..b777c70 160000 --- a/extension-ci-tools +++ b/extension-ci-tools @@ -1 +1 @@ -Subproject commit fccd748f513d018a6cb2b6e4223cec85aaa280fc +Subproject commit b777c70d30942cca5bef62d6d4fa23a13362f398 diff --git a/src/httpserver_extension.cpp b/src/httpserver_extension.cpp index d903b8c..4d952c2 100644 --- a/src/httpserver_extension.cpp +++ b/src/httpserver_extension.cpp @@ -580,9 +580,10 @@ namespace duckdb static void LoadInternal(ExtensionLoader &loader) { + auto db = loader.GetDatabaseInstance().shared_from_this(); auto httpserve_start = ScalarFunction( "httpserve_start", {LogicalType::VARCHAR, LogicalType::INTEGER, LogicalType::VARCHAR}, LogicalType::VARCHAR, - [&](DataChunk &args, ExpressionState &state, Vector &result) + [db](DataChunk &args, ExpressionState &state, Vector &result) { auto &host_vector = args.data[0]; auto &port_vector = args.data[1]; @@ -592,7 +593,7 @@ namespace duckdb { auto port = ((int32_t *)port_vector.GetData())[0]; auto auth = ((string_t *)auth_vector.GetData())[0]; - HttpServerStart(loader.GetDatabaseInstance().shared_from_this(), host, port, auth); + HttpServerStart(db, host, port, auth); return StringVector::AddString(result, "HTTP server started on " + host.GetString() + ":" + std::to_string(port)); }); }); From 63eb094231cad1c2dd398aa7c37cb594fb4ad185 Mon Sep 17 00:00:00 2001 From: Lorenzo Mangani Date: Tue, 7 Jul 2026 20:07:10 +0200 Subject: [PATCH 2/2] Fix Linux CI segfault by using synchronous httplib task queue. OpenSSL-enabled httplib runs request handlers in a thread pool by default, which can crash with statically linked OpenSSL on Linux amd64. Handle requests on the server thread instead. --- src/httpserver_extension.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/httpserver_extension.cpp b/src/httpserver_extension.cpp index 4d952c2..7f0ecc9 100644 --- a/src/httpserver_extension.cpp +++ b/src/httpserver_extension.cpp @@ -26,6 +26,23 @@ namespace duckdb using namespace duckdb_yyjson; // NOLINT(*-build-using-namespace) + // httplib defaults to a thread pool when OpenSSL is enabled. With statically + // linked OpenSSL on Linux this can segfault in worker threads, so handle + // requests synchronously on the server thread instead. + class SynchronousTaskQueue : public duckdb_httplib_openssl::TaskQueue + { + public: + bool enqueue(std::function fn) override + { + fn(); + return true; + } + + void shutdown() override + { + } + }; + struct HttpServerState { std::unique_ptr server; @@ -384,6 +401,12 @@ namespace duckdb std::string error_message = "DB::Exception: " + std::string(ex.what()); res.set_content(error_message, "text/plain"); } + catch (const std::exception &ex) + { + res.status = 500; + std::string error_message = "DB::Exception: " + std::string(ex.what()); + res.set_content(error_message, "text/plain"); + } } void HttpServerStart(shared_ptr db, string_t host, int32_t port, string_t auth = string_t()) @@ -395,6 +418,7 @@ namespace duckdb global_state.db_instance = db; global_state.server = make_uniq(); + global_state.server->new_task_queue = []() { return new SynchronousTaskQueue(); }; global_state.is_running = true; global_state.auth_token = auth.GetString();