From e233fe407683469e9921a9332f0a834a3dbe5b58 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 56fd9eac..7ee80282 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" @@ -78,6 +79,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) @@ -114,6 +116,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