1- use std:: collections:: HashMap ;
1+ use std:: { cmp :: min , collections:: HashMap } ;
22
33use rusty_ulid:: Ulid ;
44use sozu_command:: ready:: Ready ;
@@ -9,7 +9,7 @@ use crate::{
99 converter, debug_kawa, forcefully_terminate_answer,
1010 parser:: {
1111 self , error_code_to_str, Frame , FrameHeader , FrameType , H2Error , Headers , ParserError ,
12- ParserErrorKind , StreamDependency , WindowUpdate ,
12+ ParserErrorKind , WindowUpdate ,
1313 } ,
1414 pkawa, serializer, set_default_answer, update_readiness_after_read,
1515 update_readiness_after_write, BackendStatus , Context , Endpoint , GenericHttpStream ,
@@ -127,13 +127,13 @@ pub struct ConnectionH2<Front: SocketHandler> {
127127impl < Front : SocketHandler > std:: fmt:: Debug for ConnectionH2 < Front > {
128128 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
129129 f. debug_struct ( "ConnectionH2" )
130- . field ( "expect" , & self . expect_read )
131130 . field ( "position" , & self . position )
131+ . field ( "state" , & self . state )
132+ . field ( "expect" , & self . expect_read )
132133 . field ( "readiness" , & self . readiness )
133134 . field ( "local_settings" , & self . local_settings )
134135 . field ( "peer_settings" , & self . peer_settings )
135136 . field ( "socket" , & self . socket . socket_ref ( ) )
136- . field ( "state" , & self . state )
137137 . field ( "streams" , & self . streams )
138138 . field ( "zero" , & self . zero . storage . meter ( 20 ) )
139139 . field ( "window" , & self . window )
@@ -185,15 +185,6 @@ impl<Front: SocketHandler> ConnectionH2<Front> {
185185 return self . force_disconnect ( ) ;
186186 }
187187 }
188- // (
189- // H2State::Frame(FrameHeader {
190- // payload_len,
191- // frame_type: FrameType::Data,
192- // flags,
193- // stream_id,
194- // }),
195- // _,
196- // ) => {}
197188 _ => { }
198189 }
199190 return MuxResult :: Continue ;
@@ -340,9 +331,7 @@ impl<Front: SocketHandler> ConnectionH2<Front> {
340331 Some ( _) => { }
341332 None => return self . goaway ( H2Error :: InternalError ) ,
342333 }
343- } else if header. frame_type != FrameType :: Priority
344- && header. frame_type != FrameType :: WindowUpdate
345- {
334+ } else if header. frame_type != FrameType :: Priority {
346335 println_ ! (
347336 "ONLY HEADERS AND PRIORITY CAN BE RECEIVED ON IDLE/CLOSED STREAMS"
348337 ) ;
@@ -546,6 +535,7 @@ impl<Front: SocketHandler> ConnectionH2<Front> {
546535 }
547536
548537 let mut converter = converter:: H2BlockConverter {
538+ window : 0 ,
549539 stream_id : 0 ,
550540 encoder : & mut self . encoder ,
551541 out : Vec :: new ( ) ,
@@ -557,10 +547,16 @@ impl<Front: SocketHandler> ConnectionH2<Front> {
557547 ' outer: for stream_id in priorities {
558548 let global_stream_id = * self . streams . get ( stream_id) . unwrap ( ) ;
559549 let stream = & mut context. streams [ global_stream_id] ;
560- let kawa = stream. wbuffer ( & self . position ) ;
550+ let parts = stream. split ( & self . position ) ;
551+ let kawa = parts. wbuffer ;
561552 if kawa. is_main_phase ( ) || kawa. is_error ( ) {
553+ let window = min ( * parts. window , self . window ) ;
554+ converter. window = window;
562555 converter. stream_id = * stream_id;
563556 kawa. prepare ( & mut converter) ;
557+ let consumed = window - converter. window ;
558+ * parts. window -= consumed;
559+ self . window -= consumed;
564560 debug_kawa ( kawa) ;
565561 }
566562 while !kawa. out . is_empty ( ) {
@@ -828,7 +824,7 @@ impl<Front: SocketHandler> ConnectionH2<Front> {
828824 1 => { self . peer_settings . settings_header_table_size = v } ,
829825 2 => { self . peer_settings . settings_enable_push = v == 1 ; is_error |= v > 1 } ,
830826 3 => { self . peer_settings . settings_max_concurrent_streams = v } ,
831- 4 => { self . peer_settings . settings_initial_window_size = v ; is_error |= v >= 1 << 31 } ,
827+ 4 => { is_error |= self . update_initial_window_size ( v , context ) } ,
832828 5 => { self . peer_settings . settings_max_frame_size = v; is_error |= v >= 1 <<24 || v < 1 <<14 } ,
833829 6 => { self . peer_settings . settings_max_header_list_size = v } ,
834830 8 => { self . peer_settings . settings_enable_connect_protocol = v == 1 ; is_error |= v > 1 } ,
@@ -881,23 +877,29 @@ impl<Front: SocketHandler> ConnectionH2<Front> {
881877 } ) => {
882878 let increment = increment as i32 ;
883879 if stream_id == 0 {
884- if increment > i32:: MAX - self . window {
885- return self . goaway ( H2Error :: FlowControlError ) ;
880+ if let Some ( window) = self . window . checked_add ( increment) {
881+ if self . window <= 0 && window > 0 {
882+ self . readiness . interest . insert ( Ready :: WRITABLE ) ;
883+ }
884+ self . window = window;
886885 } else {
887- self . window += increment ;
886+ return self . goaway ( H2Error :: FlowControlError ) ;
888887 }
889888 } else {
890889 if let Some ( global_stream_id) = self . streams . get ( & stream_id) {
891890 let stream = & mut context. streams [ * global_stream_id] ;
892- if increment > i32:: MAX - stream. window {
891+ if let Some ( window) = stream. window . checked_add ( increment) {
892+ if stream. window <= 0 && window > 0 {
893+ self . readiness . interest . insert ( Ready :: WRITABLE ) ;
894+ }
895+ stream. window = window;
896+ } else {
893897 return self . reset_stream (
894898 * global_stream_id,
895899 context,
896900 endpoint,
897901 H2Error :: FlowControlError ,
898902 ) ;
899- } else {
900- stream. window += increment;
901903 }
902904 } else {
903905 println_ ! (
@@ -911,6 +913,36 @@ impl<Front: SocketHandler> ConnectionH2<Front> {
911913 MuxResult :: Continue
912914 }
913915
916+ fn update_initial_window_size < L > ( & mut self , value : u32 , context : & mut Context < L > ) -> bool
917+ where
918+ L : ListenerHandler + L7ListenerHandler ,
919+ {
920+ if value >= 1 << 31 {
921+ return true ;
922+ }
923+ let delta = value as i32 - self . peer_settings . settings_initial_window_size as i32 ;
924+ println ! (
925+ "INITIAL_WINDOW_SIZE: {} -> {} => {}" ,
926+ self . peer_settings. settings_initial_window_size, value, delta
927+ ) ;
928+ let mut open_window = false ;
929+ for ( i, stream) in context. streams . iter_mut ( ) . enumerate ( ) {
930+ println ! (
931+ " - stream_{i}: {} -> {}" ,
932+ stream. window,
933+ stream. window + delta
934+ ) ;
935+ open_window |= stream. window <= 0 && stream. window + delta > 0 ;
936+ stream. window += delta;
937+ }
938+ println_ ! ( "UPDATE INIT WINDOW: {open_window} {:?}" , self . readiness) ;
939+ if open_window {
940+ self . readiness . interest . insert ( Ready :: WRITABLE ) ;
941+ }
942+ self . peer_settings . settings_initial_window_size = value;
943+ false
944+ }
945+
914946 pub fn force_disconnect ( & mut self ) -> MuxResult {
915947 self . state = H2State :: Error ;
916948 match self . position {
0 commit comments