@@ -244,6 +244,18 @@ struct aws_h2_decoder {
244244 bool malformed ;
245245 } header_block_in_progress ;
246246
247+ /* Settings for decoder, which is based on the settings sent to the peer and ACKed by peer */
248+ struct {
249+ /* the maximum size of the header compression table used to decode header blocks */
250+ uint32_t header_table_size ;
251+ /* enable/disable server push */
252+ uint32_t enable_push ;
253+ /* the size of the largest frame payload */
254+ uint32_t max_frame_size ;
255+ } settings ;
256+
257+ struct aws_array_list settings_buffer_list ;
258+
247259 /* User callbacks and settings. */
248260 const struct aws_h2_decoder_vtable * vtable ;
249261 void * userdata ;
@@ -290,9 +302,19 @@ struct aws_h2_decoder *aws_h2_decoder_new(struct aws_h2_decoder_params *params)
290302 decoder -> state = & s_state_prefix ;
291303 }
292304
305+ decoder -> settings .header_table_size = aws_h2_settings_initial [AWS_H2_SETTINGS_HEADER_TABLE_SIZE ];
306+ decoder -> settings .enable_push = aws_h2_settings_initial [AWS_H2_SETTINGS_ENABLE_PUSH ];
307+ decoder -> settings .max_frame_size = aws_h2_settings_initial [AWS_H2_SETTINGS_MAX_FRAME_SIZE ];
308+
309+ if (aws_array_list_init_dynamic (
310+ & decoder -> settings_buffer_list , decoder -> alloc , 0 , sizeof (struct aws_h2_frame_setting ))) {
311+ goto array_list_failed ;
312+ }
313+
293314 return decoder ;
294315
295316failed_new_hpack :
317+ array_list_failed :
296318 aws_mem_release (params -> alloc , allocation );
297319failed_alloc :
298320 return NULL ;
@@ -309,6 +331,7 @@ void aws_h2_decoder_destroy(struct aws_h2_decoder *decoder) {
309331 if (!decoder ) {
310332 return ;
311333 }
334+ aws_array_list_clean_up (& decoder -> settings_buffer_list );
312335 aws_hpack_context_destroy (decoder -> hpack );
313336 s_reset_header_block_in_progress (decoder );
314337 aws_mem_release (decoder -> alloc , decoder );
@@ -587,13 +610,13 @@ static int s_state_fn_prefix(struct aws_h2_decoder *decoder, struct aws_byte_cur
587610 }
588611
589612 /* Validate payload length. */
590- static const uint32_t MAX_FRAME_SIZE = 16384 ; /* #TODO handle the SETTINGS_MAX_FRAME_SIZE setting */
591- if (frame -> payload_len > MAX_FRAME_SIZE ) {
613+ uint32_t max_frame_size = decoder -> settings . max_frame_size ;
614+ if (frame -> payload_len > max_frame_size ) {
592615 DECODER_LOGF (
593616 ERROR ,
594617 decoder ,
595618 "Decoder's max frame size is %" PRIu32 ", but frame of size %" PRIu32 " was received." ,
596- MAX_FRAME_SIZE ,
619+ max_frame_size ,
597620 frame -> payload_len );
598621 return aws_raise_error (AWS_ERROR_HTTP_INVALID_FRAME_SIZE );
599622 }
@@ -785,9 +808,6 @@ static int s_state_fn_frame_settings_begin(struct aws_h2_decoder *decoder, struc
785808 return aws_raise_error (AWS_ERROR_HTTP_INVALID_FRAME_SIZE );
786809 }
787810
788- /* Report start of non-ACK settings frame */
789- DECODER_CALL_VTABLE (decoder , on_settings_begin );
790-
791811 /* Enter looping states until all entries are consumed. */
792812 return s_decoder_switch_state (decoder , & s_state_frame_settings_loop );
793813}
@@ -797,8 +817,12 @@ static int s_state_fn_frame_settings_loop(struct aws_h2_decoder *decoder, struct
797817 (void )input ;
798818
799819 if (decoder -> frame_in_progress .payload_len == 0 ) {
800- /* Huzzah, done with the frame */
801- DECODER_CALL_VTABLE (decoder , on_settings_end );
820+ /* Huzzah, done with the frame, fire the callback */
821+ struct aws_array_list * buffer = & decoder -> settings_buffer_list ;
822+ DECODER_CALL_VTABLE_ARGS (
823+ decoder , on_settings , buffer -> data , aws_array_list_length (& decoder -> settings_buffer_list ));
824+ /* clean up the buffer */
825+ aws_array_list_clear (& decoder -> settings_buffer_list );
802826 return s_decoder_reset_state (decoder );
803827 }
804828
@@ -831,7 +855,25 @@ static int s_state_fn_frame_settings_i(struct aws_h2_decoder *decoder, struct aw
831855 /* An endpoint that receives a SETTINGS frame with any unknown or unsupported identifier MUST ignore that setting.
832856 * RFC-7540 6.5.2 */
833857 if (id >= AWS_H2_SETTINGS_BEGIN_RANGE && id < AWS_H2_SETTINGS_END_RANGE ) {
834- DECODER_CALL_VTABLE_ARGS (decoder , on_settings_i , id , value );
858+ /* check the value meets the settings bounds */
859+ if (value < aws_h2_settings_bounds [id ][0 ] || value > aws_h2_settings_bounds [id ][1 ]) {
860+ DECODER_LOGF (
861+ ERROR , decoder , "A value of SETTING frame is invalid, id: %" PRIu16 ", value: %" PRIu32 , id , value );
862+ if (id == AWS_H2_SETTINGS_INITIAL_WINDOW_SIZE ) {
863+ return aws_raise_error (AWS_H2_ERR_FLOW_CONTROL_ERROR );
864+ } else {
865+ /* TODO: translates errors from AWS_ERROR_HTTP_XYZ into AWS_H2_ERR_XYZ */
866+ return aws_raise_error (AWS_ERROR_HTTP_PROTOCOL_ERROR );
867+ }
868+ }
869+ struct aws_h2_frame_setting setting ;
870+ setting .id = id ;
871+ setting .value = value ;
872+ /* array_list will keep a copy of setting, it is fine to be a local variable */
873+ if (aws_array_list_push_back (& decoder -> settings_buffer_list , & setting )) {
874+ DECODER_LOGF (ERROR , decoder , "Writing setting to buffer failed, %s" , aws_error_name (aws_last_error ()));
875+ return AWS_OP_ERR ;
876+ }
835877 }
836878
837879 /* Update payload len */
@@ -848,6 +890,12 @@ static int s_state_fn_frame_settings_i(struct aws_h2_decoder *decoder, struct aw
848890 */
849891static int s_state_fn_frame_push_promise (struct aws_h2_decoder * decoder , struct aws_byte_cursor * input ) {
850892
893+ if (decoder -> settings .enable_push == 0 ) {
894+ /* treat the receipt of a PUSH_PROMISE frame as a connection error of type PROTOCOL_ERROR.(RFC-7540 6.5.2) */
895+ DECODER_LOG (ERROR , decoder , "PUSH_PROMISE is invalid, the seting for enable push is 0" );
896+ return aws_raise_error (AWS_ERROR_HTTP_PROTOCOL_ERROR );
897+ }
898+
851899 AWS_ASSERT (input -> len >= s_state_frame_push_promise_requires_4_bytes );
852900
853901 uint32_t promised_stream_id = 0 ;
@@ -1342,3 +1390,15 @@ static int s_state_fn_connection_preface_string(struct aws_h2_decoder *decoder,
13421390 /* Remain in state until more data arrives */
13431391 return AWS_OP_SUCCESS ;
13441392}
1393+
1394+ void aws_h2_decoder_set_setting_header_table_size (struct aws_h2_decoder * decoder , uint32_t data ) {
1395+ decoder -> settings .header_table_size = data ;
1396+ }
1397+
1398+ void aws_h2_decoder_set_setting_enable_push (struct aws_h2_decoder * decoder , uint32_t data ) {
1399+ decoder -> settings .enable_push = data ;
1400+ }
1401+
1402+ void aws_h2_decoder_set_setting_max_frame_size (struct aws_h2_decoder * decoder , uint32_t data ) {
1403+ decoder -> settings .max_frame_size = data ;
1404+ }
0 commit comments