+25
knotserver/router.go
+25
knotserver/router.go
···
5
5
"fmt"
6
6
"log/slog"
7
7
"net/http"
8
+
"strings"
8
9
9
10
"github.com/go-chi/chi/v5"
10
11
"tangled.org/core/idresolver"
···
79
80
})
80
81
81
82
r.Route("/{did}", func(r chi.Router) {
83
+
r.Use(h.resolveDidRedirect)
82
84
r.Route("/{name}", func(r chi.Router) {
83
85
// routes for git operations
84
86
r.Get("/info/refs", h.InfoRefs)
···
113
115
}
114
116
115
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
+
})
116
141
}
117
142
118
143
func (h *Knot) configureOwner() error {