This is an automated email from the ASF dual-hosted git repository. morningman pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new 355620b84dc [Enhancement](http)Add http authentication to all API interfaces under be 8040. (#39577) 355620b84dc is described below commit 355620b84dcf9d09515c3f81dd50e1aac27699f5 Author: daidai <2017501...@qq.com> AuthorDate: Fri Aug 23 12:35:13 2024 +0800 [Enhancement](http)Add http authentication to all API interfaces under be 8040. (#39577) Add http authentication to all API interfaces under be 8040 The `enable_all_http_auth parameter` in be.conf can control the switch. --- be/src/cloud/cloud_compaction_action.cpp | 6 +- be/src/cloud/cloud_compaction_action.h | 2 +- be/src/http/action/adjust_log_level.h | 7 +- be/src/http/action/adjust_tracing_dump.h | 7 +- be/src/http/action/be_proc_thread_action.h | 7 +- be/src/http/action/clear_cache_action.h | 7 +- be/src/http/action/compaction_action.cpp | 6 +- be/src/http/action/compaction_action.h | 2 +- be/src/http/action/config_action.cpp | 6 +- be/src/http/action/config_action.h | 9 +- be/src/http/action/download_action.cpp | 4 +- be/src/http/action/download_action.h | 4 +- be/src/http/action/download_binlog_action.cpp | 4 +- be/src/http/action/download_binlog_action.h | 5 +- be/src/http/action/file_cache_action.h | 6 +- be/src/http/action/health_action.cpp | 2 - be/src/http/action/health_action.h | 7 +- be/src/http/action/jeprofile_actions.cpp | 8 +- be/src/http/action/load_stream_action.h | 5 +- be/src/http/action/pipeline_task_action.h | 15 +- be/src/http/action/pprof_actions.cpp | 55 ++++--- be/src/http/action/reset_rpc_channel_action.cpp | 1 - be/src/http/action/show_hotspot_action.h | 7 +- be/src/http/action/shrink_mem_action.h | 5 +- be/src/http/http_handler_with_auth.cpp | 13 +- be/src/http/http_handler_with_auth.h | 7 +- be/src/http/web_page_handler.cpp | 3 +- be/src/http/web_page_handler.h | 5 +- be/src/service/http_service.cpp | 37 +++-- be/test/http/http_client_test.cpp | 200 ++++++++++++++++++++++++ be/test/testutil/run_all_tests.cpp | 11 +- 31 files changed, 355 insertions(+), 108 deletions(-) diff --git a/be/src/cloud/cloud_compaction_action.cpp b/be/src/cloud/cloud_compaction_action.cpp index 012a5ff7e3d..13161c32c8e 100644 --- a/be/src/cloud/cloud_compaction_action.cpp +++ b/be/src/cloud/cloud_compaction_action.cpp @@ -62,7 +62,7 @@ const static std::string HEADER_JSON = "application/json"; CloudCompactionAction::CloudCompactionAction(CompactionActionType ctype, ExecEnv* exec_env, CloudStorageEngine& engine, TPrivilegeHier::type hier, TPrivilegeType::type ptype) - : HttpHandlerWithAuth(exec_env, hier, ptype), _engine(engine), _type(ctype) {} + : HttpHandlerWithAuth(exec_env, hier, ptype), _engine(engine), _compaction_type(ctype) {} /// check param and fetch tablet_id & table_id from req static Status _check_param(HttpRequest* req, uint64_t* tablet_id, uint64_t* table_id) { @@ -233,7 +233,7 @@ Status CloudCompactionAction::_handle_run_status_compaction(HttpRequest* req, void CloudCompactionAction::handle(HttpRequest* req) { req->add_output_header(HttpHeaders::CONTENT_TYPE, HEADER_JSON.c_str()); - if (_type == CompactionActionType::SHOW_INFO) { + if (_compaction_type == CompactionActionType::SHOW_INFO) { std::string json_result; Status st = _handle_show_compaction(req, &json_result); if (!st.ok()) { @@ -241,7 +241,7 @@ void CloudCompactionAction::handle(HttpRequest* req) { } else { HttpChannel::send_reply(req, HttpStatus::OK, json_result); } - } else if (_type == CompactionActionType::RUN_COMPACTION) { + } else if (_compaction_type == CompactionActionType::RUN_COMPACTION) { std::string json_result; Status st = _handle_run_compaction(req, &json_result); if (!st.ok()) { diff --git a/be/src/cloud/cloud_compaction_action.h b/be/src/cloud/cloud_compaction_action.h index 648d00d9203..026426826d8 100644 --- a/be/src/cloud/cloud_compaction_action.h +++ b/be/src/cloud/cloud_compaction_action.h @@ -70,7 +70,7 @@ private: private: CloudStorageEngine& _engine; - CompactionActionType _type; + CompactionActionType _compaction_type; }; } // end namespace doris diff --git a/be/src/http/action/adjust_log_level.h b/be/src/http/action/adjust_log_level.h index 606d6129a26..0176774cf75 100644 --- a/be/src/http/action/adjust_log_level.h +++ b/be/src/http/action/adjust_log_level.h @@ -20,15 +20,16 @@ #include <string> #include "common/status.h" -#include "http/http_handler.h" +#include "http/http_handler_with_auth.h" namespace doris { class HttpRequest; +class ExecEnv; -class AdjustLogLevelAction : public HttpHandler { +class AdjustLogLevelAction : public HttpHandlerWithAuth { public: - AdjustLogLevelAction() = default; + AdjustLogLevelAction(ExecEnv* exec_env) : HttpHandlerWithAuth(exec_env) {} ~AdjustLogLevelAction() override = default; diff --git a/be/src/http/action/adjust_tracing_dump.h b/be/src/http/action/adjust_tracing_dump.h index d82d8b1e55b..7fe29690dfe 100644 --- a/be/src/http/action/adjust_tracing_dump.h +++ b/be/src/http/action/adjust_tracing_dump.h @@ -17,15 +17,16 @@ #pragma once -#include "http/http_handler.h" +#include "http/http_handler_with_auth.h" namespace doris { class HttpRequest; +class ExecEnv; -class AdjustTracingDump : public HttpHandler { +class AdjustTracingDump : public HttpHandlerWithAuth { public: - AdjustTracingDump() = default; + AdjustTracingDump(ExecEnv* exec_env) : HttpHandlerWithAuth(exec_env) {} ~AdjustTracingDump() override = default; diff --git a/be/src/http/action/be_proc_thread_action.h b/be/src/http/action/be_proc_thread_action.h index 923bc3f56d9..f1ad8198d7f 100644 --- a/be/src/http/action/be_proc_thread_action.h +++ b/be/src/http/action/be_proc_thread_action.h @@ -16,16 +16,17 @@ // under the License. #pragma once -#include "http/http_handler.h" +#include "http/http_handler_with_auth.h" #include "http/http_request.h" namespace doris { class HttpRequest; +class ExecEnv; -class BeProcThreadAction : public HttpHandler { +class BeProcThreadAction : public HttpHandlerWithAuth { public: - BeProcThreadAction() = default; + BeProcThreadAction(ExecEnv* exec_env) : HttpHandlerWithAuth(exec_env) {} ~BeProcThreadAction() override = default; void handle(HttpRequest* req) override; }; diff --git a/be/src/http/action/clear_cache_action.h b/be/src/http/action/clear_cache_action.h index 3795a87b5d7..40233be1fb8 100644 --- a/be/src/http/action/clear_cache_action.h +++ b/be/src/http/action/clear_cache_action.h @@ -17,15 +17,16 @@ #pragma once -#include "http/http_handler.h" +#include "http/http_handler_with_auth.h" namespace doris { class HttpRequest; +class ExecEnv; -class ClearCacheAction : public HttpHandler { +class ClearCacheAction : public HttpHandlerWithAuth { public: - ClearCacheAction() = default; + ClearCacheAction(ExecEnv* exec_env) : HttpHandlerWithAuth(exec_env) {} ~ClearCacheAction() override = default; diff --git a/be/src/http/action/compaction_action.cpp b/be/src/http/action/compaction_action.cpp index c3fb5638c7c..05ec2591c32 100644 --- a/be/src/http/action/compaction_action.cpp +++ b/be/src/http/action/compaction_action.cpp @@ -59,7 +59,7 @@ constexpr std::string_view HEADER_JSON = "application/json"; CompactionAction::CompactionAction(CompactionActionType ctype, ExecEnv* exec_env, StorageEngine& engine, TPrivilegeHier::type hier, TPrivilegeType::type ptype) - : HttpHandlerWithAuth(exec_env, hier, ptype), _engine(engine), _type(ctype) {} + : HttpHandlerWithAuth(exec_env, hier, ptype), _engine(engine), _compaction_type(ctype) {} /// check param and fetch tablet_id & table_id from req static Status _check_param(HttpRequest* req, uint64_t* tablet_id, uint64_t* table_id) { @@ -345,7 +345,7 @@ Status CompactionAction::_execute_compaction_callback(TabletSharedPtr tablet, void CompactionAction::handle(HttpRequest* req) { req->add_output_header(HttpHeaders::CONTENT_TYPE, HEADER_JSON.data()); - if (_type == CompactionActionType::SHOW_INFO) { + if (_compaction_type == CompactionActionType::SHOW_INFO) { std::string json_result; Status st = _handle_show_compaction(req, &json_result); if (!st.ok()) { @@ -353,7 +353,7 @@ void CompactionAction::handle(HttpRequest* req) { } else { HttpChannel::send_reply(req, HttpStatus::OK, json_result); } - } else if (_type == CompactionActionType::RUN_COMPACTION) { + } else if (_compaction_type == CompactionActionType::RUN_COMPACTION) { std::string json_result; Status st = _handle_run_compaction(req, &json_result); if (!st.ok()) { diff --git a/be/src/http/action/compaction_action.h b/be/src/http/action/compaction_action.h index 4aed97cafbb..33d48e01bc6 100644 --- a/be/src/http/action/compaction_action.h +++ b/be/src/http/action/compaction_action.h @@ -69,7 +69,7 @@ private: private: StorageEngine& _engine; - CompactionActionType _type; + CompactionActionType _compaction_type; }; } // end namespace doris diff --git a/be/src/http/action/config_action.cpp b/be/src/http/action/config_action.cpp index b855de88100..75c7df4e87b 100644 --- a/be/src/http/action/config_action.cpp +++ b/be/src/http/action/config_action.cpp @@ -45,9 +45,9 @@ const static std::string PERSIST_PARAM = "persist"; const std::string CONF_ITEM = "conf_item"; void ConfigAction::handle(HttpRequest* req) { - if (_type == ConfigActionType::UPDATE_CONFIG) { + if (_config_type == ConfigActionType::UPDATE_CONFIG) { handle_update_config(req); - } else if (_type == ConfigActionType::SHOW_CONFIG) { + } else if (_config_type == ConfigActionType::SHOW_CONFIG) { handle_show_config(req); } } @@ -62,7 +62,7 @@ void ConfigAction::handle_show_config(HttpRequest* req) { writer.StartArray(); for (const auto& _config : config_info) { - if (conf_item != nullptr || !conf_item.empty()) { + if (!conf_item.empty()) { if (_config[0] == conf_item) { writer.StartArray(); for (const std::string& config_filed : _config) { diff --git a/be/src/http/action/config_action.h b/be/src/http/action/config_action.h index 7d9d3e7f2ed..67f8f213b63 100644 --- a/be/src/http/action/config_action.h +++ b/be/src/http/action/config_action.h @@ -18,9 +18,11 @@ #pragma once #include "http/http_handler.h" +#include "http/http_handler_with_auth.h" namespace doris { class HttpRequest; +class HttpRequest; enum ConfigActionType { UPDATE_CONFIG = 1, @@ -28,16 +30,17 @@ enum ConfigActionType { }; // Update BE config. -class ConfigAction : public HttpHandler { +class ConfigAction : public HttpHandlerWithAuth { public: - ConfigAction(ConfigActionType type) : _type(type) {} + ConfigAction(ConfigActionType config_type, ExecEnv* exec_env) + : HttpHandlerWithAuth(exec_env), _config_type(config_type) {} virtual ~ConfigAction() {} void handle(HttpRequest* req) override; private: - ConfigActionType _type; + ConfigActionType _config_type; void handle_update_config(HttpRequest* req); diff --git a/be/src/http/action/download_action.cpp b/be/src/http/action/download_action.cpp index 80a7bc28c58..67999c2d09a 100644 --- a/be/src/http/action/download_action.cpp +++ b/be/src/http/action/download_action.cpp @@ -42,7 +42,7 @@ const std::string ACQUIRE_MD5_PARAMETER = "acquire_md5"; DownloadAction::DownloadAction(ExecEnv* exec_env, std::shared_ptr<bufferevent_rate_limit_group> rate_limit_group, const std::vector<std::string>& allow_dirs, int32_t num_workers) - : _exec_env(exec_env), + : HttpHandlerWithAuth(exec_env), _download_type(NORMAL), _num_workers(num_workers), _rate_limit_group(std::move(rate_limit_group)) { @@ -64,7 +64,7 @@ DownloadAction::DownloadAction(ExecEnv* exec_env, } DownloadAction::DownloadAction(ExecEnv* exec_env, const std::string& error_log_root_dir) - : _exec_env(exec_env), _download_type(ERROR_LOG), _num_workers(0) { + : HttpHandlerWithAuth(exec_env), _download_type(ERROR_LOG), _num_workers(0) { #ifndef BE_TEST static_cast<void>( io::global_local_filesystem()->canonicalize(error_log_root_dir, &_error_log_root_dir)); diff --git a/be/src/http/action/download_action.h b/be/src/http/action/download_action.h index 370059ba886..8d38e80ab32 100644 --- a/be/src/http/action/download_action.h +++ b/be/src/http/action/download_action.h @@ -22,6 +22,7 @@ #include "common/status.h" #include "http/http_handler.h" +#include "http/http_handler_with_auth.h" #include "util/threadpool.h" struct bufferevent_rate_limit_group; @@ -36,7 +37,7 @@ class HttpRequest; // TODO(lingbin): implements two useful header ('If-Modified-Since' and 'RANGE') to reduce // transmission consumption. // We use parameter named 'file' to specify the static resource path, it is an absolute path. -class DownloadAction : public HttpHandler { +class DownloadAction : public HttpHandlerWithAuth { public: DownloadAction(ExecEnv* exec_env, std::shared_ptr<bufferevent_rate_limit_group> rate_limit_group, @@ -63,7 +64,6 @@ private: void handle_error_log(HttpRequest* req, const std::string& file_param); void _handle(HttpRequest* req); - ExecEnv* _exec_env; DOWNLOAD_TYPE _download_type; std::vector<std::string> _allow_paths; diff --git a/be/src/http/action/download_binlog_action.cpp b/be/src/http/action/download_binlog_action.cpp index e263112da26..54701c5e463 100644 --- a/be/src/http/action/download_binlog_action.cpp +++ b/be/src/http/action/download_binlog_action.cpp @@ -197,7 +197,9 @@ void handle_get_rowset_meta(StorageEngine& engine, HttpRequest* req) { DownloadBinlogAction::DownloadBinlogAction( ExecEnv* exec_env, StorageEngine& engine, std::shared_ptr<bufferevent_rate_limit_group> rate_limit_group) - : _exec_env(exec_env), _engine(engine), _rate_limit_group(std::move(rate_limit_group)) {} + : HttpHandlerWithAuth(exec_env), + _engine(engine), + _rate_limit_group(std::move(rate_limit_group)) {} void DownloadBinlogAction::handle(HttpRequest* req) { VLOG_CRITICAL << "accept one download binlog request " << req->debug_string(); diff --git a/be/src/http/action/download_binlog_action.h b/be/src/http/action/download_binlog_action.h index 0e50c5e3faf..f1162ff8a3e 100644 --- a/be/src/http/action/download_binlog_action.h +++ b/be/src/http/action/download_binlog_action.h @@ -23,6 +23,7 @@ #include "common/status.h" #include "http/http_handler.h" +#include "http/http_handler_with_auth.h" struct bufferevent_rate_limit_group; @@ -32,7 +33,7 @@ class ExecEnv; class StorageEngine; class HttpRequest; -class DownloadBinlogAction : public HttpHandler { +class DownloadBinlogAction : public HttpHandlerWithAuth { public: DownloadBinlogAction(ExecEnv* exec_env, StorageEngine& engine, std::shared_ptr<bufferevent_rate_limit_group> rate_limit_group); @@ -43,8 +44,6 @@ public: private: Status _check_token(HttpRequest* req); -private: - ExecEnv* _exec_env; StorageEngine& _engine; std::shared_ptr<bufferevent_rate_limit_group> _rate_limit_group; }; diff --git a/be/src/http/action/file_cache_action.h b/be/src/http/action/file_cache_action.h index 0460273dbc0..1b3e255f57b 100644 --- a/be/src/http/action/file_cache_action.h +++ b/be/src/http/action/file_cache_action.h @@ -21,14 +21,16 @@ #include "common/status.h" #include "http/http_handler.h" +#include "http/http_handler_with_auth.h" namespace doris { class HttpRequest; +class ExecEnv; -class FileCacheAction : public HttpHandler { +class FileCacheAction : public HttpHandlerWithAuth { public: - FileCacheAction() = default; + FileCacheAction(ExecEnv* exec_env) : HttpHandlerWithAuth(exec_env) {} ~FileCacheAction() override = default; diff --git a/be/src/http/action/health_action.cpp b/be/src/http/action/health_action.cpp index ef937ab27c5..91be5f78f30 100644 --- a/be/src/http/action/health_action.cpp +++ b/be/src/http/action/health_action.cpp @@ -29,8 +29,6 @@ namespace doris { const static std::string HEADER_JSON = "application/json"; -HealthAction::HealthAction() {} - void HealthAction::handle(HttpRequest* req) { std::stringstream ss; ss << "{"; diff --git a/be/src/http/action/health_action.h b/be/src/http/action/health_action.h index 6724ef08563..e6cfd4cdb7b 100644 --- a/be/src/http/action/health_action.h +++ b/be/src/http/action/health_action.h @@ -18,15 +18,16 @@ #pragma once #include "http/http_handler.h" - +#include "http/http_handler_with_auth.h" namespace doris { class HttpRequest; +class ExecEnv; // Get BE health state from http API. -class HealthAction : public HttpHandler { +class HealthAction : public HttpHandlerWithAuth { public: - HealthAction(); + HealthAction(ExecEnv* exec_env) : HttpHandlerWithAuth(exec_env) {} ~HealthAction() override = default; diff --git a/be/src/http/action/jeprofile_actions.cpp b/be/src/http/action/jeprofile_actions.cpp index 1ed763cfb74..f805d61d5b0 100644 --- a/be/src/http/action/jeprofile_actions.cpp +++ b/be/src/http/action/jeprofile_actions.cpp @@ -32,6 +32,7 @@ #include "http/ev_http_server.h" #include "http/http_channel.h" #include "http/http_handler.h" +#include "http/http_handler_with_auth.h" #include "http/http_method.h" #include "io/fs/local_file_system.h" @@ -39,9 +40,9 @@ namespace doris { class HttpRequest; static std::mutex kJeprofileActionMutex; -class JeHeapAction : public HttpHandler { +class JeHeapAction : public HttpHandlerWithAuth { public: - JeHeapAction() = default; + JeHeapAction(ExecEnv* exec_env) : HttpHandlerWithAuth(exec_env) {} virtual ~JeHeapAction() = default; virtual void handle(HttpRequest* req) override; @@ -77,7 +78,8 @@ Status JeprofileActions::setup(doris::ExecEnv* exec_env, doris::EvHttpServer* ht if (!config::jeprofile_dir.empty()) { RETURN_IF_ERROR(io::global_local_filesystem()->create_directory(config::jeprofile_dir)); } - http_server->register_handler(HttpMethod::GET, "/jeheap/dump", pool.add(new JeHeapAction())); + http_server->register_handler(HttpMethod::GET, "/jeheap/dump", + pool.add(new JeHeapAction(exec_env))); return Status::OK(); } diff --git a/be/src/http/action/load_stream_action.h b/be/src/http/action/load_stream_action.h index 25689d3f88e..d1030ba0f89 100644 --- a/be/src/http/action/load_stream_action.h +++ b/be/src/http/action/load_stream_action.h @@ -20,6 +20,7 @@ #include <string> #include "http/http_handler.h" +#include "http/http_handler_with_auth.h" #include "util/easy_json.h" namespace doris { @@ -28,9 +29,9 @@ class HttpRequest; class ExecEnv; // Get BE load stream info from http API. -class LoadStreamAction final : public HttpHandler { +class LoadStreamAction final : public HttpHandlerWithAuth { public: - LoadStreamAction() = default; + LoadStreamAction(ExecEnv* exec_env) : HttpHandlerWithAuth(exec_env) {} ~LoadStreamAction() override = default; diff --git a/be/src/http/action/pipeline_task_action.h b/be/src/http/action/pipeline_task_action.h index 23c1a17464f..a9f222cc016 100644 --- a/be/src/http/action/pipeline_task_action.h +++ b/be/src/http/action/pipeline_task_action.h @@ -18,32 +18,33 @@ #pragma once #include "http/http_handler.h" +#include "http/http_handler_with_auth.h" namespace doris { - +class ExecEnv; class HttpRequest; -class PipelineTaskAction : public HttpHandler { +class PipelineTaskAction : public HttpHandlerWithAuth { public: - PipelineTaskAction() = default; + PipelineTaskAction(ExecEnv* exec_env) : HttpHandlerWithAuth(exec_env) {} ~PipelineTaskAction() override = default; void handle(HttpRequest* req) override; }; -class LongPipelineTaskAction : public HttpHandler { +class LongPipelineTaskAction : public HttpHandlerWithAuth { public: - LongPipelineTaskAction() = default; + LongPipelineTaskAction(ExecEnv* exec_env) : HttpHandlerWithAuth(exec_env) {} ~LongPipelineTaskAction() override = default; void handle(HttpRequest* req) override; }; -class QueryPipelineTaskAction : public HttpHandler { +class QueryPipelineTaskAction : public HttpHandlerWithAuth { public: - QueryPipelineTaskAction() = default; + QueryPipelineTaskAction(ExecEnv* exec_env) : HttpHandlerWithAuth(exec_env) {} ~QueryPipelineTaskAction() override = default; diff --git a/be/src/http/action/pprof_actions.cpp b/be/src/http/action/pprof_actions.cpp index 2894ba01781..1cc5f9cbef2 100644 --- a/be/src/http/action/pprof_actions.cpp +++ b/be/src/http/action/pprof_actions.cpp @@ -17,6 +17,8 @@ #include "http/action/pprof_actions.h" +#include "http/http_handler_with_auth.h" + #if !defined(__SANITIZE_ADDRESS__) && !defined(ADDRESS_SANITIZER) && !defined(LEAK_SANITIZER) && \ !defined(THREAD_SANITIZER) && !defined(USE_JEMALLOC) #include <gperftools/heap-profiler.h> // IWYU pragma: keep @@ -51,9 +53,10 @@ static const int kPprofDefaultSampleSecs = 30; // Protect, only one thread can work static std::mutex kPprofActionMutex; -class HeapAction : public HttpHandler { +class HeapAction : public HttpHandlerWithAuth { public: - HeapAction() {} + HeapAction(ExecEnv* exec_env) : HttpHandlerWithAuth(exec_env) {} + virtual ~HeapAction() {} virtual void handle(HttpRequest* req) override; @@ -103,9 +106,10 @@ void HeapAction::handle(HttpRequest* req) { #endif } -class GrowthAction : public HttpHandler { +class GrowthAction : public HttpHandlerWithAuth { public: - GrowthAction() {} + GrowthAction(ExecEnv* exec_env) : HttpHandlerWithAuth(exec_env) {} + virtual ~GrowthAction() {} virtual void handle(HttpRequest* req) override; @@ -127,9 +131,10 @@ void GrowthAction::handle(HttpRequest* req) { #endif } -class ProfileAction : public HttpHandler { +class ProfileAction : public HttpHandlerWithAuth { public: - ProfileAction() {} + ProfileAction(ExecEnv* exec_env) : HttpHandlerWithAuth(exec_env) {} + virtual ~ProfileAction() {} virtual void handle(HttpRequest* req) override; @@ -199,24 +204,27 @@ void ProfileAction::handle(HttpRequest* req) { #endif } -class PmuProfileAction : public HttpHandler { +class PmuProfileAction : public HttpHandlerWithAuth { public: - PmuProfileAction() {} + PmuProfileAction(ExecEnv* exec_env) : HttpHandlerWithAuth(exec_env) {} + virtual ~PmuProfileAction() {} virtual void handle(HttpRequest* req) override {} }; -class ContentionAction : public HttpHandler { +class ContentionAction : public HttpHandlerWithAuth { public: - ContentionAction() {} + ContentionAction(ExecEnv* exec_env) : HttpHandlerWithAuth(exec_env) {} + virtual ~ContentionAction() {} virtual void handle(HttpRequest* req) override {} }; -class CmdlineAction : public HttpHandler { +class CmdlineAction : public HttpHandlerWithAuth { public: - CmdlineAction() {} + CmdlineAction(ExecEnv* exec_env) : HttpHandlerWithAuth(exec_env) {} + virtual ~CmdlineAction() {} virtual void handle(HttpRequest* req) override; }; @@ -242,9 +250,10 @@ void CmdlineAction::handle(HttpRequest* req) { HttpChannel::send_reply(req, str); } -class SymbolAction : public HttpHandler { +class SymbolAction : public HttpHandlerWithAuth { public: - SymbolAction(BfdParser* parser) : _parser(parser) {} + SymbolAction(BfdParser* parser, ExecEnv* exec_env) + : HttpHandlerWithAuth(exec_env), _parser(parser) {} virtual ~SymbolAction() {} virtual void handle(HttpRequest* req) override; @@ -297,15 +306,19 @@ Status PprofActions::setup(ExecEnv* exec_env, EvHttpServer* http_server, ObjectP RETURN_IF_ERROR(io::global_local_filesystem()->create_directory(config::pprof_profile_dir)); } - http_server->register_handler(HttpMethod::GET, "/pprof/heap", pool.add(new HeapAction())); - http_server->register_handler(HttpMethod::GET, "/pprof/growth", pool.add(new GrowthAction())); - http_server->register_handler(HttpMethod::GET, "/pprof/profile", pool.add(new ProfileAction())); + http_server->register_handler(HttpMethod::GET, "/pprof/heap", + pool.add(new HeapAction(exec_env))); + http_server->register_handler(HttpMethod::GET, "/pprof/growth", + pool.add(new GrowthAction(exec_env))); + http_server->register_handler(HttpMethod::GET, "/pprof/profile", + pool.add(new ProfileAction(exec_env))); http_server->register_handler(HttpMethod::GET, "/pprof/pmuprofile", - pool.add(new PmuProfileAction())); + pool.add(new PmuProfileAction(exec_env))); http_server->register_handler(HttpMethod::GET, "/pprof/contention", - pool.add(new ContentionAction())); - http_server->register_handler(HttpMethod::GET, "/pprof/cmdline", pool.add(new CmdlineAction())); - auto action = pool.add(new SymbolAction(exec_env->bfd_parser())); + pool.add(new ContentionAction(exec_env))); + http_server->register_handler(HttpMethod::GET, "/pprof/cmdline", + pool.add(new CmdlineAction(exec_env))); + auto action = pool.add(new SymbolAction(exec_env->bfd_parser(), exec_env)); http_server->register_handler(HttpMethod::GET, "/pprof/symbol", action); http_server->register_handler(HttpMethod::HEAD, "/pprof/symbol", action); http_server->register_handler(HttpMethod::POST, "/pprof/symbol", action); diff --git a/be/src/http/action/reset_rpc_channel_action.cpp b/be/src/http/action/reset_rpc_channel_action.cpp index a9aa6ec950e..e1b180a61d4 100644 --- a/be/src/http/action/reset_rpc_channel_action.cpp +++ b/be/src/http/action/reset_rpc_channel_action.cpp @@ -35,7 +35,6 @@ namespace doris { ResetRPCChannelAction::ResetRPCChannelAction(ExecEnv* exec_env, TPrivilegeHier::type hier, TPrivilegeType::type type) : HttpHandlerWithAuth(exec_env, hier, type) {} - void ResetRPCChannelAction::handle(HttpRequest* req) { std::string endpoints = req->param("endpoints"); if (iequal(endpoints, "all")) { diff --git a/be/src/http/action/show_hotspot_action.h b/be/src/http/action/show_hotspot_action.h index a18fb945cce..41625bab855 100644 --- a/be/src/http/action/show_hotspot_action.h +++ b/be/src/http/action/show_hotspot_action.h @@ -19,13 +19,16 @@ #include "cloud/cloud_storage_engine.h" #include "http/http_handler.h" +#include "http/http_handler_with_auth.h" namespace doris { class CloudStorageEngine; +class ExecEnv; -class ShowHotspotAction final : public HttpHandler { +class ShowHotspotAction final : public HttpHandlerWithAuth { public: - ShowHotspotAction(CloudStorageEngine& eng) : _storage_engine(eng) {} + ShowHotspotAction(CloudStorageEngine& eng, ExecEnv* exec_env) + : HttpHandlerWithAuth(exec_env), _storage_engine(eng) {} ~ShowHotspotAction() override = default; diff --git a/be/src/http/action/shrink_mem_action.h b/be/src/http/action/shrink_mem_action.h index 2ffae60327f..4d6fa3ffbcd 100644 --- a/be/src/http/action/shrink_mem_action.h +++ b/be/src/http/action/shrink_mem_action.h @@ -18,12 +18,13 @@ #pragma once #include "http/http_handler.h" +#include "http/http_handler_with_auth.h" namespace doris { class ExecEnv; -class ShrinkMemAction : public HttpHandler { +class ShrinkMemAction : public HttpHandlerWithAuth { public: - explicit ShrinkMemAction() {} + explicit ShrinkMemAction(ExecEnv* exec_env) : HttpHandlerWithAuth(exec_env) {} virtual ~ShrinkMemAction() {} diff --git a/be/src/http/http_handler_with_auth.cpp b/be/src/http/http_handler_with_auth.cpp index 6a4b28beb27..166638ab318 100644 --- a/be/src/http/http_handler_with_auth.cpp +++ b/be/src/http/http_handler_with_auth.cpp @@ -46,7 +46,9 @@ int HttpHandlerWithAuth::on_header(HttpRequest* req) { if (!parse_basic_auth(*req, &auth_info)) { LOG(WARNING) << "parse basic authorization failed" << ", request: " << req->debug_string(); - HttpChannel::send_error(req, HttpStatus::UNAUTHORIZED); + evhttp_add_header(evhttp_request_get_output_headers(req->get_evhttp_request()), + "WWW-Authenticate", "Basic realm=\"Restricted\""); + HttpChannel::send_reply(req, HttpStatus::UNAUTHORIZED); return -1; } @@ -75,12 +77,17 @@ int HttpHandlerWithAuth::on_header(HttpRequest* req) { } } #else - CHECK(_exec_env == nullptr); + if (auth_request.user == "root" && auth_request.passwd.empty()) { + auth_result.status.status_code = TStatusCode::type::OK; + auth_result.status.error_msgs.clear(); + } else { + return -1; + } #endif Status status(Status::create(auth_result.status)); if (!status.ok()) { LOG(WARNING) << "permission verification failed, request: " << auth_request; - HttpChannel::send_error(req, HttpStatus::FORBIDDEN); + HttpChannel::send_reply(req, HttpStatus::FORBIDDEN); return -1; } return 0; diff --git a/be/src/http/http_handler_with_auth.h b/be/src/http/http_handler_with_auth.h index 894a3a81e50..f6546eca1a8 100644 --- a/be/src/http/http_handler_with_auth.h +++ b/be/src/http/http_handler_with_auth.h @@ -37,6 +37,7 @@ class HttpHandlerWithAuth : public HttpHandler { public: HttpHandlerWithAuth(ExecEnv* exec_env, TPrivilegeHier::type hier, TPrivilegeType::type type); + HttpHandlerWithAuth(ExecEnv* exec_env) : _exec_env(exec_env) {} ~HttpHandlerWithAuth() override = default; // return 0 if auth pass, otherwise -1. @@ -53,10 +54,8 @@ public: protected: ExecEnv* _exec_env; - -private: - TPrivilegeHier::type _hier; - TPrivilegeType::type _type; + TPrivilegeHier::type _hier = TPrivilegeHier::GLOBAL; + TPrivilegeType::type _type = TPrivilegeType::ADMIN; }; } // namespace doris diff --git a/be/src/http/web_page_handler.cpp b/be/src/http/web_page_handler.cpp index c6def7ff0f4..90abd57af3e 100644 --- a/be/src/http/web_page_handler.cpp +++ b/be/src/http/web_page_handler.cpp @@ -48,7 +48,8 @@ namespace doris { static std::string s_html_content_type = "text/html"; -WebPageHandler::WebPageHandler(EvHttpServer* server) : _http_server(server) { +WebPageHandler::WebPageHandler(EvHttpServer* server, ExecEnv* exec_env) + : HttpHandlerWithAuth(exec_env), _http_server(server) { _www_path = std::string(getenv("DORIS_HOME")) + "/www/"; // Make WebPageHandler to be static file handler, static files, e.g. css, png, will be handled by WebPageHandler. diff --git a/be/src/http/web_page_handler.h b/be/src/http/web_page_handler.h index 3fab082847d..d5c8a497ef8 100644 --- a/be/src/http/web_page_handler.h +++ b/be/src/http/web_page_handler.h @@ -25,6 +25,7 @@ #include <utility> #include "http/http_handler.h" +#include "http/http_handler_with_auth.h" namespace doris { @@ -34,7 +35,7 @@ class HttpRequest; // This a handler for webpage request // and this handler manage all the page handler -class WebPageHandler : public HttpHandler { +class WebPageHandler : public HttpHandlerWithAuth { public: typedef std::map<std::string, std::string> ArgumentMap; typedef std::function<void(const ArgumentMap& args, std::stringstream* output)> @@ -42,7 +43,7 @@ public: typedef std::function<void(const ArgumentMap& args, EasyJson* output)> TemplatePageHandlerCallback; - WebPageHandler(EvHttpServer* http_server); + WebPageHandler(EvHttpServer* http_server, ExecEnv* exec_env); virtual ~WebPageHandler(); void handle(HttpRequest* req) override; diff --git a/be/src/service/http_service.cpp b/be/src/service/http_service.cpp index 9522f23e3bd..9f98a86bda4 100644 --- a/be/src/service/http_service.cpp +++ b/be/src/service/http_service.cpp @@ -103,7 +103,7 @@ std::shared_ptr<bufferevent_rate_limit_group> get_rate_limit_group(event_base* e HttpService::HttpService(ExecEnv* env, int port, int num_threads) : _env(env), _ev_http_server(new EvHttpServer(port, num_threads)), - _web_page_handler(new WebPageHandler(_ev_http_server.get())) {} + _web_page_handler(new WebPageHandler(_ev_http_server.get(), env)) {} HttpService::~HttpService() { stop(); @@ -139,11 +139,11 @@ Status HttpService::start() { _ev_http_server->register_handler(HttpMethod::HEAD, "/api/_load_error_log", error_log_download_action); - AdjustLogLevelAction* adjust_log_level_action = _pool.add(new AdjustLogLevelAction()); + AdjustLogLevelAction* adjust_log_level_action = _pool.add(new AdjustLogLevelAction(_env)); _ev_http_server->register_handler(HttpMethod::POST, "api/glog/adjust", adjust_log_level_action); //TODO: add query GET interface - auto* adjust_tracing_dump = _pool.add(new AdjustTracingDump()); + auto* adjust_tracing_dump = _pool.add(new AdjustTracingDump(_env)); _ev_http_server->register_handler(HttpMethod::POST, "api/pipeline/tracing", adjust_tracing_dump); @@ -153,36 +153,37 @@ Status HttpService::start() { _ev_http_server->register_handler(HttpMethod::GET, "/api/be_version_info", version_action); // Register BE health action - HealthAction* health_action = _pool.add(new HealthAction()); + HealthAction* health_action = _pool.add(new HealthAction(_env)); _ev_http_server->register_handler(HttpMethod::GET, "/api/health", health_action); // Clear cache action - ClearCacheAction* clear_cache_action = _pool.add(new ClearCacheAction()); + ClearCacheAction* clear_cache_action = _pool.add(new ClearCacheAction(_env)); _ev_http_server->register_handler(HttpMethod::GET, "/api/clear_cache/{type}", clear_cache_action); // Dump all running pipeline tasks - PipelineTaskAction* pipeline_task_action = _pool.add(new PipelineTaskAction()); + PipelineTaskAction* pipeline_task_action = _pool.add(new PipelineTaskAction(_env)); _ev_http_server->register_handler(HttpMethod::GET, "/api/running_pipeline_tasks", pipeline_task_action); // Dump all running pipeline tasks which has been running for more than {duration} seconds - LongPipelineTaskAction* long_pipeline_task_action = _pool.add(new LongPipelineTaskAction()); + LongPipelineTaskAction* long_pipeline_task_action = _pool.add(new LongPipelineTaskAction(_env)); _ev_http_server->register_handler(HttpMethod::GET, "/api/running_pipeline_tasks/{duration}", long_pipeline_task_action); // Dump all running pipeline tasks which has been running for more than {duration} seconds - QueryPipelineTaskAction* query_pipeline_task_action = _pool.add(new QueryPipelineTaskAction()); + QueryPipelineTaskAction* query_pipeline_task_action = + _pool.add(new QueryPipelineTaskAction(_env)); _ev_http_server->register_handler(HttpMethod::GET, "/api/query_pipeline_tasks/{query_id}", query_pipeline_task_action); // Dump all be process thread num - BeProcThreadAction* be_proc_thread_action = _pool.add(new BeProcThreadAction()); + BeProcThreadAction* be_proc_thread_action = _pool.add(new BeProcThreadAction(_env)); _ev_http_server->register_handler(HttpMethod::GET, "/api/be_process_thread_num", be_proc_thread_action); // Register BE LoadStream action - LoadStreamAction* load_stream_action = _pool.add(new LoadStreamAction()); + LoadStreamAction* load_stream_action = _pool.add(new LoadStreamAction(_env)); _ev_http_server->register_handler(HttpMethod::GET, "/api/load_streams", load_stream_action); // Register Tablets Info action @@ -209,10 +210,11 @@ Status HttpService::start() { _ev_http_server->register_handler(HttpMethod::GET, "/api/meta/{op}/{tablet_id}", meta_action); ConfigAction* update_config_action = - _pool.add(new ConfigAction(ConfigActionType::UPDATE_CONFIG)); + _pool.add(new ConfigAction(ConfigActionType::UPDATE_CONFIG, _env)); _ev_http_server->register_handler(HttpMethod::POST, "/api/update_config", update_config_action); - ConfigAction* show_config_action = _pool.add(new ConfigAction(ConfigActionType::SHOW_CONFIG)); + ConfigAction* show_config_action = + _pool.add(new ConfigAction(ConfigActionType::SHOW_CONFIG, _env)); _ev_http_server->register_handler(HttpMethod::GET, "/api/show_config", show_config_action); // 3 check action @@ -234,16 +236,17 @@ Status HttpService::start() { _ev_http_server->register_handler(HttpMethod::GET, "/api/report/task", report_task_action); // shrink memory for starting co-exist process during upgrade - ShrinkMemAction* shrink_mem_action = _pool.add(new ShrinkMemAction()); + ShrinkMemAction* shrink_mem_action = _pool.add(new ShrinkMemAction(_env)); _ev_http_server->register_handler(HttpMethod::GET, "/api/shrink_mem", shrink_mem_action); +#ifndef BE_TEST auto& engine = _env->storage_engine(); if (config::is_cloud_mode()) { register_cloud_handler(engine.to_cloud()); } else { register_local_handler(engine.to_local()); } - +#endif _ev_http_server->start(); return Status::OK(); } @@ -300,7 +303,7 @@ void HttpService::register_local_handler(StorageEngine& engine) { _ev_http_server->register_handler(HttpMethod::HEAD, "/api/_binlog/_download", download_binlog_action); - FileCacheAction* file_cache_action = _pool.add(new FileCacheAction()); + FileCacheAction* file_cache_action = _pool.add(new FileCacheAction(_env)); _ev_http_server->register_handler(HttpMethod::POST, "/api/file_cache", file_cache_action); TabletsDistributionAction* tablets_distribution_action = @@ -401,9 +404,9 @@ void HttpService::register_cloud_handler(CloudStorageEngine& engine) { _ev_http_server->register_handler(HttpMethod::GET, "/api/injection_point/{op}", injection_point_action); #endif - FileCacheAction* file_cache_action = _pool.add(new FileCacheAction()); + FileCacheAction* file_cache_action = _pool.add(new FileCacheAction(_env)); _ev_http_server->register_handler(HttpMethod::GET, "/api/file_cache", file_cache_action); - auto* show_hotspot_action = _pool.add(new ShowHotspotAction(engine)); + auto* show_hotspot_action = _pool.add(new ShowHotspotAction(engine, _env)); _ev_http_server->register_handler(HttpMethod::GET, "/api/hotspot/tablet", show_hotspot_action); CalcFileCrcAction* calc_crc_action = _pool.add( diff --git a/be/test/http/http_client_test.cpp b/be/test/http/http_client_test.cpp index 00b3288d2e9..4e2ada03c66 100644 --- a/be/test/http/http_client_test.cpp +++ b/be/test/http/http_client_test.cpp @@ -33,6 +33,10 @@ #include "http/http_headers.h" #include "http/http_request.h" #include "http/utils.h" +#include "runtime/exec_env.h" +#include "service/backend_service.h" +#include "service/http_service.h" +#include "testutil/http_utils.h" #include "util/md5.h" namespace doris { @@ -341,4 +345,200 @@ TEST_F(HttpClientTest, escape_url) { ASSERT_TRUE(check_result(input_G, output_G)); } +TEST_F(HttpClientTest, enable_http_auth) { + std::string origin_hostname = hostname; + Defer defer {[&origin_hostname]() { + hostname = origin_hostname; + config::enable_all_http_auth = false; + }}; + + hostname = doris::global_test_http_host; + + { + config::enable_all_http_auth = false; + std::string url = hostname + "/api/health"; + HttpClient client; + auto st = client.init(url); + EXPECT_TRUE(st.ok()); + client.set_method(GET); + std::string response; + st = client.execute(&response); + EXPECT_TRUE(st.ok()); + std::cout << "response = " << response << "\n"; + EXPECT_TRUE(response.find("To Be Added") != std::string::npos); + } + + { + config::enable_all_http_auth = true; + std::string url = hostname + "/api/health"; + HttpClient client; + auto st = client.init(url); + EXPECT_TRUE(st.ok()); + client.set_method(GET); + std::string response; + st = client.execute(&response); + std::cout << "st = " << st << "\n"; + std::cout << "response = " << response << "\n"; + std::cout << "st.msg() = " << st.msg() << "\n"; + EXPECT_TRUE(!st.ok()); + EXPECT_TRUE(st.msg().find("The requested URL returned error") != std::string::npos); + } + + { + config::enable_all_http_auth = true; + std::string url = hostname + "/api/health"; + HttpClient client; + auto st = client.init(url); + EXPECT_TRUE(st.ok()); + client.set_method(GET); + client.set_basic_auth("root", ""); + std::string response; + st = client.execute(&response); + EXPECT_TRUE(st.ok()); + std::cout << "response = " << response << "\n"; + EXPECT_TRUE(response.find("To Be Added") != std::string::npos); + } + + { + config::enable_all_http_auth = true; + std::string url = hostname + "/api/health"; + HttpClient client; + auto st = client.init(url); + EXPECT_TRUE(st.ok()); + client.set_method(GET); + client.set_basic_auth("root", "errorpasswd"); + client.set_timeout_ms(200); + std::string response; + st = client.execute(&response); + EXPECT_TRUE(!st.ok()); + std::cout << "response = " << response << "\n"; + std::cout << "st.msg() = " << st.msg() << "\n"; + EXPECT_TRUE(st.msg().find("Operation timed out after") != std::string::npos); + } + + { + config::enable_all_http_auth = false; + std::string url = hostname + "/metrics"; + HttpClient client; + auto st = client.init(url); + EXPECT_TRUE(st.ok()); + client.set_method(GET); + std::string response; + st = client.execute(&response); + EXPECT_TRUE(st.ok()); + std::cout << "response = " << response << "\n"; + EXPECT_TRUE(response.size() != 0); + } + + { + config::enable_all_http_auth = true; + std::string url = hostname + "/metrics"; + HttpClient client; + auto st = client.init(url); + EXPECT_TRUE(st.ok()); + client.set_method(GET); + std::string response; + st = client.execute(&response); + std::cout << "st = " << st << "\n"; + std::cout << "response = " << response << "\n"; + std::cout << "st.msg() = " << st.msg() << "\n"; + EXPECT_TRUE(!st.ok()); + EXPECT_TRUE(st.msg().find("The requested URL returned error") != std::string::npos); + } + { + config::enable_all_http_auth = true; + std::string url = hostname + "/metrics"; + HttpClient client; + auto st = client.init(url); + EXPECT_TRUE(st.ok()); + client.set_method(GET); + client.set_basic_auth("root", ""); + std::string response; + st = client.execute(&response); + EXPECT_TRUE(st.ok()); + std::cout << "response = " << response << "\n"; + EXPECT_TRUE(response.size() != 0); + } + + { + config::enable_all_http_auth = true; + std::string url = hostname + "/metrics"; + HttpClient client; + auto st = client.init(url); + EXPECT_TRUE(st.ok()); + client.set_method(GET); + client.set_basic_auth("root", "errorpasswd"); + client.set_timeout_ms(200); + std::string response; + st = client.execute(&response); + EXPECT_TRUE(!st.ok()); + std::cout << "response = " << response << "\n"; + std::cout << "st.msg() = " << st.msg() << "\n"; + EXPECT_TRUE(st.msg().find("Operation timed out after") != std::string::npos); + } + + { + config::enable_all_http_auth = true; + std::string url = hostname + "/api/glog/adjust"; + HttpClient client; + auto st = client.init(url); + EXPECT_TRUE(st.ok()); + client.set_method(POST); + client.set_basic_auth("rootss", ""); + client.set_timeout_ms(200); + std::string response; + st = client.execute_post_request("level=1&module=xxx", &response); + EXPECT_TRUE(!st.ok()); + std::cout << "response = " << response << "\n"; + std::cout << "st.msg() = " << st.msg() << "\n"; + EXPECT_TRUE(st.msg().find("Operation timed out after") != std::string::npos); + } + + std::vector<std::string> check_get_list = {"/api/clear_cache/aa", + "/api/running_pipeline_tasks", + "/api/running_pipeline_tasks/223", + "/api/query_pipeline_tasks/78902309190709864", + "/api/be_process_thread_num", + "/api/load_streams", + "/api/show_config", + "/api/shrink_mem"}; + + for (auto endpoint : check_get_list) { + std::cout << "endpint = " << endpoint << "\n"; + + { + config::enable_all_http_auth = true; + std::string url = hostname + endpoint; + HttpClient client; + auto st = client.init(url); + EXPECT_TRUE(st.ok()); + client.set_method(GET); + std::string response; + st = client.execute(&response); + std::cout << "st = " << st << "\n"; + std::cout << "response = " << response << "\n"; + std::cout << "st.msg() = " << st.msg() << "\n"; + EXPECT_TRUE(!st.ok()); + EXPECT_TRUE(st.msg().find("The requested URL returned error") != std::string::npos); + } + + { + config::enable_all_http_auth = true; + std::string url = hostname + endpoint; + HttpClient client; + auto st = client.init(url); + EXPECT_TRUE(st.ok()); + client.set_method(GET); + client.set_basic_auth("roxot", "errorpasswd"); + client.set_timeout_ms(200); + std::string response; + st = client.execute(&response); + EXPECT_TRUE(!st.ok()); + std::cout << "response = " << response << "\n"; + std::cout << "st.msg() = " << st.msg() << "\n"; + EXPECT_TRUE(st.msg().find("Operation timed out after") != std::string::npos); + } + } +} + } // namespace doris diff --git a/be/test/testutil/run_all_tests.cpp b/be/test/testutil/run_all_tests.cpp index d40ce9c5e8a..a0fc174aeda 100644 --- a/be/test/testutil/run_all_tests.cpp +++ b/be/test/testutil/run_all_tests.cpp @@ -27,20 +27,24 @@ #include "gtest/gtest.h" #include "gtest/gtest_pred_impl.h" #include "http/ev_http_server.h" +#include "olap/options.h" #include "olap/page_cache.h" #include "olap/segment_loader.h" +#include "olap/storage_engine.h" #include "olap/tablet_schema_cache.h" #include "runtime/exec_env.h" #include "runtime/memory/cache_manager.h" #include "runtime/memory/thread_mem_tracker_mgr.h" #include "runtime/thread_context.h" #include "service/backend_options.h" +#include "service/backend_service.h" #include "service/http_service.h" #include "test_util.h" #include "testutil/http_utils.h" #include "util/cpu_info.h" #include "util/disk_info.h" #include "util/mem_info.h" +#include "util/thrift_server.h" int main(int argc, char** argv) { doris::ThreadLocalHandle::create_thread_local_if_not_exits(); @@ -75,8 +79,11 @@ int main(int argc, char** argv) { doris::BackendOptions::init(); auto service = std::make_unique<doris::HttpService>(doris::ExecEnv::GetInstance(), 0, 1); - service->register_debug_point_handler(); - service->_ev_http_server->start(); + auto status = service->start(); + if (!s.ok()) { + LOG(WARNING) << "start http service fail."; + } + doris::global_test_http_host = "http://127.0.0.1:" + std::to_string(service->get_real_port()); ::testing::TestEventListeners& listeners = ::testing::UnitTest::GetInstance()->listeners(); --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org