upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/http/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/http/mod.rs')
-rw-r--r--src/http/mod.rs19
1 files changed, 10 insertions, 9 deletions
diff --git a/src/http/mod.rs b/src/http/mod.rs
index c397365..154d6c5 100644
--- a/src/http/mod.rs
+++ b/src/http/mod.rs
@@ -42,8 +42,11 @@ const ICON_PNG: &[u8] = include_bytes!("../../static/icon.png");
42/// 42///
43/// Parses paths like `/<npub>/<identifier>.git` (for repository webpage/404) 43/// Parses paths like `/<npub>/<identifier>.git` (for repository webpage/404)
44/// 44///
45/// The identifier is percent-decoded so that URLs like `/npub1.../my%20repo.git`
46/// resolve to the correct filesystem path.
47///
45/// Returns (npub, identifier) if the path matches a repository URL pattern 48/// Returns (npub, identifier) if the path matches a repository URL pattern
46fn parse_repo_url(path: &str) -> Option<(&str, &str)> { 49fn parse_repo_url(path: &str) -> Option<(String, String)> {
47 // Remove leading slash 50 // Remove leading slash
48 let path = path.strip_prefix('/').unwrap_or(path); 51 let path = path.strip_prefix('/').unwrap_or(path);
49 52
@@ -56,7 +59,7 @@ fn parse_repo_url(path: &str) -> Option<(&str, &str)> {
56 } 59 }
57 60
58 let npub = parts[0]; 61 let npub = parts[0];
59 let repo_part = parts[1]; 62 let repo_part = git::percent_decode(parts[1]);
60 63
61 // The repo part must end with .git 64 // The repo part must end with .git
62 if !repo_part.ends_with(".git") { 65 if !repo_part.ends_with(".git") {
@@ -69,14 +72,17 @@ fn parse_repo_url(path: &str) -> Option<(&str, &str)> {
69 } 72 }
70 73
71 // Extract identifier (remove .git suffix) 74 // Extract identifier (remove .git suffix)
72 let identifier = repo_part.strip_suffix(".git").unwrap_or(repo_part); 75 let identifier = repo_part
76 .strip_suffix(".git")
77 .unwrap_or(&repo_part)
78 .to_string();
73 79
74 // Identifier must not be empty 80 // Identifier must not be empty
75 if identifier.is_empty() { 81 if identifier.is_empty() {
76 return None; 82 return None;
77 } 83 }
78 84
79 Some((npub, identifier)) 85 Some((npub.to_string(), identifier))
80} 86}
81 87
82/// Add CORS headers to a response builder 88/// Add CORS headers to a response builder
@@ -160,9 +166,6 @@ impl Service<Request<Incoming>> for HttpService {
160 166
161 // Check for Git HTTP requests first 167 // Check for Git HTTP requests first
162 if let Some((npub, identifier, subpath)) = git::parse_git_url(&path) { 168 if let Some((npub, identifier, subpath)) = git::parse_git_url(&path) {
163 let npub = npub.to_string();
164 let identifier = identifier.to_string();
165 let subpath = subpath.to_string();
166 169
167 // Extract Git-Protocol header for protocol v2 support 170 // Extract Git-Protocol header for protocol v2 support
168 let git_protocol = req 171 let git_protocol = req
@@ -391,8 +394,6 @@ impl Service<Request<Incoming>> for HttpService {
391 // GRASP-01: "SHOULD serve a webpage at the same endpoint linking to git nostr client(s) 394 // GRASP-01: "SHOULD serve a webpage at the same endpoint linking to git nostr client(s)
392 // to browse the repository and a 404 page for repositories it doesn't host" 395 // to browse the repository and a 404 page for repositories it doesn't host"
393 if let Some((npub, identifier)) = parse_repo_url(&path) { 396 if let Some((npub, identifier)) = parse_repo_url(&path) {
394 let npub = npub.to_string();
395 let identifier = identifier.to_string();
396 let config = self.config.clone(); 397 let config = self.config.clone();
397 let repo_path = git::resolve_repo_path(&git_data_path, &npub, &identifier); 398 let repo_path = git::resolve_repo_path(&git_data_path, &npub, &identifier);
398 399