@@ -642,6 +642,131 @@ func TestHTTP2WriteDeadlineExtendedOnNewRequest(t *testing.T) {
642
642
}
643
643
}
644
644
645
+ // tryTimeouts runs testFunc with increasing timeouts. Test passes on first success,
646
+ // and fails if all timeouts fail.
647
+ func tryTimeouts (t * testing.T , testFunc func (timeout time.Duration ) error ) {
648
+ tries := []time.Duration {250 * time .Millisecond , 500 * time .Millisecond , 1 * time .Second }
649
+ for i , timeout := range tries {
650
+ err := testFunc (timeout )
651
+ if err == nil {
652
+ return
653
+ }
654
+ t .Logf ("failed at %v: %v" , timeout , err )
655
+ if i != len (tries )- 1 {
656
+ t .Logf ("retrying at %v ..." , tries [i + 1 ])
657
+ }
658
+ }
659
+ t .Fatal ("all attempts failed" )
660
+ }
661
+
662
+ // Test that the HTTP/2 server RSTs stream on slow write.
663
+ func TestHTTP2WriteDeadlineEnforcedPerStream (t * testing.T ) {
664
+ t .Skip ("disabled until Issue 18437 is fixed" )
665
+ if testing .Short () {
666
+ t .Skip ("skipping in short mode" )
667
+ }
668
+ setParallel (t )
669
+ defer afterTest (t )
670
+ tryTimeouts (t , testHTTP2WriteDeadlineEnforcedPerStream )
671
+ }
672
+
673
+ func testHTTP2WriteDeadlineEnforcedPerStream (timeout time.Duration ) error {
674
+ reqNum := 0
675
+ ts := httptest .NewUnstartedServer (HandlerFunc (func (res ResponseWriter , req * Request ) {
676
+ reqNum ++
677
+ if reqNum == 1 {
678
+ return // first request succeeds
679
+ }
680
+ time .Sleep (timeout ) // second request times out
681
+ }))
682
+ ts .Config .WriteTimeout = timeout / 2
683
+ ts .TLS = & tls.Config {NextProtos : []string {"h2" }}
684
+ ts .StartTLS ()
685
+ defer ts .Close ()
686
+
687
+ c := ts .Client ()
688
+ if err := ExportHttp2ConfigureTransport (c .Transport .(* Transport )); err != nil {
689
+ return fmt .Errorf ("ExportHttp2ConfigureTransport: %v" , err )
690
+ }
691
+
692
+ req , err := NewRequest ("GET" , ts .URL , nil )
693
+ if err != nil {
694
+ return fmt .Errorf ("NewRequest: %v" , err )
695
+ }
696
+ r , err := c .Do (req )
697
+ if err != nil {
698
+ return fmt .Errorf ("http2 Get #1: %v" , err )
699
+ }
700
+ r .Body .Close ()
701
+ if r .ProtoMajor != 2 {
702
+ return fmt .Errorf ("http2 Get expected HTTP/2.0, got %q" , r .Proto )
703
+ }
704
+
705
+ req , err = NewRequest ("GET" , ts .URL , nil )
706
+ if err != nil {
707
+ return fmt .Errorf ("NewRequest: %v" , err )
708
+ }
709
+ r , err = c .Do (req )
710
+ if err == nil {
711
+ r .Body .Close ()
712
+ if r .ProtoMajor != 2 {
713
+ return fmt .Errorf ("http2 Get expected HTTP/2.0, got %q" , r .Proto )
714
+ }
715
+ return fmt .Errorf ("http2 Get #2 expected error, got nil" )
716
+ }
717
+ expected := "stream ID 3; INTERNAL_ERROR" // client IDs are odd, second stream should be 3
718
+ if ! strings .Contains (err .Error (), expected ) {
719
+ return fmt .Errorf ("http2 Get #2: expected error to contain %q, got %q" , expected , err )
720
+ }
721
+ return nil
722
+ }
723
+
724
+ // Test that the HTTP/2 server does not send RST when WriteDeadline not set.
725
+ func TestHTTP2NoWriteDeadline (t * testing.T ) {
726
+ t .Skip ("disabled until Issue 18437 is fixed" )
727
+ if testing .Short () {
728
+ t .Skip ("skipping in short mode" )
729
+ }
730
+ setParallel (t )
731
+ defer afterTest (t )
732
+ tryTimeouts (t , testHTTP2NoWriteDeadline )
733
+ }
734
+
735
+ func testHTTP2NoWriteDeadline (timeout time.Duration ) error {
736
+ reqNum := 0
737
+ ts := httptest .NewUnstartedServer (HandlerFunc (func (res ResponseWriter , req * Request ) {
738
+ reqNum ++
739
+ if reqNum == 1 {
740
+ return // first request succeeds
741
+ }
742
+ time .Sleep (timeout ) // second request timesout
743
+ }))
744
+ ts .TLS = & tls.Config {NextProtos : []string {"h2" }}
745
+ ts .StartTLS ()
746
+ defer ts .Close ()
747
+
748
+ c := ts .Client ()
749
+ if err := ExportHttp2ConfigureTransport (c .Transport .(* Transport )); err != nil {
750
+ return fmt .Errorf ("ExportHttp2ConfigureTransport: %v" , err )
751
+ }
752
+
753
+ for i := 0 ; i < 2 ; i ++ {
754
+ req , err := NewRequest ("GET" , ts .URL , nil )
755
+ if err != nil {
756
+ return fmt .Errorf ("NewRequest: %v" , err )
757
+ }
758
+ r , err := c .Do (req )
759
+ if err != nil {
760
+ return fmt .Errorf ("http2 Get #%d: %v" , i , err )
761
+ }
762
+ r .Body .Close ()
763
+ if r .ProtoMajor != 2 {
764
+ return fmt .Errorf ("http2 Get expected HTTP/2.0, got %q" , r .Proto )
765
+ }
766
+ }
767
+ return nil
768
+ }
769
+
645
770
// golang.org/issue/4741 -- setting only a write timeout that triggers
646
771
// shouldn't cause a handler to block forever on reads (next HTTP
647
772
// request) that will never happen.
0 commit comments