@@ -1256,6 +1256,67 @@ async fn disable_keep_alive_post_request() {
1256
1256
child. join ( ) . unwrap ( ) ;
1257
1257
}
1258
1258
1259
+ #[ tokio:: test]
1260
+ async fn http1_graceful_shutdown_after_upgrade ( ) {
1261
+ let ( listener, addr) = setup_tcp_listener ( ) ;
1262
+ let ( read_101_tx, read_101_rx) = oneshot:: channel ( ) ;
1263
+
1264
+ thread:: spawn ( move || {
1265
+ let mut tcp = connect ( & addr) ;
1266
+ tcp. write_all (
1267
+ b"\
1268
+ GET / HTTP/1.1\r \n \
1269
+ Upgrade: foobar\r \n \
1270
+ Connection: upgrade\r \n \
1271
+ \r \n \
1272
+ eagerly optimistic\
1273
+ ",
1274
+ )
1275
+ . expect ( "write 1" ) ;
1276
+ let mut buf = [ 0 ; 256 ] ;
1277
+ tcp. read ( & mut buf) . expect ( "read 1" ) ;
1278
+
1279
+ let response = s ( & buf) ;
1280
+ assert ! ( response. starts_with( "HTTP/1.1 101 Switching Protocols\r \n " ) ) ;
1281
+ assert ! ( !has_header( & response, "content-length" ) ) ;
1282
+ let _ = read_101_tx. send ( ( ) ) ;
1283
+ } ) ;
1284
+
1285
+ let ( upgrades_tx, upgrades_rx) = mpsc:: channel ( ) ;
1286
+ let svc = service_fn ( move |req : Request < IncomingBody > | {
1287
+ let on_upgrade = hyper:: upgrade:: on ( req) ;
1288
+ let _ = upgrades_tx. send ( on_upgrade) ;
1289
+ future:: ok :: < _ , hyper:: Error > (
1290
+ Response :: builder ( )
1291
+ . status ( 101 )
1292
+ . header ( "upgrade" , "foobar" )
1293
+ . body ( Empty :: < Bytes > :: new ( ) )
1294
+ . unwrap ( ) ,
1295
+ )
1296
+ } ) ;
1297
+
1298
+ let ( socket, _) = listener. accept ( ) . await . unwrap ( ) ;
1299
+ let socket = TokioIo :: new ( socket) ;
1300
+
1301
+ let mut conn = http1:: Builder :: new ( )
1302
+ . serve_connection ( socket, svc)
1303
+ . with_upgrades ( ) ;
1304
+ ( & mut conn) . await . unwrap ( ) ;
1305
+
1306
+ let on_upgrade = upgrades_rx. recv ( ) . unwrap ( ) ;
1307
+
1308
+ // wait so that we don't write until other side saw 101 response
1309
+ read_101_rx. await . unwrap ( ) ;
1310
+
1311
+ let upgraded = on_upgrade. await . expect ( "on_upgrade" ) ;
1312
+ let parts = upgraded. downcast :: < TokioIo < TkTcpStream > > ( ) . unwrap ( ) ;
1313
+ assert_eq ! ( parts. read_buf, "eagerly optimistic" ) ;
1314
+
1315
+ pin ! ( conn) ;
1316
+ // graceful shutdown doesn't cause issues or panic. It should be ignored after upgrade
1317
+ conn. as_mut ( ) . graceful_shutdown ( ) ;
1318
+ }
1319
+
1259
1320
#[ tokio:: test]
1260
1321
async fn empty_parse_eof_does_not_return_error ( ) {
1261
1322
let ( listener, addr) = setup_tcp_listener ( ) ;
0 commit comments