@@ -3998,6 +3998,64 @@ func TestTransportResponseDataBeforeHeaders(t *testing.T) {
3998
3998
ct .run ()
3999
3999
}
4000
4000
4001
+ // Test that the server received values are in range.
4002
+ func TestTransportMaxFrameReadSize (t * testing.T ) {
4003
+ st := newServerTester (t , func (w http.ResponseWriter , r * http.Request ) {
4004
+ }, func (s * Server ) {
4005
+ s .MaxConcurrentStreams = 1
4006
+ })
4007
+ defer st .Close ()
4008
+ tr := & Transport {
4009
+ TLSClientConfig : tlsConfigInsecure ,
4010
+ MaxReadFrameSize : 64000 ,
4011
+ }
4012
+ defer tr .CloseIdleConnections ()
4013
+
4014
+ req , err := http .NewRequest ("GET" , st .ts .URL , nil )
4015
+ if err != nil {
4016
+ t .Fatal (err )
4017
+ }
4018
+ res , err := tr .RoundTrip (req )
4019
+ if err != nil {
4020
+ t .Fatal (err )
4021
+ }
4022
+ if got , want := res .StatusCode , 200 ; got != want {
4023
+ t .Errorf ("StatusCode = %v; want %v" , got , want )
4024
+ }
4025
+ if res != nil && res .Body != nil {
4026
+ res .Body .Close ()
4027
+ }
4028
+ // Test that maxFrameReadSize() matches the requested size.
4029
+ if got , want := tr .maxFrameReadSize (), uint32 (64000 ); got != want {
4030
+ t .Errorf ("maxFrameReadSize = %v; want %v" , got , want )
4031
+ }
4032
+ // Test that server receives the requested size.
4033
+ if got , want := st .sc .maxFrameSize , int32 (64000 ); got != want {
4034
+ t .Errorf ("maxFrameReadSize = %v; want %v" , got , want )
4035
+ }
4036
+
4037
+ // test for minimum frame read size
4038
+ tr = & Transport {
4039
+ TLSClientConfig : tlsConfigInsecure ,
4040
+ MaxReadFrameSize : 1024 ,
4041
+ }
4042
+
4043
+ if got , want := tr .maxFrameReadSize (), uint32 (minMaxFrameSize ); got != want {
4044
+ t .Errorf ("maxFrameReadSize = %v; want %v" , got , want )
4045
+ }
4046
+
4047
+ // test for maximum frame size
4048
+ tr = & Transport {
4049
+ TLSClientConfig : tlsConfigInsecure ,
4050
+ MaxReadFrameSize : 1024 * 1024 * 16 ,
4051
+ }
4052
+
4053
+ if got , want := tr .maxFrameReadSize (), uint32 (maxFrameSize ); got != want {
4054
+ t .Errorf ("maxFrameReadSize = %v; want %v" , got , want )
4055
+ }
4056
+
4057
+ }
4058
+
4001
4059
func TestTransportRequestsLowServerLimit (t * testing.T ) {
4002
4060
st := newServerTester (t , func (w http.ResponseWriter , r * http.Request ) {
4003
4061
}, optOnlyServer , func (s * Server ) {
@@ -4608,6 +4666,61 @@ func BenchmarkClientResponseHeaders(b *testing.B) {
4608
4666
b .Run ("1000 Headers" , func (b * testing.B ) { benchSimpleRoundTrip (b , 0 , 1000 ) })
4609
4667
}
4610
4668
4669
+ func BenchmarkDownloadFrameSize (b * testing.B ) {
4670
+ b .Run (" 16k Frame" , func (b * testing.B ) { benchLargeDownloadRoundTrip (b , 16 * 1024 ) })
4671
+ b .Run (" 64k Frame" , func (b * testing.B ) { benchLargeDownloadRoundTrip (b , 64 * 1024 ) })
4672
+ b .Run ("128k Frame" , func (b * testing.B ) { benchLargeDownloadRoundTrip (b , 128 * 1024 ) })
4673
+ b .Run ("256k Frame" , func (b * testing.B ) { benchLargeDownloadRoundTrip (b , 256 * 1024 ) })
4674
+ b .Run ("512k Frame" , func (b * testing.B ) { benchLargeDownloadRoundTrip (b , 512 * 1024 ) })
4675
+ }
4676
+ func benchLargeDownloadRoundTrip (b * testing.B , frameSize uint32 ) {
4677
+ defer disableGoroutineTracking ()()
4678
+ const transferSize = 1024 * 1024 * 1024 // must be multiple of 1M
4679
+ b .ReportAllocs ()
4680
+ st := newServerTester (b ,
4681
+ func (w http.ResponseWriter , r * http.Request ) {
4682
+ // test 1GB transfer
4683
+ w .Header ().Set ("Content-Length" , strconv .Itoa (transferSize ))
4684
+ w .Header ().Set ("Content-Transfer-Encoding" , "binary" )
4685
+ var data [1024 * 1024 ]byte
4686
+ for i := 0 ; i < transferSize / (1024 * 1024 ); i ++ {
4687
+ w .Write (data [:])
4688
+ }
4689
+ }, optQuiet ,
4690
+ )
4691
+ defer st .Close ()
4692
+
4693
+ tr := & Transport {TLSClientConfig : tlsConfigInsecure , MaxReadFrameSize : frameSize }
4694
+ defer tr .CloseIdleConnections ()
4695
+
4696
+ req , err := http .NewRequest ("GET" , st .ts .URL , nil )
4697
+ if err != nil {
4698
+ b .Fatal (err )
4699
+ }
4700
+
4701
+ b .N = 3
4702
+ b .SetBytes (transferSize )
4703
+ b .ResetTimer ()
4704
+
4705
+ for i := 0 ; i < b .N ; i ++ {
4706
+ res , err := tr .RoundTrip (req )
4707
+ if err != nil {
4708
+ if res != nil {
4709
+ res .Body .Close ()
4710
+ }
4711
+ b .Fatalf ("RoundTrip err = %v; want nil" , err )
4712
+ }
4713
+ data , _ := io .ReadAll (res .Body )
4714
+ if len (data ) != transferSize {
4715
+ b .Fatalf ("Response length invalid" )
4716
+ }
4717
+ res .Body .Close ()
4718
+ if res .StatusCode != http .StatusOK {
4719
+ b .Fatalf ("Response code = %v; want %v" , res .StatusCode , http .StatusOK )
4720
+ }
4721
+ }
4722
+ }
4723
+
4611
4724
func activeStreams (cc * ClientConn ) int {
4612
4725
count := 0
4613
4726
cc .mu .Lock ()
0 commit comments