wayver's git archive


a simple self-hosted git server
git clone https://git.wayver.dev/bile

src/handlers/repo_file_raw.rs@f3f2b40f0ffae5de2e6d3f661e32b582274bae49

raw
Date Commit Message Author Files + -
2026-02-17 21:07 initial mvp wayverd 74 10800 0
...

1use std::path;
2
3use axum::{
4    extract::Path,
5    http::{StatusCode, header},
6    response::{IntoResponse as _, Response},
7};
8
9use crate::utils::{
10    Error, Result, blob_mime, error::Context as _, extractor::repo_name_checks, git::Repository,
11    spawn_blocking,
12};
13
14#[tracing::instrument(skip_all)]
15pub async fn get(
16    Path((repo_name, r#ref, object_name)): Path<(String, String, String)>,
17) -> Response {
18    spawn_blocking(move || inner(&repo_name, &r#ref, &object_name).into_response()).await
19}
20
21#[tracing::instrument(skip_all)]
22fn inner(repo_name: &str, r#ref: &str, object_name: &str) -> Result {
23    repo_name_checks(repo_name)?;
24
25    let Some(repo) = Repository::open(repo_name).context("opening repository")? else {
26        return Err(Error::new(StatusCode::NOT_FOUND, "repo does not exist"));
27    };
28
29    let path = path::Path::new(&object_name);
30
31    let Some((_, tree)) = repo
32        .commit_tree(r#ref)
33        .context("failed to get commit tree")?
34    else {
35        return Err(Error::new(
36            StatusCode::NOT_FOUND,
37            "commit does not exist in repo",
38        ));
39    };
40
41    let Some(blob) = repo.tree_blob(&tree, path)? else {
42        return Err(Error::new(
43            StatusCode::NOT_FOUND,
44            "file does not exist into repo",
45        ));
46    };
47
48    let extension = path
49        .extension()
50        .and_then(std::ffi::OsStr::to_str)
51        .unwrap_or_default();
52
53    let mime = blob_mime(&blob, extension);
54
55    Ok((
56        StatusCode::OK,
57        [(header::CONTENT_TYPE, mime.as_ref())],
58        blob.content().to_vec(),
59    )
60        .into_response())
61}
62