From 875de1875719d8139c5525818284439208bc90b3 Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Wed, 22 Oct 2025 18:27:15 +0000 Subject: [PATCH] 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 --- knotserver/router.go | 25 +++++++++++++++++++++++++ 1 file(s) changed, 25 insertion(s)(+), 0 deletion(s)(-) diff --git a/knotserver/router.go b/knotserver/router.go --- a/knotserver/router.go +++ b/knotserver/router.go @@ -5,6 +5,7 @@ "fmt" "log/slog" "net/http" + "strings" "github.com/go-chi/chi/v5" "tangled.org/core/idresolver" @@ -79,6 +80,7 @@ }) r.Route("/{did}", func(r chi.Router) { + r.Use(h.resolveDidRedirect) r.Route("/{name}", func(r chi.Router) { // routes for git operations r.Get("/info/refs", h.InfoRefs) @@ -114,6 +116,29 @@ } return xrpc.Router() +} + +func (h *Knot) resolveDidRedirect(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + didOrHandle := chi.URLParam(r, "did") + if strings.HasPrefix(didOrHandle, "did:") { + next.ServeHTTP(w, r) + return + } + + trimmed := strings.TrimPrefix(didOrHandle, "@") + id, err := h.resolver.ResolveIdent(r.Context(), trimmed) + if err != nil { + // invalid did or handle + h.l.Error("failed to resolve did/handle", "handle", trimmed, "err", err) + http.Error(w, fmt.Sprintf("failed to resolve did/handle: %s", trimmed), http.StatusInternalServerError) + return + } + + suffix := strings.TrimPrefix(r.URL.Path, "/"+didOrHandle) + newPath := fmt.Sprintf("/%s/%s?%s", id.DID.String(), suffix, r.URL.RawQuery) + http.Redirect(w, r, newPath, http.StatusTemporaryRedirect) + }) } func (h *Knot) configureOwner() error { -- tangled.sh