Skip to content

huma.WithValue + context.Unwrap loses request context #859

@costela

Description

@costela

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions