From 57d2cd5549607baa7911ac3dfaa8e3c2b257f6f6 Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Thu, 23 Oct 2025 03:27:15 +0900 Subject: [PATCH] knotserver: redirect handle-path to did-path Change-Id: xpolynpvotztkopmlwntwlyrnwnrswnz 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 changed, 25 insertions(+) diff --git a/knotserver/router.go b/knotserver/router.go index 482f932d..c13d6ce5 100644 --- a/knotserver/router.go +++ b/knotserver/router.go @@ -5,6 +5,7 @@ import ( "fmt" "log/slog" "net/http" + "strings" "github.com/go-chi/chi/v5" "tangled.org/core/idresolver" @@ -79,6 +80,7 @@ func (h *Knot) Router() http.Handler { }) 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) @@ -115,6 +117,29 @@ func (h *Knot) XrpcRouter() http.Handler { 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 { cfgOwner := h.c.Server.Owner -- 2.43.0