Added configurable user agents that get served the text version by default

This commit is contained in:
Slatian 2023-02-21 10:00:10 +01:00
parent c4379d4c19
commit c7ba9a6346
6 changed files with 71 additions and 3 deletions

43
Cargo.lock generated
View File

@ -49,6 +49,7 @@ dependencies = [
"bitflags",
"bytes",
"futures-util",
"headers",
"http",
"http-body",
"hyper",
@ -111,6 +112,12 @@ dependencies = [
"syn",
]
[[package]]
name = "base64"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "bitflags"
version = "1.3.2"
@ -481,6 +488,31 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "headers"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584"
dependencies = [
"base64",
"bitflags",
"bytes",
"headers-core",
"http",
"httpdate",
"mime",
"sha1",
]
[[package]]
name = "headers-core"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
dependencies = [
"http",
]
[[package]]
name = "heck"
version = "0.4.1"
@ -1275,6 +1307,17 @@ dependencies = [
"serde",
]
[[package]]
name = "sha1"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "sha2"
version = "0.10.6"

View File

@ -7,7 +7,7 @@ authors = ["Slatian <baschdel@disroot.org>"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
axum = { version = "0.6", features = ["macros"] }
axum = { version = "0.6", features = ["macros", "headers"] }
axum-client-ip = "0.4"
clap = { version = "4", features = ["derive"] }
serde = { version = "1", features = ["derive"] }

View File

@ -40,3 +40,7 @@ location_database = "mmdb/GeoLite2-City.mmdb"
[template]
# Path to the template directory, can contain glob patterns
template_location = "templates"
# Prefixes of user agents that should get a text reponse by default
text_user_agents = ["curl/"]

View File

@ -40,3 +40,6 @@ hidden_suffixes = [".com"]
[template]
# Path to the template directory, can contain glob patterns
template_location = "templates"
# Prefixes of user agents that should get a text reponse by default
text_user_agents = ["curl/"]

View File

@ -35,6 +35,7 @@ pub struct GeoIpConfig {
pub struct TemplateConfig {
pub template_location: String,
pub extra_config: Option<String>,
pub text_user_agents: Vec<String>,
}
impl Default for ServerConfig {
@ -71,6 +72,7 @@ impl Default for TemplateConfig {
TemplateConfig {
template_location: "templates/".to_string(),
extra_config: None,
text_user_agents: vec!["curl/".to_string()],
}
}
}

View File

@ -5,11 +5,13 @@ use axum::{
State,
Extension,
},
headers,
http::Request,
middleware::{self, Next},
response::Response,
Router,
routing::get,
TypedHeader,
};
use axum_client_ip::SecureClientIp;
use clap::Parser;
@ -244,12 +246,26 @@ async fn main() {
async fn format_and_language_middleware<B>(
Query(query): Query<BaseQuery>,
Extension(config): Extension<config::EchoIpServiceConfig>,
user_agent_header: Option<TypedHeader<headers::UserAgent>>,
mut req: Request<B>,
next: Next<B>
) -> Response {
let format = query.format.unwrap_or(ResponseFormat::TextHtml);
let mut format = query.format;
// Try to guess type from user agent
if format.is_none() {
if let Some(TypedHeader(user_agent)) = user_agent_header {
let ua = user_agent.as_str();
for tua in config.template.text_user_agents {
if ua.starts_with(&tua) {
format = Some(ResponseFormat::TextPlain);
break;
}
}
}
}
// Add the request settings extension
req.extensions_mut().insert(TemplateSettings{
format: format,
format: format.unwrap_or(ResponseFormat::TextHtml),
lang: query.lang.unwrap_or("en".to_string()),
});
next.run(req).await