@@ -244,6 +244,50 @@ func TestServer_Push_Success(t *testing.T) {
244
244
}
245
245
}
246
246
247
+ func TestServer_Push_SuccessNoRace (t * testing.T ) {
248
+ // Regression test for issue #18326. Ensure the request handler can mutate
249
+ // pushed request headers without racing with the PUSH_PROMISE write.
250
+ errc := make (chan error , 2 )
251
+ st := newServerTester (t , func (w http.ResponseWriter , r * http.Request ) {
252
+ switch r .URL .RequestURI () {
253
+ case "/" :
254
+ opt := & http.PushOptions {
255
+ Header : http.Header {"User-Agent" : {"testagent" }},
256
+ }
257
+ if err := w .(http.Pusher ).Push ("/pushed" , opt ); err != nil {
258
+ errc <- fmt .Errorf ("error pushing: %v" , err )
259
+ return
260
+ }
261
+ w .WriteHeader (200 )
262
+ errc <- nil
263
+
264
+ case "/pushed" :
265
+ // Update request header, ensure there is no race.
266
+ r .Header .Set ("User-Agent" , "newagent" )
267
+ r .Header .Set ("Cookie" , "cookie" )
268
+ w .WriteHeader (200 )
269
+ errc <- nil
270
+
271
+ default :
272
+ errc <- fmt .Errorf ("unknown RequestURL %q" , r .URL .RequestURI ())
273
+ }
274
+ })
275
+
276
+ // Send one request, which should push one response.
277
+ st .greet ()
278
+ getSlash (st )
279
+ for k := 0 ; k < 2 ; k ++ {
280
+ select {
281
+ case <- time .After (2 * time .Second ):
282
+ t .Errorf ("timeout waiting for handler %d to finish" , k )
283
+ case err := <- errc :
284
+ if err != nil {
285
+ t .Fatal (err )
286
+ }
287
+ }
288
+ }
289
+ }
290
+
247
291
func TestServer_Push_RejectRecursivePush (t * testing.T ) {
248
292
// Expect two requests, but might get three if there's a bug and the second push succeeds.
249
293
errc := make (chan error , 3 )
0 commit comments