add opensearch

This commit is contained in:
mat 2023-12-20 17:56:03 -06:00
parent c7633f68c1
commit 598b60b1f0
4 changed files with 40 additions and 1 deletions

View File

@ -6,6 +6,7 @@
<title>metasearch</title> <title>metasearch</title>
<link rel="stylesheet" href="/style.css"> <link rel="stylesheet" href="/style.css">
<script src="/script.js" defer></script> <script src="/script.js" defer></script>
<link rel="search" type="application/opensearchdescription+xml" title="metasearch" href="/opensearch.xml"/>
</head> </head>
<body> <body>
<div class="main-container"> <div class="main-container">

View File

@ -1,4 +1,5 @@
pub mod autocomplete; pub mod autocomplete;
pub mod opensearch;
pub mod search; pub mod search;
use std::net::SocketAddr; use std::net::SocketAddr;
@ -36,6 +37,7 @@ pub async fn run() {
) )
}), }),
) )
.route("/opensearch.xml", get(opensearch::route))
.route("/search", get(search::route)) .route("/search", get(search::route))
.route("/autocomplete", get(autocomplete::route)); .route("/autocomplete", get(autocomplete::route));

29
src/web/opensearch.rs Normal file
View File

@ -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#"<?xml version="1.0" encoding="utf-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>metasearch</ShortName>
<Description>Search metasearch</Description>
<InputEncoding>UTF-8</InputEncoding>
<Url type="text/html" method="get" template="https://{host}/search?q={{searchTerms}}" />
<Url type="application/x-suggestions+json" method="get"
template="https://{host}/autocomplete?q={{searchTerms}}" />
</OpenSearchDescription>"#
),
)
}

View File

@ -22,6 +22,7 @@ fn render_beginning_of_html(query: &str) -> String {
<title>{} - metasearch</title> <title>{} - metasearch</title>
<link rel="stylesheet" href="/style.css"> <link rel="stylesheet" href="/style.css">
<script src="/script.js" defer></script> <script src="/script.js" defer></script>
<link rel="search" type="application/opensearchdescription+xml" title="metasearch" href="/opensearch.xml"/>
</head> </head>
<body> <body>
<main> <main>
@ -149,6 +150,7 @@ pub async fn route(
let query = SearchQuery { let query = SearchQuery {
query, query,
request_headers: headers request_headers: headers
.clone()
.into_iter() .into_iter()
.map(|(k, v)| { .map(|(k, v)| {
( (
@ -157,7 +159,12 @@ pub async fn route(
) )
}) })
.collect(), .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! { let s = stream! {