@@ -70,6 +70,7 @@ use std::io;
70
70
use std:: pin:: Pin ;
71
71
use std:: ptr:: null;
72
72
use std:: rc:: Rc ;
73
+ use std:: time:: Duration ;
73
74
74
75
use super :: fly_accept_encoding;
75
76
use fly_accept_encoding:: Encoding ;
@@ -165,6 +166,25 @@ pub enum HttpNextError {
165
166
UpgradeUnavailable ( #[ from] crate :: service:: UpgradeUnavailableError ) ,
166
167
}
167
168
169
+ /// A set of configuration parameters for HTTP/2.
170
+ /// If a field is `None`, the default value from the hyper crate will be used.
171
+ /// The default values may change in future versions.
172
+ #[ derive( Default , Clone , Copy ) ]
173
+ pub struct Http2Config {
174
+ pub max_pending_accept_reset_streams : Option < usize > ,
175
+ pub max_local_error_reset_streams : Option < usize > ,
176
+ pub initial_stream_window_size : Option < u32 > ,
177
+ pub initial_connection_window_size : Option < u32 > ,
178
+ pub adaptive_window : Option < bool > ,
179
+ pub max_frame_size : Option < u32 > ,
180
+ pub max_concurrent_streams : Option < u32 > ,
181
+ pub keep_alive_interval : Option < Duration > ,
182
+ pub keep_alive_timeout : Option < Duration > ,
183
+ pub max_send_buf_size : Option < usize > ,
184
+ pub max_header_list_size : Option < u32 > ,
185
+ pub auto_date_header : Option < bool > ,
186
+ }
187
+
168
188
#[ op2( fast) ]
169
189
#[ smi]
170
190
pub fn op_http_upgrade_raw (
@@ -829,9 +849,48 @@ fn serve_http2_unconditional(
829
849
io : impl HttpServeStream ,
830
850
svc : impl HttpService < Incoming , ResBody = HttpRecordResponse > + ' static ,
831
851
cancel : Rc < CancelHandle > ,
852
+ h2_config : Http2Config ,
832
853
) -> impl Future < Output = Result < ( ) , hyper:: Error > > + ' static {
833
- let conn =
834
- http2:: Builder :: new ( LocalExecutor ) . serve_connection ( TokioIo :: new ( io) , svc) ;
854
+ let mut builder = http2:: Builder :: new ( LocalExecutor ) ;
855
+
856
+ if let Some ( v) = h2_config. max_pending_accept_reset_streams {
857
+ builder. max_pending_accept_reset_streams ( v) ;
858
+ }
859
+ if let Some ( v) = h2_config. max_local_error_reset_streams {
860
+ builder = builder. max_local_error_reset_streams ( v) ;
861
+ }
862
+ if let Some ( v) = h2_config. initial_stream_window_size {
863
+ builder. initial_stream_window_size ( v) ;
864
+ }
865
+ if let Some ( v) = h2_config. initial_connection_window_size {
866
+ builder. initial_connection_window_size ( v) ;
867
+ }
868
+ if let Some ( v) = h2_config. adaptive_window {
869
+ builder. adaptive_window ( v) ;
870
+ }
871
+ if let Some ( v) = h2_config. max_frame_size {
872
+ builder. max_frame_size ( v) ;
873
+ }
874
+ if let Some ( v) = h2_config. max_concurrent_streams {
875
+ builder. max_concurrent_streams ( v) ;
876
+ }
877
+ if let Some ( v) = h2_config. keep_alive_interval {
878
+ builder. keep_alive_interval ( v) ;
879
+ }
880
+ if let Some ( v) = h2_config. keep_alive_timeout {
881
+ builder. keep_alive_timeout ( v) ;
882
+ }
883
+ if let Some ( v) = h2_config. max_send_buf_size {
884
+ builder. max_send_buf_size ( v) ;
885
+ }
886
+ if let Some ( v) = h2_config. max_header_list_size {
887
+ builder. max_header_list_size ( v) ;
888
+ }
889
+ if let Some ( v) = h2_config. auto_date_header {
890
+ builder. auto_date_header ( v) ;
891
+ }
892
+
893
+ let conn = builder. serve_connection ( TokioIo :: new ( io) , svc) ;
835
894
async {
836
895
match conn. or_abort ( cancel) . await {
837
896
Err ( mut conn) => {
@@ -847,11 +906,12 @@ async fn serve_http2_autodetect(
847
906
io : impl HttpServeStream ,
848
907
svc : impl HttpService < Incoming , ResBody = HttpRecordResponse > + ' static ,
849
908
cancel : Rc < CancelHandle > ,
909
+ h2_config : Http2Config ,
850
910
) -> Result < ( ) , HttpNextError > {
851
911
let prefix = NetworkStreamPrefixCheck :: new ( io, HTTP2_PREFIX ) ;
852
912
let ( matches, io) = prefix. match_prefix ( ) . await ?;
853
913
if matches {
854
- serve_http2_unconditional ( io, svc, cancel)
914
+ serve_http2_unconditional ( io, svc, cancel, h2_config )
855
915
. await
856
916
. map_err ( HttpNextError :: Hyper )
857
917
} else {
@@ -866,6 +926,7 @@ fn serve_https(
866
926
request_info : HttpConnectionProperties ,
867
927
lifetime : HttpLifetime ,
868
928
tx : tokio:: sync:: mpsc:: Sender < Rc < HttpRecord > > ,
929
+ h2_config : Http2Config ,
869
930
) -> JoinHandle < Result < ( ) , HttpNextError > > {
870
931
let HttpLifetime {
871
932
server_state,
@@ -877,21 +938,21 @@ fn serve_https(
877
938
handle_request ( req, request_info. clone ( ) , server_state. clone ( ) , tx. clone ( ) )
878
939
} ) ;
879
940
spawn (
880
- async {
941
+ async move {
881
942
let handshake = io. handshake ( ) . await ?;
882
943
// If the client specifically negotiates a protocol, we will use it. If not, we'll auto-detect
883
944
// based on the prefix bytes
884
945
let handshake = handshake. alpn ;
885
946
if Some ( TLS_ALPN_HTTP_2 ) == handshake. as_deref ( ) {
886
- serve_http2_unconditional ( io, svc, listen_cancel_handle)
947
+ serve_http2_unconditional ( io, svc, listen_cancel_handle, h2_config )
887
948
. await
888
949
. map_err ( HttpNextError :: Hyper )
889
950
} else if Some ( TLS_ALPN_HTTP_11 ) == handshake. as_deref ( ) {
890
951
serve_http11_unconditional ( io, svc, listen_cancel_handle)
891
952
. await
892
953
. map_err ( HttpNextError :: Hyper )
893
954
} else {
894
- serve_http2_autodetect ( io, svc, listen_cancel_handle) . await
955
+ serve_http2_autodetect ( io, svc, listen_cancel_handle, h2_config ) . await
895
956
}
896
957
}
897
958
. try_or_cancel ( connection_cancel_handle) ,
@@ -903,6 +964,7 @@ fn serve_http(
903
964
request_info : HttpConnectionProperties ,
904
965
lifetime : HttpLifetime ,
905
966
tx : tokio:: sync:: mpsc:: Sender < Rc < HttpRecord > > ,
967
+ h2_config : Http2Config ,
906
968
) -> JoinHandle < Result < ( ) , HttpNextError > > {
907
969
let HttpLifetime {
908
970
server_state,
@@ -914,7 +976,7 @@ fn serve_http(
914
976
handle_request ( req, request_info. clone ( ) , server_state. clone ( ) , tx. clone ( ) )
915
977
} ) ;
916
978
spawn (
917
- serve_http2_autodetect ( io, svc, listen_cancel_handle)
979
+ serve_http2_autodetect ( io, svc, listen_cancel_handle, h2_config )
918
980
. try_or_cancel ( connection_cancel_handle) ,
919
981
)
920
982
}
@@ -924,6 +986,7 @@ fn serve_http_on<HTTP>(
924
986
listen_properties : & HttpListenProperties ,
925
987
lifetime : HttpLifetime ,
926
988
tx : tokio:: sync:: mpsc:: Sender < Rc < HttpRecord > > ,
989
+ h2_config : Http2Config ,
927
990
) -> JoinHandle < Result < ( ) , HttpNextError > >
928
991
where
929
992
HTTP : HttpPropertyExtractor ,
@@ -935,14 +998,14 @@ where
935
998
936
999
match network_stream {
937
1000
NetworkStream :: Tcp ( conn) => {
938
- serve_http ( conn, connection_properties, lifetime, tx)
1001
+ serve_http ( conn, connection_properties, lifetime, tx, h2_config )
939
1002
}
940
1003
NetworkStream :: Tls ( conn) => {
941
- serve_https ( conn, connection_properties, lifetime, tx)
1004
+ serve_https ( conn, connection_properties, lifetime, tx, h2_config )
942
1005
}
943
1006
#[ cfg( unix) ]
944
1007
NetworkStream :: Unix ( conn) => {
945
- serve_http ( conn, connection_properties, lifetime, tx)
1008
+ serve_http ( conn, connection_properties, lifetime, tx, h2_config )
946
1009
}
947
1010
}
948
1011
}
@@ -1031,6 +1094,11 @@ where
1031
1094
1032
1095
let lifetime = resource. lifetime ( ) ;
1033
1096
1097
+ let h2_config = {
1098
+ let state = state. borrow ( ) ;
1099
+ * state. borrow :: < Http2Config > ( )
1100
+ } ;
1101
+
1034
1102
let listen_properties_clone: HttpListenProperties = listen_properties. clone ( ) ;
1035
1103
let handle = spawn ( async move {
1036
1104
loop {
@@ -1043,6 +1111,7 @@ where
1043
1111
& listen_properties_clone,
1044
1112
lifetime. clone ( ) ,
1045
1113
tx. clone ( ) ,
1114
+ h2_config,
1046
1115
) ;
1047
1116
}
1048
1117
#[ allow( unreachable_code) ]
@@ -1079,11 +1148,17 @@ where
1079
1148
let ( tx, rx) = tokio:: sync:: mpsc:: channel ( 10 ) ;
1080
1149
let resource: Rc < HttpJoinHandle > = Rc :: new ( HttpJoinHandle :: new ( rx) ) ;
1081
1150
1151
+ let h2_config = {
1152
+ let state = state. borrow ( ) ;
1153
+ * state. borrow :: < Http2Config > ( )
1154
+ } ;
1155
+
1082
1156
let handle = serve_http_on :: < HTTP > (
1083
1157
connection,
1084
1158
& listen_properties,
1085
1159
resource. lifetime ( ) ,
1086
1160
tx,
1161
+ h2_config,
1087
1162
) ;
1088
1163
1089
1164
// Set the handle after we start the future
0 commit comments