diff --git a/src/web/assets/index.html b/src/web/assets/index.html index 62868cf..4dd28e4 100644 --- a/src/web/assets/index.html +++ b/src/web/assets/index.html @@ -6,6 +6,7 @@ metasearch +
diff --git a/src/web/mod.rs b/src/web/mod.rs index e21975f..f7608f5 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -1,4 +1,5 @@ pub mod autocomplete; +pub mod opensearch; pub mod search; use std::net::SocketAddr; @@ -36,6 +37,7 @@ pub async fn run() { ) }), ) + .route("/opensearch.xml", get(opensearch::route)) .route("/search", get(search::route)) .route("/autocomplete", get(autocomplete::route)); diff --git a/src/web/opensearch.rs b/src/web/opensearch.rs new file mode 100644 index 0000000..690a858 --- /dev/null +++ b/src/web/opensearch.rs @@ -0,0 +1,29 @@ +use axum::{ + http::{header, HeaderMap}, + response::IntoResponse, +}; + +pub async fn route(headers: HeaderMap) -> impl IntoResponse { + let host = headers + .get("host") + .and_then(|host| host.to_str().ok()) + .unwrap_or("localhost"); + + ( + [( + header::CONTENT_TYPE, + "application/opensearchdescription+xml", + )], + format!( + r#" + + metasearch + Search metasearch + UTF-8 + + + "# + ), + ) +} diff --git a/src/web/search.rs b/src/web/search.rs index 27f4978..0246b99 100644 --- a/src/web/search.rs +++ b/src/web/search.rs @@ -22,6 +22,7 @@ fn render_beginning_of_html(query: &str) -> String { {} - metasearch +
@@ -149,6 +150,7 @@ pub async fn route( let query = SearchQuery { query, request_headers: headers + .clone() .into_iter() .map(|(k, v)| { ( @@ -157,7 +159,12 @@ pub async fn route( ) }) .collect(), - ip: addr.ip().to_string(), + ip: headers + // this could be exploited under some setups, but the ip is only used for the + // "what is my ip" answer so it doesn't really matter + .get("x-forwarded-for") + .map(|ip| ip.to_str().unwrap_or_default().to_string()) + .unwrap_or_else(|| addr.ip().to_string()), }; let s = stream! {