package grasp import ( "fmt" "net/http" "regexp" "strings" "fiatjaf.com/nostr" "fiatjaf.com/nostr/nip19" ) var asciiPattern = regexp.MustCompile(`^[\w-.]+$`) // handleGitRequest validates .git suffix and decodes npub, then calls the handler func (gs *GraspServer) handleGitRequest( w http.ResponseWriter, r *http.Request, base http.Handler, handler func(http.ResponseWriter, *http.Request, nostr.PubKey, string, ), ) { npub := r.PathValue("npub") repoWithGit := r.PathValue("repo") // validate .git suffix if !strings.HasSuffix(repoWithGit, ".git") { base.ServeHTTP(w, r) return } repoName := strings.TrimSuffix(repoWithGit, ".git") // validate repo name if !asciiPattern.MatchString(repoName) { http.Error(w, "invalid repository name", 400) return } // decode npub to pubkey _, value, err := nip19.Decode(npub) if err != nil { http.Error(w, "invalid npub", 400) return } pk, ok := value.(nostr.PubKey) if !ok { http.Error(w, "invalid npub", 400) return } handler(w, r, pk, repoName) } // serveRepoPage serves a webpage for the repository func (gs *GraspServer) serveRepoPage(w http.ResponseWriter, r *http.Request, npub, repoName string) { w.Header().Set("Content-Type", "text/html") html := fmt.Sprintf(`
This is a NIP-34 git repository served over Nostr.
Use a git-nostr client to clone:
git clone %s/%s/%s.git
Use a git-nostr web client or Nostr client to browse this repository.
`, npub, repoName, npub, repoName, r.Host, npub, repoName) fmt.Fprint(w, html) }