diff --git a/Cargo.lock b/Cargo.lock
index fece92b..239bd46 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
-version = 4
+version = 3
[[package]]
name = "addr2line"
@@ -2600,7 +2600,6 @@ dependencies = [
"tokio",
"tokio-stream",
"tokio-util",
- "tower",
"tower-http",
"tower-layer",
"tower-service",
diff --git a/Cargo.toml b/Cargo.toml
index ae94462..6f93ff9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -68,7 +68,6 @@ timeago = { version = "0.4.2", default-features = false }
tokio = { version = "1.42", features = ["full", "tracing"] }
tokio-stream = "0.1"
tokio-util = { version = "0.7.10", features = ["io"] }
-tower = "0.5"
tower-http = { version = "0.6", features = ["cors", "timeout"] }
tower-layer = "0.3"
tower-service = "0.3"
diff --git a/src/methods/repo/mod.rs b/src/methods/repo/mod.rs
index 821836d..34d8c9e 100644
--- a/src/methods/repo/mod.rs
+++ b/src/methods/repo/mod.rs
@@ -18,12 +18,11 @@ use std::{
use axum::{
body::Body,
- handler::HandlerWithoutStateExt,
+ handler::Handler,
http::{Request, StatusCode},
response::{IntoResponse, Response},
};
use path_clean::PathClean;
-use tower::{util::BoxCloneService, Service};
use self::{
about::handle as handle_about,
@@ -38,10 +37,7 @@ use self::{
tree::handle as handle_tree,
};
use crate::database::schema::tag::YokedString;
-use crate::{
- database::schema::{commit::YokedCommit, tag::YokedTag},
- layers::UnwrapInfallible,
-};
+use crate::database::schema::{commit::YokedCommit, tag::YokedTag};
pub const DEFAULT_BRANCHES: [&str; 2] = ["refs/heads/master", "refs/heads/main"];
@@ -53,15 +49,52 @@ pub async fn service(mut request: Request
) -> Response {
.get::>()
.expect("scan_path missing");
- let mut child_path = None;
+ let ParsedUri {
+ uri,
+ child_path,
+ action,
+ } = parse_uri(request.uri().path().trim_matches('/'));
+
+ let uri = Path::new(uri).clean();
+ let path = scan_path.join(&uri);
- macro_rules! h {
- ($handler:ident) => {
- BoxCloneService::new($handler.into_service())
- };
+ let db = request
+ .extensions()
+ .get::>()
+ .expect("db extension missing");
+ if path.as_os_str().is_empty()
+ || !crate::database::schema::repository::Repository::exists(db, &uri).unwrap_or_default()
+ {
+ return RepositoryNotFound.into_response();
+ }
+
+ request.extensions_mut().insert(ChildPath(child_path));
+ request.extensions_mut().insert(Repository(uri));
+ request.extensions_mut().insert(RepositoryPath(path));
+
+ match action {
+ HandlerAction::About => handle_about.call(request, None::<()>).await,
+ HandlerAction::SmartGit => handle_smart_git.call(request, None::<()>).await,
+ HandlerAction::Refs => handle_refs.call(request, None::<()>).await,
+ HandlerAction::Log => handle_log.call(request, None::<()>).await,
+ HandlerAction::Tree => handle_tree.call(request, None::<()>).await,
+ HandlerAction::Commit => handle_commit.call(request, None::<()>).await,
+ HandlerAction::Diff => handle_diff.call(request, None::<()>).await,
+ HandlerAction::Patch => handle_patch.call(request, None::<()>).await,
+ HandlerAction::Tag => handle_tag.call(request, None::<()>).await,
+ HandlerAction::Snapshot => handle_snapshot.call(request, None::<()>).await,
+ HandlerAction::Summary => handle_summary.call(request, None::<()>).await,
}
+}
+
+#[derive(Debug, PartialEq, Eq)]
+struct ParsedUri<'a> {
+ action: HandlerAction,
+ uri: &'a str,
+ child_path: Option,
+}
- let uri = request.uri().path().trim_matches('/');
+fn parse_uri(uri: &str) -> ParsedUri<'_> {
let mut uri_parts = memchr::memchr_iter(b'/', uri.as_bytes());
let original_uri = uri;
@@ -71,28 +104,75 @@ pub async fn service(mut request: Request) -> Response {
(None, uri)
};
- let mut service = match action {
- Some("about") => h!(handle_about),
- Some("git-upload-pack") => h!(handle_smart_git),
+ match action {
+ Some("about") => ParsedUri {
+ action: HandlerAction::About,
+ uri,
+ child_path: None,
+ },
+ Some("git-upload-pack") => ParsedUri {
+ action: HandlerAction::SmartGit,
+ uri,
+ child_path: None,
+ },
Some("refs") => {
if let Some(idx) = uri_parts.next_back() {
if uri.get(idx + 1..) == Some("info") {
- uri = &uri[..idx];
- h!(handle_smart_git)
+ ParsedUri {
+ action: HandlerAction::SmartGit,
+ uri: &uri[..idx],
+ child_path: None,
+ }
} else {
- h!(handle_refs)
+ ParsedUri {
+ action: HandlerAction::Refs,
+ uri,
+ child_path: None,
+ }
}
} else {
- h!(handle_refs)
+ ParsedUri {
+ action: HandlerAction::Refs,
+ uri,
+ child_path: None,
+ }
}
}
- Some("log") => h!(handle_log),
- Some("tree") => h!(handle_tree),
- Some("commit") => h!(handle_commit),
- Some("diff") => h!(handle_diff),
- Some("patch") => h!(handle_patch),
- Some("tag") => h!(handle_tag),
- Some("snapshot") => h!(handle_snapshot),
+ Some("log") => ParsedUri {
+ action: HandlerAction::Log,
+ uri,
+ child_path: None,
+ },
+ Some("tree") => ParsedUri {
+ action: HandlerAction::Tree,
+ uri,
+ child_path: None,
+ },
+ Some("commit") => ParsedUri {
+ action: HandlerAction::Commit,
+ uri,
+ child_path: None,
+ },
+ Some("diff") => ParsedUri {
+ action: HandlerAction::Diff,
+ uri,
+ child_path: None,
+ },
+ Some("patch") => ParsedUri {
+ action: HandlerAction::Patch,
+ uri,
+ child_path: None,
+ },
+ Some("tag") => ParsedUri {
+ action: HandlerAction::Tag,
+ uri,
+ child_path: None,
+ },
+ Some("snapshot") => ParsedUri {
+ action: HandlerAction::Snapshot,
+ uri,
+ child_path: None,
+ },
Some(_) => {
static TREE_FINDER: LazyLock =
LazyLock::new(|| memchr::memmem::Finder::new(b"/tree/"));
@@ -101,39 +181,41 @@ pub async fn service(mut request: Request) -> Response {
// match tree children
if let Some(idx) = TREE_FINDER.find(uri.as_bytes()) {
- // 6 is the length of /tree/
- child_path = Some(Path::new(&uri[idx + 6..]).clean());
- uri = &uri[..idx];
- h!(handle_tree)
+ ParsedUri {
+ action: HandlerAction::Tree,
+ uri: &uri[..idx],
+ // 6 is the length of /tree/
+ child_path: Some(Path::new(&uri[idx + 6..]).clean()),
+ }
} else {
- h!(handle_summary)
+ ParsedUri {
+ action: HandlerAction::Summary,
+ uri,
+ child_path: None,
+ }
}
}
- None => h!(handle_summary),
- };
-
- let uri = Path::new(uri).clean();
- let path = scan_path.join(&uri);
-
- let db = request
- .extensions()
- .get::>()
- .expect("db extension missing");
- if path.as_os_str().is_empty()
- || !crate::database::schema::repository::Repository::exists(db, &uri).unwrap_or_default()
- {
- return RepositoryNotFound.into_response();
+ None => ParsedUri {
+ action: HandlerAction::Summary,
+ uri,
+ child_path: None,
+ },
}
+}
- request.extensions_mut().insert(ChildPath(child_path));
- request.extensions_mut().insert(Repository(uri));
- request.extensions_mut().insert(RepositoryPath(path));
-
- service
- .call(request)
- .await
- .unwrap_infallible()
- .into_response()
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+enum HandlerAction {
+ About,
+ SmartGit,
+ Refs,
+ Log,
+ Tree,
+ Commit,
+ Diff,
+ Patch,
+ Tag,
+ Snapshot,
+ Summary,
}
#[derive(Clone)]