repos
/ repos-rust master

repos-rust

mirror archived upstream

A minimal self-hosted git browser on Rust axum: bare repos rendered as a website with commits, diffs, syntax-highlighted blobs, atom feeds, and clone over HTTPS.

axumdockergitgit-browsergitoxidegixrustself-hosted

1.4 KB · 47 lines · Rust Raw History
 1use axum::{
 2    extract::State,
 3    http::{header, StatusCode},
 4    response::{IntoResponse, Response},
 5    routing::get,
 6    Router,
 7};
 8
 9use crate::AppState;
10
11pub fn router() -> Router<AppState> {
12    Router::new()
13        .route("/favicon.ico", get(favicon))
14        .route("/favicon.svg", get(favicon))
15        .route("/robots.txt", get(robots))
16}
17
18/// Serve the favicon from the built `dist/` directory. Vite copies anything in
19/// `frontend/static_src/public/` into the build output, so `dist/favicon.svg`
20/// is what ships in the runtime image (the `frontend/` source tree is not).
21async fn favicon(State(state): State<AppState>) -> Response {
22    let full = state.config.root.join("dist/favicon.svg");
23    match std::fs::read(&full) {
24        Ok(data) => {
25            let mut resp = data.into_response();
26            resp.headers_mut()
27                .insert(header::CONTENT_TYPE, "image/svg+xml".parse().unwrap());
28            resp.headers_mut().insert(
29                header::CACHE_CONTROL,
30                "public, max-age=86400".parse().unwrap(),
31            );
32            resp
33        }
34        Err(_) => (StatusCode::NOT_FOUND, "no favicon").into_response(),
35    }
36}
37
38async fn robots() -> Response {
39    let body = "User-agent: *\nAllow: /\n";
40    let mut resp = body.into_response();
41    resp.headers_mut().insert(
42        header::CONTENT_TYPE,
43        "text/plain; charset=utf-8".parse().unwrap(),
44    );
45    resp
46}