From 7834a03e8467c1b58eda0efd58374896f240f69c Mon Sep 17 00:00:00 2001 From: wei Date: Thu, 24 Jun 2021 16:33:14 +0800 Subject: [PATCH] gin.Context with fallback value from gin.Context.Request.Context() (#2751) * Update tree.go (#2659) delete more "()" * updated comments for Get function for params (#2756) * ci: add github action workflows (#2596) * ci: add github action workflows * test: fixed the TestUnixSocket test on windows (#20) * ci: add github action workflows (#18) * Remove .travis.yml * ci: replace GITTER_ROOM_ID and upload coverage every time you go test * ci: update coverage using codecov/codecov-action@v1 * Merge branch 'master' into github-actions * repo: replace travis ci to github actions * ci: add go version 1.16 * fix: go install requires a specific version * chore(ci): remove go 1.12 support * chore(ci): remove os windows-latest Co-authored-by: thinkerou Co-authored-by: Bo-Yi Wu * Setting trusted platform using an enum-like (#2739) * gin.Context with fallback value from c.Request.Context() * add test case Co-authored-by: youzeliang Co-authored-by: Ashwani Co-authored-by: Jeff Co-authored-by: thinkerou Co-authored-by: Bo-Yi Wu Co-authored-by: Alessandro (Ale) Segala <43508+ItalyPaleAle@users.noreply.github.com> --- context.go | 10 +++++++--- context_test.go | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/context.go b/context.go index 5c1aba5e61..ede16fd4d8 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 93b58ee8e1..2a4d21856e 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)) + }) + } +}