@@ -1164,6 +1164,102 @@ func TestServerContextCanceledOnClosedConnection(t *testing.T) {
11641164server .stop ()
11651165}
11661166
1167+ func TestClientConnDecoupledFromApplicationRead (t * testing.T ) {
1168+ connectOptions := ConnectOptions {
1169+ InitialWindowSize : defaultWindowSize ,
1170+ InitialConnWindowSize : defaultWindowSize ,
1171+ }
1172+ server , client := setUpWithOptions (t , 0 , & ServerConfig {}, suspended , connectOptions )
1173+ defer server .stop ()
1174+ defer client .Close ()
1175+
1176+ waitWhileTrue (t , func () (bool , error ) {
1177+ server .mu .Lock ()
1178+ defer server .mu .Unlock ()
1179+
1180+ if len (server .conns ) == 0 {
1181+ return true , fmt .Errorf ("timed-out while waiting for connection to be created on the server" )
1182+ }
1183+ return false , nil
1184+ })
1185+
1186+ var st * http2Server
1187+ server .mu .Lock ()
1188+ for k := range server .conns {
1189+ st = k .(* http2Server )
1190+ }
1191+ server .mu .Unlock ()
1192+ cstream1 , err := client .NewStream (context .Background (), & CallHdr {Flush : true })
1193+ if err != nil {
1194+ t .Fatalf ("Client failed to create first stream. Err: %v" , err )
1195+ }
1196+
1197+ var sstream1 * Stream
1198+ // Access stream on the server.
1199+ waitWhileTrue (t , func () (bool , error ) {
1200+ st .mu .Lock ()
1201+ defer st .mu .Unlock ()
1202+
1203+ if len (st .activeStreams ) != 1 {
1204+ return true , fmt .Errorf ("timed-out while waiting for server to have created a stream" )
1205+ }
1206+ for _ , v := range st .activeStreams {
1207+ sstream1 = v
1208+ }
1209+ return false , nil
1210+ })
1211+
1212+ // Exhaust client's conneciton window.
1213+ <- st .writableChan
1214+ if err := st .framer .writeData (true , sstream1 .id , true , make ([]byte , defaultWindowSize )); err != nil {
1215+ st .writableChan <- 0
1216+ t .Fatalf ("Server failed to write data. Err: %v" , err )
1217+ }
1218+ st .writableChan <- 0
1219+ // Create another stream on client.
1220+ cstream2 , err := client .NewStream (context .Background (), & CallHdr {Flush : true })
1221+ if err != nil {
1222+ t .Fatalf ("Client failed to create second stream. Err: %v" , err )
1223+ }
1224+
1225+ var sstream2 * Stream
1226+ waitWhileTrue (t , func () (bool , error ) {
1227+ st .mu .Lock ()
1228+ defer st .mu .Unlock ()
1229+
1230+ if len (st .activeStreams ) != 2 {
1231+ return true , fmt .Errorf ("timed-out while waiting for server to have created the second stream" )
1232+ }
1233+ for _ , v := range st .activeStreams {
1234+ if v .id == cstream2 .id {
1235+ sstream2 = v
1236+ }
1237+ }
1238+ if sstream2 == nil {
1239+ return true , fmt .Errorf ("didn't find stream corresponding to client cstream.id: %v on the server" , cstream2 .id )
1240+ }
1241+ return false , nil
1242+ })
1243+
1244+ // Server should be able to send data on the new stream, even though the client hasn't read anything on the first stream.
1245+ <- st .writableChan
1246+ if err := st .framer .writeData (true , sstream2 .id , true , make ([]byte , defaultWindowSize )); err != nil {
1247+ st .writableChan <- 0
1248+ t .Fatalf ("Server failed to write data. Err: %v" , err )
1249+ }
1250+ st .writableChan <- 0
1251+
1252+ // Client should be able to read data on second stream.
1253+ if _ , err := cstream2 .Read (make ([]byte , defaultWindowSize )); err != nil {
1254+ t .Fatalf ("_.Read(_) = _, %v, want _, <nil>" , err )
1255+ }
1256+
1257+ // Client should be able to read data on first stream.
1258+ if _ , err := cstream1 .Read (make ([]byte , defaultWindowSize )); err != nil {
1259+ t .Fatalf ("_.Read(_) = _, %v, want _, <nil>" , err )
1260+ }
1261+ }
1262+
11671263func TestServerConnDecoupledFromApplicationRead (t * testing.T ) {
11681264serverConfig := & ServerConfig {
11691265InitialWindowSize : defaultWindowSize ,
0 commit comments