@@ -13,9 +13,10 @@ use http::{HeaderMap, Method, Request, Response, StatusCode};
1313use http_body_util:: { BodyExt , Full } ;
1414use hyper:: body:: Incoming ;
1515use hyper:: client:: conn:: http1 as client_http1;
16+ use hyper:: client:: conn:: http2 as client_http2;
1617use hyper:: server:: conn:: http1;
1718use hyper:: service:: service_fn;
18- use hyper_util:: rt:: TokioIo ;
19+ use hyper_util:: rt:: { TokioExecutor , TokioIo } ;
1920use reqwest:: Client ;
2021use rustls:: SignatureScheme ;
2122use rustls:: client:: { EchConfig , EchMode } ;
@@ -392,6 +393,10 @@ async fn send_once(
392393 }
393394
394395 let tls_stream = connect_tls ( request_host, outer_sni, ech_config, addr) . await ?;
396+ let negotiated_h2 = tls_stream. get_ref ( ) . 1 . alpn_protocol ( ) == Some ( b"h2" ) ;
397+ if negotiated_h2 {
398+ return send_over_io_http2 ( TokioIo :: new ( tls_stream) , request) . await ;
399+ }
395400 send_over_io ( TokioIo :: new ( tls_stream) , request) . await
396401}
397402
@@ -410,8 +415,7 @@ fn build_upstream_request(
410415 builder = builder. header ( name, value) ;
411416 }
412417 builder = builder
413- . header ( HOST , request_host)
414- . header ( "x-linuxdo-accelerator" , "1" ) ;
418+ . header ( HOST , request_host) ;
415419 builder
416420 . body ( Full :: new ( body) )
417421 . context ( "failed to build upstream request" )
@@ -436,6 +440,26 @@ where
436440 . context ( "failed to contact upstream" )
437441}
438442
443+ async fn send_over_io_http2 < T > (
444+ io : TokioIo < T > ,
445+ request : Request < Full < Bytes > > ,
446+ ) -> Result < Response < Incoming > >
447+ where
448+ T : tokio:: io:: AsyncRead + tokio:: io:: AsyncWrite + Unpin + Send + ' static ,
449+ {
450+ let ( mut sender, connection) = client_http2:: Builder :: new ( TokioExecutor :: new ( ) )
451+ . handshake ( io)
452+ . await
453+ . context ( "failed to initialize upstream HTTP/2 client" ) ?;
454+ tokio:: spawn ( async move {
455+ let _ = connection. await ;
456+ } ) ;
457+ sender
458+ . send_request ( request)
459+ . await
460+ . context ( "failed to contact upstream" )
461+ }
462+
439463async fn connect_tls (
440464 request_host : & str ,
441465 outer_sni : Option < & str > ,
@@ -460,7 +484,7 @@ async fn connect_tls(
460484 . with_custom_certificate_verifier ( Arc :: new ( NoCertificateVerification ) )
461485 . with_no_client_auth ( )
462486 } ;
463- tls_config. alpn_protocols = vec ! [ b"http/1.1" . to_vec( ) ] ;
487+ tls_config. alpn_protocols = vec ! [ b"h2" . to_vec ( ) , b" http/1.1". to_vec( ) ] ;
464488
465489 let server_name = ServerName :: try_from ( outer_sni. unwrap_or ( request_host) . to_string ( ) )
466490 . context ( "failed to construct upstream SNI name" ) ?;
0 commit comments