From 9562fea7136f983c328e20f86beb7cf4c8624d14 Mon Sep 17 00:00:00 2001 From: Xuan Son Nguyen Date: Tue, 14 Jul 2026 12:58:13 +0200 Subject: [PATCH] fix test --- tools/server/server-http.cpp | 2 ++ tools/server/server.cpp | 28 ++++++++++++++---------- tools/server/tests/unit/test_security.py | 5 ++++- tools/server/tests/utils.py | 2 +- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/tools/server/server-http.cpp b/tools/server/server-http.cpp index e8cc5a50a0..24a38452aa 100644 --- a/tools/server/server-http.cpp +++ b/tools/server/server-http.cpp @@ -285,6 +285,8 @@ bool server_http_context::init(const common_params & params) { std::string origin = req.get_header_value("Origin"); if (origin_is_localhost(origin)) { res.set_header("Access-Control-Allow-Origin", origin); + } else { + SRV_WRN("(CORS) skip non-localhost origin: %s\n", origin.c_str()); } } else { res.set_header("Access-Control-Allow-Origin", params.cors_origins); diff --git a/tools/server/server.cpp b/tools/server/server.cpp index f307c960db..b1c43974c5 100644 --- a/tools/server/server.cpp +++ b/tools/server/server.cpp @@ -312,13 +312,15 @@ int llama_server(common_params & params, int argc, char ** argv) { } // CORS proxy (EXPERIMENTAL, only used by the Web UI for MCP) + std::vector warn_names; + if (is_router_server) { + warn_names.push_back("router mode"); + } + if (params.ui_mcp_proxy) { - SRV_WRN("%s", "-----------------\n"); - SRV_WRN("%s", "CORS proxy is enabled, do not expose server to untrusted environments\n"); - SRV_WRN("%s", "This feature is EXPERIMENTAL and may be removed or changed in future versions\n"); - SRV_WRN("%s", "-----------------\n"); ctx_http.get ("/cors-proxy", ex_wrapper(proxy_handler_get)); ctx_http.post("/cors-proxy", ex_wrapper(proxy_handler_post)); + warn_names.push_back("MCP proxy (experimental)"); } else { ctx_http.get ("/cors-proxy", ex_wrapper(res_403)); ctx_http.post("/cors-proxy", ex_wrapper(res_403)); @@ -332,17 +334,24 @@ int llama_server(common_params & params, int argc, char ** argv) { SRV_ERR("tools setup failed: %s\n", e.what()); return 1; } - SRV_WRN("%s", "-----------------\n"); - SRV_WRN("%s", "Built-in tools are enabled, do not expose server to untrusted environments\n"); - SRV_WRN("%s", "This feature is EXPERIMENTAL and may be changed in the future\n"); - SRV_WRN("%s", "-----------------\n"); ctx_http.get ("/tools", ex_wrapper(tools.handle_get)); ctx_http.post("/tools", ex_wrapper(tools.handle_post)); + warn_names.push_back("built-in tools (experimental)"); } else { ctx_http.get ("/tools", ex_wrapper(res_403)); ctx_http.post("/tools", ex_wrapper(res_403)); } + if (warn_names.size() > 0) { + SRV_WRN("%s", "-----------------\n"); + SRV_WRN("%s", "the following feature(s) are enabled:\n"); + for (const auto & name : warn_names) { + SRV_WRN(" %s\n", name.c_str()); + } + SRV_WRN("%s", "do not expose the server to untrusted environments\n"); + SRV_WRN("%s", "-----------------\n"); + } + // // Handle downloading model // @@ -460,9 +469,6 @@ int llama_server(common_params & params, int argc, char ** argv) { SRV_INF("listening on %s\n", ctx_http.listening_address.c_str()); if (is_router_server) { - SRV_WRN("%s", "NOTE: router mode is experimental\n"); - SRV_WRN("%s", " it is not recommended to use this mode in untrusted environments\n"); - if (!params.models_preset_hf.empty()) { SRV_WRN( "NOTE: using preset.ini from HF repo '%s'\n", params.models_preset_hf.c_str()); SRV_WRN("%s", " please only use presets that you can trust! Unknown presets may be unsafe\n"); diff --git a/tools/server/tests/unit/test_security.py b/tools/server/tests/unit/test_security.py index fa22c5dcda..ac0544575b 100644 --- a/tools/server/tests/unit/test_security.py +++ b/tools/server/tests/unit/test_security.py @@ -91,7 +91,7 @@ def test_openai_library_correct_api_key(): ("localhost", "Access-Control-Allow-Origin", "localhost"), ("web.mydomain.fr", "Access-Control-Allow-Origin", "web.mydomain.fr"), ("origin", "Access-Control-Allow-Credentials", "true"), - ("web.mydomain.fr", "Access-Control-Allow-Methods", "GET, POST"), + ("web.mydomain.fr", "Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS"), ("web.mydomain.fr", "Access-Control-Allow-Headers", "*"), ]) def test_cors_options(origin: str, cors_header: str, cors_header_value: str): @@ -116,6 +116,7 @@ def test_cors_options(origin: str, cors_header: str, cors_header_value: str): "http://[::1]:3000", ]) def test_cors_origins_localhost_reflects(origin: str): + global server server = ServerPreset.router() server.cors_origins = "localhost" server.start() @@ -135,6 +136,7 @@ def test_cors_origins_localhost_reflects(origin: str): "http://localhost.evil.com", ]) def test_cors_origins_localhost_rejects(origin: str): + global server server = ServerPreset.router() server.cors_origins = "localhost" server.start() @@ -148,6 +150,7 @@ def test_cors_origins_localhost_rejects(origin: str): def test_cors_origins_defaults_to_localhost_with_tools_enabled(): + global server server = ServerPreset.router() server.server_tools = "all" server.start() diff --git a/tools/server/tests/utils.py b/tools/server/tests/utils.py index b32a037d82..f4f0e61e61 100644 --- a/tools/server/tests/utils.py +++ b/tools/server/tests/utils.py @@ -362,7 +362,7 @@ class ServerProcess: if parse_body: try: result.body = response.json() - except JSONDecodeError: + except (JSONDecodeError, requests.exceptions.JSONDecodeError): result.body = response.text else: result.body = None