diff --git a/context.go b/context.go index 5c1aba5e..ede16fd4 100644 --- a/context.go +++ b/context.go @@ -1186,8 +1186,12 @@ func (c *Context) Value(key interface{}) interface{} { return c.Request } if keyAsString, ok := key.(string); ok { - val, _ := c.Get(keyAsString) - return val + if val, exists := c.Get(keyAsString); exists { + return val + } } - return nil + if c.Request == nil || c.Request.Context() == nil { + return nil + } + return c.Request.Context().Value(key) } diff --git a/context_test.go b/context_test.go index 93b58ee8..2a4d2185 100644 --- a/context_test.go +++ b/context_test.go @@ -2057,3 +2057,56 @@ func TestRemoteIPFail(t *testing.T) { assert.Nil(t, ip) assert.False(t, trust) } + +func TestContextWithFallbackValueFromRequestContext(t *testing.T) { + tests := []struct { + name string + getContextAndKey func() (*Context, interface{}) + value interface{} + }{ + { + name: "c with struct context key", + getContextAndKey: func() (*Context, interface{}) { + var key struct{} + c := &Context{} + c.Request, _ = http.NewRequest("POST", "/", nil) + c.Request = c.Request.WithContext(context.WithValue(context.TODO(), key, "value")) + return c, key + }, + value: "value", + }, + { + name: "c with string context key", + getContextAndKey: func() (*Context, interface{}) { + c := &Context{} + c.Request, _ = http.NewRequest("POST", "/", nil) + c.Request = c.Request.WithContext(context.WithValue(context.TODO(), "key", "value")) + return c, "key" + }, + value: "value", + }, + { + name: "c with nil http.Request", + getContextAndKey: func() (*Context, interface{}) { + c := &Context{} + return c, "key" + }, + value: nil, + }, + { + name: "c with nil http.Request.Context()", + getContextAndKey: func() (*Context, interface{}) { + c := &Context{} + c.Request, _ = http.NewRequest("POST", "/", nil) + return c, "key" + }, + value: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c, key := tt.getContextAndKey() + assert.Equal(t, tt.value, c.Value(key)) + }) + } +}