this repo has no description

knotserver: redirect handle-path to did-path

this will allow handle based url when cloning from knot over https
usually appview will resolve this before redirecting to the knot

this implementation just redirects to resolved path instead of passing
the entire identity for performance. As we won't want to resolve same
identity twice when proxied by appview.

Signed-off-by: Seongmin Lee <git@boltless.me>

Changed files
+25
knotserver
+25
knotserver/router.go
··· 5 "fmt" 6 "log/slog" 7 "net/http" 8 9 "github.com/go-chi/chi/v5" 10 "tangled.org/core/idresolver" ··· 79 }) 80 81 r.Route("/{did}", func(r chi.Router) { 82 r.Route("/{name}", func(r chi.Router) { 83 // routes for git operations 84 r.Get("/info/refs", h.InfoRefs) ··· 113 } 114 115 return xrpc.Router() 116 } 117 118 func (h *Knot) configureOwner() error {
··· 5 "fmt" 6 "log/slog" 7 "net/http" 8 + "strings" 9 10 "github.com/go-chi/chi/v5" 11 "tangled.org/core/idresolver" ··· 80 }) 81 82 r.Route("/{did}", func(r chi.Router) { 83 + r.Use(h.resolveDidRedirect) 84 r.Route("/{name}", func(r chi.Router) { 85 // routes for git operations 86 r.Get("/info/refs", h.InfoRefs) ··· 115 } 116 117 return xrpc.Router() 118 + } 119 + 120 + func (h *Knot) resolveDidRedirect(next http.Handler) http.Handler { 121 + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 122 + didOrHandle := chi.URLParam(r, "did") 123 + if strings.HasPrefix(didOrHandle, "did:") { 124 + next.ServeHTTP(w, r) 125 + return 126 + } 127 + 128 + trimmed := strings.TrimPrefix(didOrHandle, "@") 129 + id, err := h.resolver.ResolveIdent(r.Context(), trimmed) 130 + if err != nil { 131 + // invalid did or handle 132 + h.l.Error("failed to resolve did/handle", "handle", trimmed, "err", err) 133 + http.Error(w, fmt.Sprintf("failed to resolve did/handle: %s", trimmed), http.StatusInternalServerError) 134 + return 135 + } 136 + 137 + suffix := strings.TrimPrefix(r.URL.Path, "/"+didOrHandle) 138 + newPath := fmt.Sprintf("/%s/%s?%s", id.DID.String(), suffix, r.URL.RawQuery) 139 + http.Redirect(w, r, newPath, http.StatusTemporaryRedirect) 140 + }) 141 } 142 143 func (h *Knot) configureOwner() error {