package templer import ( "context" "fmt" "log/slog" "net/http" "net/url" "strings" ) type ctxKey int const ( pathKey ctxKey = iota headerKey titleKey ) func Middleware(next http.Handler) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() ctx = context.WithValue(ctx, pathKey, r.URL.Path) next.ServeHTTP(w, r.WithContext(ctx)) } } // Path returns the current path with a leading slash func Path(ctx context.Context) string { path, ok := ctx.Value(pathKey).(string) if !ok { slog.Error("could not extract request path from context") return "" } return path } func RelativePath(ctx context.Context, relPath string) (path string, err error) { baseStr := Path(ctx) if baseStr != "" && !strings.HasSuffix(baseStr, "/") { baseStr += "/" } base, err := url.Parse(baseStr) if err != nil { err = fmt.Errorf("could not parse base path: %w", err) return } rel, err := url.Parse(relPath) if err != nil { err = fmt.Errorf("could not parse relative path: %w", err) return } // Resolve the relative path against the base path = base.ResolveReference(rel).Path if strings.HasSuffix(path, "/") { path = path[:len(path)-1] } return }