add custom welcome pages support

This commit is contained in:
yggverse 2025-02-24 02:21:54 +02:00
parent 31e33bca28
commit d5883d977e
4 changed files with 66 additions and 6 deletions

View file

@ -139,16 +139,44 @@ fn handle(
}
fn gemini(
gemini: titanite::request::Gemini,
request: titanite::request::Gemini,
argument: &Argument,
peer: &SocketAddr,
stream: &mut TlsStream<TcpStream>,
) {
use titanite::*;
println!("[{}] [info] [{peer}] Request: {}", now(), gemini.url);
// file could be large,
// to not overflow the memory pool, build the response using chunks
match storage::Item::from_url(gemini.url.as_str(), &argument.directory) {
println!("[{}] [info] [{peer}] Request: {}", now(), request.url);
// try welcome page
if request.url.path().trim_end_matches("/").is_empty() {
return send(
&match welcome(argument, request.url.host_str(), request.url.port()) {
Ok(welcome) => response::success::Default {
data: welcome.as_bytes(),
meta: response::success::default::Meta {
mime: "text/gemini".to_string(),
},
}
.into_bytes(),
Err(e) => {
println!("[{}] [error] [{peer}] {e}", now());
response::failure::temporary::General {
message: Some("Internal server error".to_string()),
}
.into_bytes()
}
},
stream,
|result| match result {
Ok(()) => println!("[{}] [info] [{peer}] /", now()),
Err(e) => println!("[{}] [error] [{peer}] {e}", now()),
},
);
}
// try file resource
// * it could be large, to not overflow the memory pool, use chunked read
match storage::Item::from_url(request.url.as_str(), &argument.directory) {
Ok(item) => {
let mut read: usize = 0;
// create header packet
@ -185,7 +213,7 @@ fn gemini(
}
Err(e) => send(
&response::failure::permanent::NotFound {
message: Some("Not found".to_string()),
message: Some("Resource not found".to_string()),
}
.into_bytes(),
stream,
@ -431,6 +459,24 @@ fn send(data: &[u8], stream: &mut TlsStream<TcpStream>, callback: impl FnOnce(Re
})());
}
fn welcome(argument: &Argument, host: Option<&str>, port: Option<u16>) -> Result<String> {
let mut file = File::open(argument.welcome.as_deref().unwrap_or("welcome.gmi"))?;
let mut data = String::new();
file.read_to_string(&mut data)?;
Ok(data.replace(
"{UPLOAD_URL}",
&if let Some(host) = host {
let mut url = format!("titan://{host}");
if let Some(port) = port {
url = format!("{url}:{port}")
}
url
} else {
argument.bind.to_string()
},
))
}
fn now() -> u128 {
SystemTime::now()
.duration_since(UNIX_EPOCH)