@@ -1164,6 +1164,102 @@ func TestServerContextCanceledOnClosedConnection(t *testing.T) {
1164
1164
server .stop ()
1165
1165
}
1166
1166
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
+
1167
1263
func TestServerConnDecoupledFromApplicationRead (t * testing.T ) {
1168
1264
serverConfig := & ServerConfig {
1169
1265
InitialWindowSize : defaultWindowSize ,
0 commit comments