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 <noreply@anthropic.com>
This commit is contained in:
Sharang Parnerkar
2026-02-20 06:52:00 +01:00
parent 42b79371a2
commit a7329efa5e

View File

@@ -122,23 +122,21 @@ pub async fn search_topic(query: String) -> Result<Vec<NewsCard>, 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(&params)
.send()
.await
.map_err(|e| ServerFnError::new(format!("SearXNG request failed: {e}")))?;
@@ -207,12 +205,15 @@ pub async fn get_trending_topics() -> Result<Vec<String>, 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<Vec<String>, ServerFnError> {
.map_err(|e| ServerFnError::new(format!("HTTP client error: {e}")))?;
let resp = client
.get(&search_url)
.post(&search_url)
.form(&params)
.send()
.await
.map_err(|e| ServerFnError::new(format!("SearXNG trending search failed: {e}")))?;