From 7a619f806c7f9131953859b6c55210aa462d70be Mon Sep 17 00:00:00 2001 From: Yves Date: Wed, 12 Mar 2025 15:26:03 +0100 Subject: [PATCH] Allow to configure listening interface --- src/http_server.cpp | 15 ++++++++++----- src/include/http_server.hpp | 4 +++- src/include/settings.hpp | 3 +++ src/settings.cpp | 4 ++++ src/ui_extension.cpp | 8 ++++++++ 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/http_server.cpp b/src/http_server.cpp index 954365c..7528cb2 100644 --- a/src/http_server.cpp +++ b/src/http_server.cpp @@ -64,7 +64,8 @@ bool HttpServer::IsRunningOnMachine(ClientContext &context) { } const auto local_port = GetLocalPort(context); - auto local_url = StringUtil::Format("http://localhost:%d", local_port); + const auto local_host = GetLocalHost(context); + auto local_url = StringUtil::Format("http://%s:%d", local_host, local_port); httplib::Client client(local_url); return client.Get("/info"); @@ -94,19 +95,22 @@ const HttpServer &HttpServer::Start(ClientContext &context, bool *was_started) { const auto remote_url = GetRemoteUrl(context); const auto port = GetLocalPort(context); + const auto host = GetLocalHost(context); auto server = GetInstance(context); - server->DoStart(port, remote_url); + server->DoStart(port, host, remote_url); return *server; } void HttpServer::DoStart(const uint16_t _local_port, + const std::string &_local_host, const std::string &_remote_url) { if (Started()) { throw std::runtime_error("HttpServer already started"); } local_port = _local_port; - local_url = StringUtil::Format("http://localhost:%d", local_port); + local_host = _local_host; + local_url = StringUtil::Format("http://%s:%d", local_host, local_port); remote_url = _remote_url; user_agent = StringUtil::Format("duckdb-ui/%s-%s(%s)", DuckDB::LibraryVersion(), @@ -146,10 +150,11 @@ void HttpServer::DoStop() { ddb_instance.reset(); remote_url = ""; local_port = 0; + local_host = ""; } std::string HttpServer::LocalUrl() const { - return StringUtil::Format("http://localhost:%d/", local_port); + return StringUtil::Format("http://%s:%d/", local_host, local_port); } shared_ptr HttpServer::LockDatabaseInstance() { @@ -185,7 +190,7 @@ void HttpServer::Run() { const httplib::ContentReader &content_reader) { HandleTokenize(req, res, content_reader); }); - server.listen("localhost", local_port); + server.listen(local_host, local_port); } void HttpServer::HandleGetInfo(const httplib::Request &req, diff --git a/src/include/http_server.hpp b/src/include/http_server.hpp index 041ad01..323298d 100644 --- a/src/include/http_server.hpp +++ b/src/include/http_server.hpp @@ -40,7 +40,8 @@ class HttpServer { friend class Watcher; // Lifecycle - void DoStart(const uint16_t local_port, const std::string &remote_url); + void DoStart(const uint16_t local_port, const std::string &local_host, + const std::string &remote_url); void DoStop(); void Run(); void UpdateDatabaseInstance(shared_ptr context_db); @@ -69,6 +70,7 @@ class HttpServer { shared_ptr LockDatabaseInstance(); uint16_t local_port; + std::string local_host; std::string local_url; std::string remote_url; weak_ptr ddb_instance; diff --git a/src/include/settings.hpp b/src/include/settings.hpp index b9bdd88..6a0c1ba 100644 --- a/src/include/settings.hpp +++ b/src/include/settings.hpp @@ -5,6 +5,8 @@ #define UI_LOCAL_PORT_SETTING_NAME "ui_local_port" #define UI_LOCAL_PORT_SETTING_DEFAULT 4213 +#define UI_LOCAL_HOST_SETTING_NAME "ui_local_host" +#define UI_LOCAL_HOST_SETTING_DEFAULT "localhost" #define UI_REMOTE_URL_SETTING_NAME "ui_remote_url" #define UI_REMOTE_URL_SETTING_DEFAULT "https://ui.duckdb.org" #define UI_POLLING_INTERVAL_SETTING_NAME "ui_polling_interval" @@ -27,6 +29,7 @@ T GetSetting(const ClientContext &context, const char *setting_name) { std::string GetRemoteUrl(const ClientContext &); uint16_t GetLocalPort(const ClientContext &); +std::string GetLocalHost(const ClientContext &); uint32_t GetPollingInterval(const ClientContext &); } // namespace duckdb diff --git a/src/settings.cpp b/src/settings.cpp index e08aa59..d1af658 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -15,6 +15,10 @@ uint16_t GetLocalPort(const ClientContext &context) { return internal::GetSetting(context, UI_LOCAL_PORT_SETTING_NAME); } +std::string GetLocalHost(const ClientContext &context) { + return internal::GetSetting(context, UI_LOCAL_HOST_SETTING_NAME); +} + uint32_t GetPollingInterval(const ClientContext &context) { return internal::GetSetting(context, UI_POLLING_INTERVAL_SETTING_NAME); diff --git a/src/ui_extension.cpp b/src/ui_extension.cpp index ed1d2d0..4e7c0a3 100644 --- a/src/ui_extension.cpp +++ b/src/ui_extension.cpp @@ -93,6 +93,14 @@ static void LoadInternal(DatabaseInstance &instance) { LogicalType::USMALLINT, Value::USMALLINT(default_port)); } + { + auto default_host = GetEnvOrDefault(UI_LOCAL_HOST_SETTING_NAME, + UI_LOCAL_HOST_SETTING_DEFAULT); + config.AddExtensionOption(UI_LOCAL_HOST_SETTING_NAME, + "Local host on which the UI server listens", + LogicalType::VARCHAR, Value(default_host)); + } + { auto def = GetEnvOrDefault(UI_REMOTE_URL_SETTING_NAME, UI_REMOTE_URL_SETTING_DEFAULT);