@@ -807,6 +807,88 @@ fn client_upgrade() {
807807 assert_eq ! ( vec, b"bar=foo" ) ;
808808}
809809
810+ #[ cfg( not( miri) ) ]
811+ #[ test]
812+ fn client_http2_upgrade ( ) {
813+ use http:: { Method , Response , Version } ;
814+ use hyper:: service:: service_fn;
815+ use tokio:: io:: { AsyncReadExt , AsyncWriteExt } ;
816+ use tokio:: net:: TcpListener ;
817+
818+ let _ = pretty_env_logger:: try_init ( ) ;
819+ let rt = runtime ( ) ;
820+ let server = rt
821+ . block_on ( TcpListener :: bind ( SocketAddr :: from ( ( [ 127 , 0 , 0 , 1 ] , 0 ) ) ) )
822+ . unwrap ( ) ;
823+ let addr = server. local_addr ( ) . unwrap ( ) ;
824+ let mut connector = DebugConnector :: new ( ) ;
825+ connector. alpn_h2 = true ;
826+
827+ let client = Client :: builder ( TokioExecutor :: new ( ) ) . build ( connector) ;
828+
829+ rt. spawn ( async move {
830+ let ( stream, _) = server. accept ( ) . await . expect ( "accept" ) ;
831+ let stream = TokioIo :: new ( stream) ;
832+ let mut builder = hyper_util:: server:: conn:: auto:: Builder :: new ( TokioExecutor :: new ( ) ) ;
833+ // IMPORTANT: This is required to advertise our support for HTTP/2 websockets to the client.
834+ builder. http2 ( ) . enable_connect_protocol ( ) ;
835+ let _ = builder
836+ . serve_connection_with_upgrades (
837+ stream,
838+ service_fn ( |req| async move {
839+ assert_eq ! ( req. headers( ) . get( "host" ) , None ) ;
840+ assert_eq ! ( req. version( ) , Version :: HTTP_2 ) ;
841+ assert_eq ! (
842+ req. headers( ) . get( http:: header:: SEC_WEBSOCKET_VERSION ) ,
843+ Some ( & http:: header:: HeaderValue :: from_static( "13" ) )
844+ ) ;
845+ assert_eq ! (
846+ req. extensions( ) . get:: <hyper:: ext:: Protocol >( ) ,
847+ Some ( & hyper:: ext:: Protocol :: from_static( "websocket" ) )
848+ ) ;
849+
850+ let on_upgrade = hyper:: upgrade:: on ( req) ;
851+ tokio:: spawn ( async move {
852+ let upgraded = on_upgrade. await . unwrap ( ) ;
853+ let mut io = TokioIo :: new ( upgraded) ;
854+
855+ let mut vec = vec ! [ ] ;
856+ io. read_buf ( & mut vec) . await . unwrap ( ) ;
857+ assert_eq ! ( vec, b"foo=bar" ) ;
858+ io. write_all ( b"bar=foo" ) . await . unwrap ( ) ;
859+ } ) ;
860+
861+ Ok :: < _ , hyper:: Error > ( Response :: new ( Empty :: < Bytes > :: new ( ) ) )
862+ } ) ,
863+ )
864+ . await
865+ . expect ( "server" ) ;
866+ } ) ;
867+
868+ let req = Request :: builder ( )
869+ . method ( Method :: CONNECT )
870+ . uri ( & * format ! ( "http://{}/up" , addr) )
871+ . header ( http:: header:: SEC_WEBSOCKET_VERSION , "13" )
872+ . version ( Version :: HTTP_2 )
873+ . extension ( hyper:: ext:: Protocol :: from_static ( "websocket" ) )
874+ . body ( Empty :: < Bytes > :: new ( ) )
875+ . unwrap ( ) ;
876+
877+ let res = client. request ( req) ;
878+ let res = rt. block_on ( res) . unwrap ( ) ;
879+
880+ assert_eq ! ( res. status( ) , http:: StatusCode :: OK ) ;
881+ assert_eq ! ( res. version( ) , Version :: HTTP_2 ) ;
882+
883+ let upgraded = rt. block_on ( hyper:: upgrade:: on ( res) ) . expect ( "on_upgrade" ) ;
884+ let mut io = TokioIo :: new ( upgraded) ;
885+
886+ rt. block_on ( io. write_all ( b"foo=bar" ) ) . unwrap ( ) ;
887+ let mut vec = vec ! [ ] ;
888+ rt. block_on ( io. read_to_end ( & mut vec) ) . unwrap ( ) ;
889+ assert_eq ! ( vec, b"bar=foo" ) ;
890+ }
891+
810892#[ cfg( not( miri) ) ]
811893#[ test]
812894fn alpn_h2 ( ) {
0 commit comments