web: redirect /<repo>/ to the repo home
Assisted-by: Claude Opus 5 via Claude Code
diff --git a/quire-server/src/quire/web/handlers/mod.rs b/quire-server/src/quire/web/handlers/mod.rs
index d3ee74c..3f71675 100644
--- a/quire-server/src/quire/web/handlers/mod.rs
+++ b/quire-server/src/quire/web/handlers/mod.rs
@@ -11,7 +11,7 @@ mod tree;
pub use ci::{run_detail, run_list};
pub use commit::commit_view;
pub use log_view::log_view;
-pub use repo::repo_home;
+pub use repo::{repo_home, repo_home_slash};
pub use repo_list::repo_list;
pub use tree::{tree_view, tree_view_path};
@@ -205,6 +205,23 @@ mod tests {
assert_eq!(resp.status(), StatusCode::OK);
}
+ #[tokio::test]
+ async fn repo_home_redirects_trailing_slash() {
+ let env = TestEnv::new();
+ let resp = env
+ .app()
+ .oneshot(
+ Request::builder()
+ .uri("/example/")
+ .body(Body::empty())
+ .unwrap(),
+ )
+ .await
+ .unwrap();
+ assert_eq!(resp.status(), StatusCode::PERMANENT_REDIRECT);
+ assert_eq!(resp.headers()[axum::http::header::LOCATION], "/example");
+ }
+
#[tokio::test]
async fn run_list_returns_ok_for_known_repo() {
let env = TestEnv::new();
diff --git a/quire-server/src/quire/web/handlers/repo.rs b/quire-server/src/quire/web/handlers/repo.rs
index a7ba2b7..6bfe078 100644
--- a/quire-server/src/quire/web/handlers/repo.rs
+++ b/quire-server/src/quire/web/handlers/repo.rs
@@ -1,7 +1,7 @@
//! Handler for the repository home page.
-use axum::extract::State;
-use axum::response::Response;
+use axum::extract::{Path, State};
+use axum::response::{Redirect, Response};
use super::super::auth::Auth;
use super::super::db;
@@ -12,6 +12,13 @@ use super::render;
use crate::Quire;
use crate::quire::web::paths::RepoPath;
+/// Redirect `/{repo}/` to the canonical `/{repo}`.
+///
+/// Nothing links to the trailing-slash form, but people type it and paste it.
+pub async fn repo_home_slash(Path(repo): Path<String>) -> Redirect {
+ Redirect::permanent(&format!("/{repo}"))
+}
+
pub async fn repo_home(
RepoPath { repo }: RepoPath,
State(quire): State<Quire>,
diff --git a/quire-server/src/quire/web/mod.rs b/quire-server/src/quire/web/mod.rs
index 4de6c05..2a409c5 100644
--- a/quire-server/src/quire/web/mod.rs
+++ b/quire-server/src/quire/web/mod.rs
@@ -20,8 +20,8 @@ use axum_extra::routing::RouterExt;
use crate::{
Quire,
quire::web::handlers::{
- commit_view, config, file_view_script, log_view, repo_home, repo_list, run_detail,
- run_list, stylesheet, tree_view, tree_view_path,
+ commit_view, config, file_view_script, log_view, repo_home, repo_home_slash, repo_list,
+ run_detail, run_list, stylesheet, tree_view, tree_view_path,
},
};
@@ -95,6 +95,7 @@ pub fn public_router(quire: Quire) -> Router {
.route("/style.css", get(stylesheet))
.route("/file-view.js", get(file_view_script))
.typed_get(repo_home)
+ .route("/{repo}/", get(repo_home_slash))
.typed_get(tree_view)
.typed_get(tree_view_path)
.typed_get(log_view)