Initial commit
This commit is contained in:
+88
@@ -0,0 +1,88 @@
|
||||
use std::{
|
||||
env,
|
||||
process::{exit, Command},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use axum::{
|
||||
error_handling::HandleErrorLayer, extract::Path, http::StatusCode, response::Html,
|
||||
routing::get, BoxError, Router,
|
||||
};
|
||||
|
||||
use tower::{buffer::BufferLayer, limit::rate::RateLimitLayer, ServiceBuilder};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// initialize tracing
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
// idk how to have one rate limiting block apply to both of these but this works so it's fine
|
||||
let app = Router::new()
|
||||
.route(
|
||||
"/:name",
|
||||
get(command).layer(
|
||||
ServiceBuilder::new()
|
||||
.layer(HandleErrorLayer::new(|err: BoxError| async move {
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Unhandled error: {err}"),
|
||||
)
|
||||
}))
|
||||
.layer(BufferLayer::new(1024))
|
||||
.layer(RateLimitLayer::new(5, Duration::from_secs(1))),
|
||||
),
|
||||
)
|
||||
.route(
|
||||
"/",
|
||||
get(StatusCode::BAD_REQUEST).layer(
|
||||
ServiceBuilder::new()
|
||||
.layer(HandleErrorLayer::new(|err: BoxError| async move {
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Unhandled error: {err}"),
|
||||
)
|
||||
}))
|
||||
.layer(BufferLayer::new(1024))
|
||||
.layer(RateLimitLayer::new(5, Duration::from_secs(1))),
|
||||
),
|
||||
);
|
||||
|
||||
let args: Vec<String> = env::args().collect();
|
||||
if args.len() < 2 {
|
||||
println!("Provide a port with manserve $PORT");
|
||||
exit(1);
|
||||
}
|
||||
if args[1].parse::<u16>().is_ok() {
|
||||
let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{}", args[1]))
|
||||
.await
|
||||
.unwrap();
|
||||
println!("Starting server on port {}", args[1]);
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
} else {
|
||||
println!("Could not parse port {}", args[1]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
async fn command(Path(name): Path<String>) -> Result<Html<String>, StatusCode> {
|
||||
let mut manpage_loc = String::from_utf8(
|
||||
Command::new("man")
|
||||
.args(["-w", name.as_str()])
|
||||
.output()
|
||||
.unwrap()
|
||||
.stdout,
|
||||
)
|
||||
.unwrap();
|
||||
manpage_loc.pop();
|
||||
let man = Command::new("mandoc")
|
||||
.arg("-Thtml")
|
||||
.arg("-O")
|
||||
.arg("fragment")
|
||||
.arg(manpage_loc)
|
||||
.output()
|
||||
.unwrap();
|
||||
match man.status.success() {
|
||||
true => Ok(Html(String::from_utf8(man.stdout).unwrap())),
|
||||
false => Err(StatusCode::BAD_REQUEST),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user