@@ -807,6 +807,88 @@ fn client_upgrade() {
807
807
assert_eq ! ( vec, b"bar=foo" ) ;
808
808
}
809
809
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
+
810
892
#[ cfg( not( miri) ) ]
811
893
#[ test]
812
894
fn alpn_h2 ( ) {
0 commit comments