httpd: Return 404 for unknown archive refs

/raw/<rid>/archive/<ref> passed the git2 error from
resolve_reference_from_short_name straight through, so a typo in the
branch name or a commit SHA in place of a ref yielded a 500. Map
ErrorCode::NotFound to 404 like we already do for the object lookup.

Signed-off-by: Jörg Thalheim <joerg@thalheim.io>
This commit is contained in:
Jörg Thalheim
2026-10-22 09:53:03 +02:00
committed by Rūdolfs Ošiņš
parent e41de09a55
commit cc67fd894a
+26 -8
View File
@@ -229,23 +229,28 @@ async fn archive_by_committish(
let project = doc.project()?;
let repo_name = project.name();
let not_found = |e: radicle::git::raw::Error| {
if e.code() == ErrorCode::NotFound {
Error::NotFound
} else {
Error::Git(e)
}
};
let oid = match committish {
Committish::Oid(oid) => oid,
Committish::Ref(refname) => repo
.backend
.resolve_reference_from_short_name(refname)
.map(|reference| reference.target())?
.map_err(not_found)?
.target()
.ok_or(Error::NotFound)?
.into(),
};
if let Err(e) = repo.backend.find_object(oid.into(), None) {
return Err(if e.code() == ErrorCode::NotFound {
Error::NotFound
} else {
Error::Git(e)
});
}
repo.backend
.find_object(oid.into(), None)
.map_err(not_found)?;
// Build a prefix for the archive, which includes the
// refname (if one was given):
@@ -446,6 +451,19 @@ mod routes {
assert_eq!(&body[..4], &[0x28, 0xb5, 0x2f, 0xfd]);
}
#[tokio::test]
async fn test_archive_unknown_ref() {
let tmp = tempfile::tempdir().unwrap();
let ctx = test::seed(tmp.path());
let app = super::router(ctx.profile().to_owned(), Arc::new(HashMap::new()));
let response = get(&app, format!("/{RID}/archive/master.tar.gz")).await;
assert_eq!(response.status(), StatusCode::OK);
let response = get(&app, format!("/{RID}/archive/does-not-exist.tar.gz")).await;
assert_eq!(response.status(), StatusCode::NOT_FOUND);
}
#[tokio::test]
async fn test_alias_resolution() {
let tmp = tempfile::tempdir().unwrap();