From a7329efa5e9cadd2faf4428edbaed4b62a617979 Mon Sep 17 00:00:00 2001 From: Sharang Parnerkar Date: Fri, 20 Feb 2026 06:52:00 +0100 Subject: [PATCH] fix(searxng): use POST instead of GET for SearXNG search API SearXNG's default config sets `method: "POST"` which rejects GET requests with 405. Switch both search_topic and get_trending_topics to POST with form-encoded parameters. Co-Authored-By: Claude Opus 4.6 --- src/infrastructure/searxng.rs | 44 ++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/infrastructure/searxng.rs b/src/infrastructure/searxng.rs index d5d2322..4181c90 100644 --- a/src/infrastructure/searxng.rs +++ b/src/infrastructure/searxng.rs @@ -122,23 +122,21 @@ pub async fn search_topic(query: String) -> Result, ServerFnError> // similar to how Perplexity reformulates queries before searching. let enriched_query = format!("{query} latest news"); - // Build URL with query parameters using the url crate's encoder - // to avoid reqwest version conflicts between our dep and dioxus's. - // Key SearXNG params: - // categories=news,general - prioritize news sources + supplement with general - // time_range=month - only recent results (last 30 days) - // language=en - English results - // format=json - machine-readable output - let encoded_query: String = - url::form_urlencoded::byte_serialize(enriched_query.as_bytes()).collect(); - let search_url = format!( - "{searxng_url}/search?q={encoded_query}&format=json&language=en\ - &categories=news,general&time_range=month" - ); + // Use POST with form-encoded body because SearXNG's default config + // sets `method: "POST"` which rejects GET requests with 405. + let search_url = format!("{searxng_url}/search"); + let params = [ + ("q", enriched_query.as_str()), + ("format", "json"), + ("language", "en"), + ("categories", "news,general"), + ("time_range", "month"), + ]; let client = reqwest::Client::new(); let resp = client - .get(&search_url) + .post(&search_url) + .form(¶ms) .send() .await .map_err(|e| ServerFnError::new(format!("SearXNG request failed: {e}")))?; @@ -207,12 +205,15 @@ pub async fn get_trending_topics() -> Result, ServerFnError> { let searxng_url = std::env::var("SEARXNG_URL").unwrap_or_else(|_| "http://localhost:8888".into()); - let encoded_query: String = - url::form_urlencoded::byte_serialize(b"trending technology AI").collect(); - let search_url = format!( - "{searxng_url}/search?q={encoded_query}&format=json&language=en\ - &categories=news&time_range=week" - ); + // Use POST to match SearXNG's default `method: "POST"` setting + let search_url = format!("{searxng_url}/search"); + let params = [ + ("q", "trending technology AI"), + ("format", "json"), + ("language", "en"), + ("categories", "news"), + ("time_range", "week"), + ]; let client = reqwest::Client::builder() .timeout(std::time::Duration::from_secs(5)) @@ -220,7 +221,8 @@ pub async fn get_trending_topics() -> Result, ServerFnError> { .map_err(|e| ServerFnError::new(format!("HTTP client error: {e}")))?; let resp = client - .get(&search_url) + .post(&search_url) + .form(¶ms) .send() .await .map_err(|e| ServerFnError::new(format!("SearXNG trending search failed: {e}")))?;