Repository: ggml-org/llama.cpp
Pull request: server: fix query params lost when proxying requests in multi-model router mode

*Make sure to read the [contributing guidelines](https://github.com/ggml-org/llama.cpp/blob/master/CONTRIBUTING.md) before submitting a PR*

### Purpose:
When the multi-model router proxies requests to child servers, query parameters are lost because httplib strips them from the path; this patch preserves them by reconstructing the full URL in proxy_request.

### Testing:
```
curl -X POST 'https://www.serveurperso.com/ia/webui/slots/0?action=save'   -H 'Content-Type: application/json'   -d '{"filename": "MoE-Qwen3-235B_slot0", "model": "MoE-Qwen3-235B-A22B-Thinking-2507"}'

{"id_slot":0,"filename":"MoE-Qwen3-235B_slot0","n_saved":2510,"n_written":256745164,"timings":{"save_ms":73.442}}

curl -X POST 'https://www.serveurperso.com/ia/webui/slots/0?action=restore' \
  -H 'Content-Type: application/json' \
  -d '{"filename": "MoE-Qwen3-235B_slot0", "model": "MoE-Qwen3-235B-A22B-Thinking-2507"}'

{"id_slot":0,"filename":"MoE-Qwen3-235B_slot0","n_restored":2510,"n_read":256745164,"timings":{"restore_ms":27.164}}

ls -lha
total 245M
drwxr-xr-x 2 root root 4,0K 24 févr. 16:04 .
drwxr-xr-x 8 root root 4,0K 24 févr. 15:53 ..
-rw-r--r-- 1 root root 245M 24 févr. 16:04 MoE-Qwen3-235B_slot0
```

Closes #18703

Changed files:
filename: tools/server/server-http.cpp
patch: @@ -339,6 +339,17 @@ static std::map<std::string, std::string> get_headers(const httplib::Request & r
     return headers;
 }
 
+static std::string build_query_string(const httplib::Request & req) {
+    std::string qs;
+    for (const auto & [key, value] : req.params) {
+        if (!qs.empty()) {
+            qs += '&';
+        }
+        qs += httplib::encode_query_component(key) + "=" + httplib::encode_query_component(value);
+    }
+    return qs;
+}
+
 // using unique_ptr for request to allow safe capturing in lambdas
 using server_http_req_ptr = std::unique_ptr<server_http_req>;
 
@@ -382,6 +393,7 @@ void server_http_context::get(const std::string & path, const server_http_contex
             get_params(req),
             get_headers(req),
             req.path,
+            build_query_string(req),
             req.body,
             req.is_connection_closed
         });
@@ -396,6 +408,7 @@ void server_http_context::post(const std::string & path, const server_http_conte
             get_params(req),
             get_headers(req),
             req.path,
+            build_query_string(req),
             req.body,
             req.is_connection_closed
         });

filename: tools/server/server-http.h
patch: @@ -36,7 +36,8 @@ using server_http_res_ptr = std::unique_ptr<server_http_res>;
 struct server_http_req {
     std::map<std::string, std::string> params; // path_params + query_params
     std::map<std::string, std::string> headers; // reserved for future use
-    std::string path; // reserved for future use
+    std::string path;
+    std::string query_string; // query parameters string (e.g. "action=save")
     std::string body;
     const std::function<bool()> & should_stop;
 

filename: tools/server/server-models.cpp
patch: @@ -697,11 +697,15 @@ server_http_res_ptr server_models::proxy_request(const server_http_req & req, co
         mapping[name].meta.last_used = ggml_time_ms();
     }
     SRV_INF("proxying request to model %s on port %d\n", name.c_str(), meta->port);
+    std::string proxy_path = req.path;
+    if (!req.query_string.empty()) {
+        proxy_path += '?' + req.query_string;
+    }
     auto proxy = std::make_unique<server_http_proxy>(
             method,
             CHILD_ADDR,
             meta->port,
-            req.path,
+            proxy_path,
             req.headers,
             req.body,
             req.should_stop,