mod config;
mod handlers;
mod network;
use config::config;
use url::Url;
use windmark::response::Response;
#[windmark::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let cfg: config::Config = config()?; let version: &'static str = cfg.crate_version;
return windmark::router::Router::new()
.set_private_key_file(format!("{}/key.pem", cfg.certs_dir))
.set_certificate_file(format!("{}/cert.pem", cfg.certs_dir))
.add_header(|_| String::from("# Forgejo Proxy"))
.add_footer(move |ctx: windmark::context::RouteContext| {
let base: &str = ctx.url.path().split("/").collect::<Vec<&str>>()[1];
println!("base: '{base}'");
let mode_dest: &str;
if base == "users" {
mode_dest = "/ Recent Activity";
} else {
mode_dest = "/users Users";
}
return format!("\n=> {mode_dest}\n\nPowered by git-gemini-forge v{version}\n=> https://git.average.name/AverageHelper/git-gemini-forge View source")
})
.mount("/", |_| {
async {
let cfg: config::Config = config().unwrap(); match handlers::root::handler(&cfg) {
Ok(res) => res,
Err(network::error::Error::NetworkFailure) => Response::temporary_failure("Couldn't communicate with the forge."),
Err(network::error::Error::UnexpectedResponse) => Response::temporary_failure("The upstream gave us a response we don't understand"),
}
}
})
.mount("/users", |_| {
async {
let cfg: config::Config = config().unwrap(); match handlers::users::handler(&cfg) {
Ok(res) => res,
Err(network::error::Error::NetworkFailure) => Response::temporary_failure("Couldn't communicate with the forge."),
Err(network::error::Error::UnexpectedResponse) => Response::temporary_failure("The upstream gave us a response we don't understand"),
}
}
})
.mount("/:user", |ctx| {
async move {
let user: &str = ctx.url.path().split("/").last().unwrap_or("");
let cfg: config::Config = config().unwrap(); match handlers::user::handler(&cfg, &user) {
Ok(res) => res,
Err(network::error::Error::NetworkFailure) => Response::temporary_failure("Couldn't communicate with the forge."),
Err(network::error::Error::UnexpectedResponse) => Response::temporary_failure("The upstream gave us a response we don't understand"),
}
}
})
.mount("/:user/:repo", |ctx| {
async move {
let user: &str = ctx.url.path().split("/").collect::<Vec<&str>>()[1];
let repo: &str = ctx.url.path().split("/").collect::<Vec<&str>>()[2];
let cfg: config::Config = config().unwrap(); match handlers::repo::handler(&cfg, &user, &repo) {
Ok(res) => res,
Err(network::error::Error::NetworkFailure) => Response::temporary_failure("Couldn't communicate with the forge."),
Err(network::error::Error::UnexpectedResponse) => Response::temporary_failure("The upstream gave us a response we don't understand"),
}
}
})
.set_error_handler(|error| {
let failure_addr: Url = error.url;
println!("Failed to serve {}", failure_addr.as_str());
return Response::temporary_failure("Something went wrong!");
})
.run()
.await
}