diff --git a/main.go b/main.go index 49f4dee..36542fb 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,55 @@ package main -import "fmt" +import ( + "context" + "fmt" + "net/http" +) + +// Context key and route context — simplified chi pattern for URL parameters. +type contextKey struct{} + +// RouteContext caches the matched pattern and extracted URL parameters. +type RouteContext struct { + RoutePath string + Params map[string]string +} + +// URLParam retrieves a URL parameter from the request context. +func URLParam(r *http.Request, key string) string { + rc, _ := r.Context().Value(contextKey{}).(*RouteContext) + if rc == nil || rc.Params == nil { + return "" + } + return rc.Params[key] +} + +// WithRouteContext stores route context in the request. +func WithRouteContext(r *http.Request, rc *RouteContext) *http.Request { + return r.WithContext(context.WithValue(r.Context(), contextKey{}, rc)) +} + +// PathRewriteMiddleware demonstrates how to correctly rewrite the URL path +// while preserving URL parameter resolution for downstream handlers. +// +// When r.URL.Path is modified, RoutePath must be updated so that subsequent +// route matching and param extraction operate on the rewritten path rather +// than the original one. +func PathRewriteMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + rc, _ := r.Context().Value(contextKey{}).(*RouteContext) + if rc != nil { + // Update RoutePath to match the new URL path so URLParam() + // resolves parameters from the rewritten path. + rc.RoutePath = r.URL.Path + } + next.ServeHTTP(w, r) + }) +} func main() { fmt.Println("Hello, Bounty Hunter!") } + +// Compile-time guard: http.Handler interface satisfaction. +var _ http.Handler = (http.HandlerFunc)(nil)