diff --git a/net/ghttp/ghttp_request_param_ctx.go b/net/ghttp/ghttp_request_param_ctx.go index aae38f7bea3..5c55148ddca 100644 --- a/net/ghttp/ghttp_request_param_ctx.go +++ b/net/ghttp/ghttp_request_param_ctx.go @@ -8,11 +8,32 @@ package ghttp import ( "context" + "time" "github.com/gogf/gf/v2/container/gvar" "github.com/gogf/gf/v2/os/gctx" ) +// neverDoneCtx never done. +type neverDoneCtx struct { + context.Context +} + +// Done forbids the context done from parent context. +func (*neverDoneCtx) Done() <-chan struct{} { + return nil +} + +// Deadline forbids the context deadline from parent context. +func (*neverDoneCtx) Deadline() (deadline time.Time, ok bool) { + return time.Time{}, false +} + +// Err forbids the context done from parent context. +func (c *neverDoneCtx) Err() error { + return nil +} + // RequestFromCtx retrieves and returns the Request object from context. func RequestFromCtx(ctx context.Context) *Request { if v := ctx.Value(ctxKeyForRequest); v != nil { @@ -26,7 +47,12 @@ func RequestFromCtx(ctx context.Context) *Request { // See GetCtx. func (r *Request) Context() context.Context { if r.context == nil { - r.context = gctx.WithCtx(r.Request.Context()) + // It forbids the context manually done, + // to make the context can be propagated to asynchronous goroutines. + r.context = &neverDoneCtx{ + r.Request.Context(), + } + r.context = gctx.WithCtx(r.context) } // Inject Request object into context. if RequestFromCtx(r.context) == nil {