65 lines
1.2 KiB
Go
65 lines
1.2 KiB
Go
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
|
|
}
|