huma icon indicating copy to clipboard operation
huma copied to clipboard

huma.WithValue + context.Unwrap loses request context

Open costela opened this issue 6 months ago • 0 comments

Currently, using huma.WithValue in a pure-huma middleware sets the value only in huma.Context. This does not get propagated to the underlying adapter context, so using Unwrap (e.g. humachi.Unwrap) in a different middleware naively - e.g. when trying to use a stdlib compatible middleware - causes the context to be lost.

This is the naive middleware adapter code:

func humaChiMiddleware(mw func(http.Handler) http.Handler) func(ctx huma.Context, next func(huma.Context)) {
	return func(ctx huma.Context, next func(huma.Context)) {
		r, w := humachi.Unwrap(ctx)
		mw(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			ctx = humachi.NewContext(ctx.Operation(), r, w)
			next(ctx) // ← this new context potentially lost 
		})).ServeHTTP(w, r)
	}
}

This can be worked around like so:

func humaChiMiddleware(mw func(http.Handler) http.Handler) func(ctx huma.Context, next func(huma.Context)) {
	return func(ctx huma.Context, next func(huma.Context)) {
		r, w := humachi.Unwrap(ctx)
		mw(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			r = r.WithContext(ctx.Context()) // ✨ 
			ctx = humachi.NewContext(ctx.Operation(), r, w)
			next(ctx)
		})).ServeHTTP(w, r)
	}
}

I think this should be the responsibility of the adapter to add it to the appropriate underlying context? I'll try to come up with a PR for that.

costela avatar Jul 07 '25 13:07 costela