| 3251 | } |
| 3252 | |
| 3253 | func TestContextCopyShouldNotCancel(t *testing.T) { |
| 3254 | srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { |
| 3255 | w.WriteHeader(http.StatusOK) |
| 3256 | })) |
| 3257 | defer srv.Close() |
| 3258 | |
| 3259 | ensureRequestIsOver := make(chan struct{}) |
| 3260 | |
| 3261 | wg := &sync.WaitGroup{} |
| 3262 | |
| 3263 | r := New() |
| 3264 | r.GET("/", func(ginctx *Context) { |
| 3265 | wg.Add(1) |
| 3266 | |
| 3267 | ginctx = ginctx.Copy() |
| 3268 | |
| 3269 | // start async goroutine for calling srv |
| 3270 | go func() { |
| 3271 | defer wg.Done() |
| 3272 | |
| 3273 | <-ensureRequestIsOver // ensure request is done |
| 3274 | |
| 3275 | req, err := http.NewRequestWithContext(ginctx, http.MethodGet, srv.URL, nil) |
| 3276 | must(err) |
| 3277 | |
| 3278 | res, err := http.DefaultClient.Do(req) |
| 3279 | if err != nil { |
| 3280 | t.Error(fmt.Errorf("request error: %w", err)) |
| 3281 | return |
| 3282 | } |
| 3283 | |
| 3284 | if res.StatusCode != http.StatusOK { |
| 3285 | t.Error(fmt.Errorf("unexpected status code: %s", res.Status)) |
| 3286 | } |
| 3287 | }() |
| 3288 | }) |
| 3289 | |
| 3290 | l, err := net.Listen("tcp", ":0") |
| 3291 | must(err) |
| 3292 | go func() { |
| 3293 | s := &http.Server{ |
| 3294 | Handler: r, |
| 3295 | } |
| 3296 | |
| 3297 | must(s.Serve(l)) |
| 3298 | }() |
| 3299 | |
| 3300 | addr := strings.Split(l.Addr().String(), ":") |
| 3301 | res, err := http.Get(fmt.Sprintf("http://%s:%s/", localhostIP, addr[len(addr)-1])) |
| 3302 | if err != nil { |
| 3303 | t.Error(fmt.Errorf("request error: %w", err)) |
| 3304 | return |
| 3305 | } |
| 3306 | |
| 3307 | close(ensureRequestIsOver) |
| 3308 | |
| 3309 | if res.StatusCode != http.StatusOK { |
| 3310 | t.Error(fmt.Errorf("unexpected status code: %s", res.Status)) |