@@ -2097,12 +2097,18 @@ func TestRemoteIPFail(t *testing.T) {
2097
2097
}
2098
2098
2099
2099
func TestContextWithFallbackDeadlineFromRequestContext (t * testing.T ) {
2100
- c := & Context {}
2100
+ c , _ := CreateTestContext (httptest .NewRecorder ())
2101
+ // enable ContextWithFallback feature flag
2102
+ c .engine .ContextWithFallback = true
2103
+
2101
2104
deadline , ok := c .Deadline ()
2102
2105
assert .Zero (t , deadline )
2103
2106
assert .False (t , ok )
2104
2107
2105
- c2 := & Context {}
2108
+ c2 , _ := CreateTestContext (httptest .NewRecorder ())
2109
+ // enable ContextWithFallback feature flag
2110
+ c2 .engine .ContextWithFallback = true
2111
+
2106
2112
c2 .Request , _ = http .NewRequest (http .MethodGet , "/" , nil )
2107
2113
d := time .Now ().Add (time .Second )
2108
2114
ctx , cancel := context .WithDeadline (context .Background (), d )
@@ -2114,10 +2120,16 @@ func TestContextWithFallbackDeadlineFromRequestContext(t *testing.T) {
2114
2120
}
2115
2121
2116
2122
func TestContextWithFallbackDoneFromRequestContext (t * testing.T ) {
2117
- c := & Context {}
2123
+ c , _ := CreateTestContext (httptest .NewRecorder ())
2124
+ // enable ContextWithFallback feature flag
2125
+ c .engine .ContextWithFallback = true
2126
+
2118
2127
assert .Nil (t , c .Done ())
2119
2128
2120
- c2 := & Context {}
2129
+ c2 , _ := CreateTestContext (httptest .NewRecorder ())
2130
+ // enable ContextWithFallback feature flag
2131
+ c2 .engine .ContextWithFallback = true
2132
+
2121
2133
c2 .Request , _ = http .NewRequest (http .MethodGet , "/" , nil )
2122
2134
ctx , cancel := context .WithCancel (context .Background ())
2123
2135
c2 .Request = c2 .Request .WithContext (ctx )
@@ -2126,10 +2138,16 @@ func TestContextWithFallbackDoneFromRequestContext(t *testing.T) {
2126
2138
}
2127
2139
2128
2140
func TestContextWithFallbackErrFromRequestContext (t * testing.T ) {
2129
- c := & Context {}
2141
+ c , _ := CreateTestContext (httptest .NewRecorder ())
2142
+ // enable ContextWithFallback feature flag
2143
+ c .engine .ContextWithFallback = true
2144
+
2130
2145
assert .Nil (t , c .Err ())
2131
2146
2132
- c2 := & Context {}
2147
+ c2 , _ := CreateTestContext (httptest .NewRecorder ())
2148
+ // enable ContextWithFallback feature flag
2149
+ c2 .engine .ContextWithFallback = true
2150
+
2133
2151
c2 .Request , _ = http .NewRequest (http .MethodGet , "/" , nil )
2134
2152
ctx , cancel := context .WithCancel (context .Background ())
2135
2153
c2 .Request = c2 .Request .WithContext (ctx )
@@ -2138,9 +2156,9 @@ func TestContextWithFallbackErrFromRequestContext(t *testing.T) {
2138
2156
assert .EqualError (t , c2 .Err (), context .Canceled .Error ())
2139
2157
}
2140
2158
2141
- type contextKey string
2142
-
2143
2159
func TestContextWithFallbackValueFromRequestContext (t * testing.T ) {
2160
+ type contextKey string
2161
+
2144
2162
tests := []struct {
2145
2163
name string
2146
2164
getContextAndKey func () (* Context , any )
@@ -2150,7 +2168,9 @@ func TestContextWithFallbackValueFromRequestContext(t *testing.T) {
2150
2168
name : "c with struct context key" ,
2151
2169
getContextAndKey : func () (* Context , any ) {
2152
2170
var key struct {}
2153
- c := & Context {}
2171
+ c , _ := CreateTestContext (httptest .NewRecorder ())
2172
+ // enable ContextWithFallback feature flag
2173
+ c .engine .ContextWithFallback = true
2154
2174
c .Request , _ = http .NewRequest ("POST" , "/" , nil )
2155
2175
c .Request = c .Request .WithContext (context .WithValue (context .TODO (), key , "value" ))
2156
2176
return c , key
@@ -2160,7 +2180,9 @@ func TestContextWithFallbackValueFromRequestContext(t *testing.T) {
2160
2180
{
2161
2181
name : "c with string context key" ,
2162
2182
getContextAndKey : func () (* Context , any ) {
2163
- c := & Context {}
2183
+ c , _ := CreateTestContext (httptest .NewRecorder ())
2184
+ // enable ContextWithFallback feature flag
2185
+ c .engine .ContextWithFallback = true
2164
2186
c .Request , _ = http .NewRequest ("POST" , "/" , nil )
2165
2187
c .Request = c .Request .WithContext (context .WithValue (context .TODO (), contextKey ("key" ), "value" ))
2166
2188
return c , contextKey ("key" )
@@ -2170,15 +2192,20 @@ func TestContextWithFallbackValueFromRequestContext(t *testing.T) {
2170
2192
{
2171
2193
name : "c with nil http.Request" ,
2172
2194
getContextAndKey : func () (* Context , any ) {
2173
- c := & Context {}
2195
+ c , _ := CreateTestContext (httptest .NewRecorder ())
2196
+ // enable ContextWithFallback feature flag
2197
+ c .engine .ContextWithFallback = true
2198
+ c .Request = nil
2174
2199
return c , "key"
2175
2200
},
2176
2201
value : nil ,
2177
2202
},
2178
2203
{
2179
2204
name : "c with nil http.Request.Context()" ,
2180
2205
getContextAndKey : func () (* Context , any ) {
2181
- c := & Context {}
2206
+ c , _ := CreateTestContext (httptest .NewRecorder ())
2207
+ // enable ContextWithFallback feature flag
2208
+ c .engine .ContextWithFallback = true
2182
2209
c .Request , _ = http .NewRequest ("POST" , "/" , nil )
2183
2210
return c , "key"
2184
2211
},
@@ -2193,6 +2220,70 @@ func TestContextWithFallbackValueFromRequestContext(t *testing.T) {
2193
2220
}
2194
2221
}
2195
2222
2223
+ func TestContextCopyShouldNotCancel (t * testing.T ) {
2224
+ srv := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , _ * http.Request ) {
2225
+ w .WriteHeader (http .StatusOK )
2226
+ }))
2227
+ defer srv .Close ()
2228
+
2229
+ ensureRequestIsOver := make (chan struct {})
2230
+
2231
+ wg := & sync.WaitGroup {}
2232
+
2233
+ r := New ()
2234
+ r .GET ("/" , func (ginctx * Context ) {
2235
+ wg .Add (1 )
2236
+
2237
+ ginctx = ginctx .Copy ()
2238
+
2239
+ // start async goroutine for calling srv
2240
+ go func () {
2241
+ defer wg .Done ()
2242
+
2243
+ <- ensureRequestIsOver // ensure request is done
2244
+
2245
+ req , err := http .NewRequestWithContext (ginctx , http .MethodGet , srv .URL , nil )
2246
+ must (err )
2247
+
2248
+ res , err := http .DefaultClient .Do (req )
2249
+ if err != nil {
2250
+ t .Error (fmt .Errorf ("request error: %w" , err ))
2251
+ return
2252
+ }
2253
+
2254
+ if res .StatusCode != http .StatusOK {
2255
+ t .Error (fmt .Errorf ("unexpected status code: %s" , res .Status ))
2256
+ }
2257
+ }()
2258
+ })
2259
+
2260
+ l , err := net .Listen ("tcp" , ":0" )
2261
+ must (err )
2262
+ go func () {
2263
+ s := & http.Server {
2264
+ Handler : r ,
2265
+ }
2266
+
2267
+ must (s .Serve (l ))
2268
+ }()
2269
+
2270
+ addr := strings .Split (l .Addr ().String (), ":" )
2271
+ res , err := http .Get (fmt .Sprintf ("http://127.0.0.1:%s/" , addr [len (addr )- 1 ]))
2272
+ if err != nil {
2273
+ t .Error (fmt .Errorf ("request error: %w" , err ))
2274
+ return
2275
+ }
2276
+
2277
+ close (ensureRequestIsOver )
2278
+
2279
+ if res .StatusCode != http .StatusOK {
2280
+ t .Error (fmt .Errorf ("unexpected status code: %s" , res .Status ))
2281
+ return
2282
+ }
2283
+
2284
+ wg .Wait ()
2285
+ }
2286
+
2196
2287
func TestContextAddParam (t * testing.T ) {
2197
2288
c := & Context {}
2198
2289
id := "id"
0 commit comments