Files
nostrlib/khatru/grasp/server.go
2026-02-09 14:40:37 -08:00

76 lines
2.0 KiB
Go

package grasp
import (
"context"
"fmt"
"net/http"
"os"
"fiatjaf.com/nostr"
"fiatjaf.com/nostr/khatru"
)
type GraspServer struct {
ServiceURL string
RepositoryDir string
Relay *khatru.Relay
Log func(str string, args ...any)
OnWrite func(context.Context, nostr.PubKey, string) (reject bool, reason string)
OnRead func(context.Context, nostr.PubKey, string) (reject bool, reason string)
}
// New creates a new GraspServer and registers its handlers on the relay's router
func New(rl *khatru.Relay, repositoryDir string) *GraspServer {
gs := &GraspServer{
Relay: rl,
RepositoryDir: repositoryDir,
Log: func(str string, args ...any) {
fmt.Fprintf(os.Stderr, str, args...)
},
}
rl.Info.AddSupportedNIP("34")
rl.Info.SupportedGrasps = append(rl.Info.SupportedGrasps, "GRASP-01")
base := rl.Router()
mux := http.NewServeMux()
// use specific route patterns for git endpoints
mux.HandleFunc("GET /{npub}/{repo}/info/refs", func(w http.ResponseWriter, r *http.Request) {
gs.handleGitRequest(w, r, base, gs.handleInfoRefs)
})
mux.HandleFunc("POST /{npub}/{repo}/git-upload-pack", func(w http.ResponseWriter, r *http.Request) {
gs.handleGitRequest(w, r, base, gs.handleGitUploadPack)
})
mux.HandleFunc("POST /{npub}/{repo}/git-receive-pack", func(w http.ResponseWriter, r *http.Request) {
gs.handleGitRequest(w, r, base, gs.handleGitReceivePack)
})
mux.HandleFunc("GET /{npub}/{repo}", func(w http.ResponseWriter, r *http.Request) {
gs.handleGitRequest(w, r, base, func(w http.ResponseWriter, r *http.Request, pubkey nostr.PubKey, repoName string) {
if r.URL.RawQuery == "" {
if gs.repoExists(r.Context(), pubkey, repoName) {
gs.serveRepoPage(w, r, r.PathValue("npub"), repoName)
} else {
http.NotFound(w, r)
}
} else {
base.ServeHTTP(w, r)
}
})
})
// fallback handler for all other paths
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
base.ServeHTTP(w, r)
})
rl.SetRouter(mux)
return gs
}