@ -151,107 +151,6 @@ static grpc_error_handle parse_max_tbl_size_x(grpc_chttp2_hpack_parser* p,
const uint8_t * cur ,
const uint8_t * end ) ;
/* we translate the first byte of a hpack field into one of these decoding
cases , then use a lookup table to jump directly to the appropriate parser .
_X = > the integer index is all ones , meaning we need to do varint decoding
_V = > the integer index is all zeros , meaning we need to decode an additional
string value */
typedef enum {
INDEXED_FIELD ,
INDEXED_FIELD_X ,
LITHDR_INCIDX ,
LITHDR_INCIDX_X ,
LITHDR_INCIDX_V ,
LITHDR_NOTIDX ,
LITHDR_NOTIDX_X ,
LITHDR_NOTIDX_V ,
LITHDR_NVRIDX ,
LITHDR_NVRIDX_X ,
LITHDR_NVRIDX_V ,
MAX_TBL_SIZE ,
MAX_TBL_SIZE_X ,
ILLEGAL
} first_byte_type ;
/* jump table of parse state functions -- order must match first_byte_type
above */
static const grpc_chttp2_hpack_parser_state first_byte_action [ ] = {
parse_indexed_field , parse_indexed_field_x , parse_lithdr_incidx ,
parse_lithdr_incidx_x , parse_lithdr_incidx_v , parse_lithdr_notidx ,
parse_lithdr_notidx_x , parse_lithdr_notidx_v , parse_lithdr_nvridx ,
parse_lithdr_nvridx_x , parse_lithdr_nvridx_v , parse_max_tbl_size ,
parse_max_tbl_size_x , parse_illegal_op } ;
/* indexes the first byte to a parse state function - generated by
gen_hpack_tables . c */
static const uint8_t first_byte_lut [ 256 ] = {
LITHDR_NOTIDX_V , LITHDR_NOTIDX , LITHDR_NOTIDX , LITHDR_NOTIDX ,
LITHDR_NOTIDX , LITHDR_NOTIDX , LITHDR_NOTIDX , LITHDR_NOTIDX ,
LITHDR_NOTIDX , LITHDR_NOTIDX , LITHDR_NOTIDX , LITHDR_NOTIDX ,
LITHDR_NOTIDX , LITHDR_NOTIDX , LITHDR_NOTIDX , LITHDR_NOTIDX_X ,
LITHDR_NVRIDX_V , LITHDR_NVRIDX , LITHDR_NVRIDX , LITHDR_NVRIDX ,
LITHDR_NVRIDX , LITHDR_NVRIDX , LITHDR_NVRIDX , LITHDR_NVRIDX ,
LITHDR_NVRIDX , LITHDR_NVRIDX , LITHDR_NVRIDX , LITHDR_NVRIDX ,
LITHDR_NVRIDX , LITHDR_NVRIDX , LITHDR_NVRIDX , LITHDR_NVRIDX_X ,
MAX_TBL_SIZE , MAX_TBL_SIZE , MAX_TBL_SIZE , MAX_TBL_SIZE ,
MAX_TBL_SIZE , MAX_TBL_SIZE , MAX_TBL_SIZE , MAX_TBL_SIZE ,
MAX_TBL_SIZE , MAX_TBL_SIZE , MAX_TBL_SIZE , MAX_TBL_SIZE ,
MAX_TBL_SIZE , MAX_TBL_SIZE , MAX_TBL_SIZE , MAX_TBL_SIZE ,
MAX_TBL_SIZE , MAX_TBL_SIZE , MAX_TBL_SIZE , MAX_TBL_SIZE ,
MAX_TBL_SIZE , MAX_TBL_SIZE , MAX_TBL_SIZE , MAX_TBL_SIZE ,
MAX_TBL_SIZE , MAX_TBL_SIZE , MAX_TBL_SIZE , MAX_TBL_SIZE ,
MAX_TBL_SIZE , MAX_TBL_SIZE , MAX_TBL_SIZE , MAX_TBL_SIZE_X ,
LITHDR_INCIDX_V , LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX ,
LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX ,
LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX ,
LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX ,
LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX ,
LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX ,
LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX ,
LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX ,
LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX ,
LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX ,
LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX ,
LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX ,
LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX ,
LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX ,
LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX ,
LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX , LITHDR_INCIDX_X ,
ILLEGAL , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD ,
INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD , INDEXED_FIELD_X ,
} ;
/* state table for huffman decoding: given a state, gives an index/16 into
next_sub_tbl . Taking that index and adding the value of the nibble being
considered returns the next state .
@ -731,7 +630,105 @@ static grpc_error_handle parse_begin(grpc_chttp2_hpack_parser* p,
return GRPC_ERROR_NONE ;
}
return first_byte_action [ first_byte_lut [ * cur ] ] ( p , cur , end ) ;
switch ( * cur > > 4 ) {
// Literal header not indexed.
// First byte format: 0000xxxx
// Where xxxx:
// 0000 - literal key
// 1111 - indexed key, varint encoded index
// other - indexed key, inline encoded index
case 0 :
switch ( * cur & 0xf ) {
case 0 : // literal key
return parse_lithdr_notidx_v ( p , cur , end ) ;
case 0xf : // varint encoded key index
return parse_lithdr_notidx_x ( p , cur , end ) ;
default : // inline encoded key index
return parse_lithdr_notidx ( p , cur , end ) ;
}
// Literal header never indexed.
// First byte format: 0001xxxx
// Where xxxx:
// 0000 - literal key
// 1111 - indexed key, varint encoded index
// other - indexed key, inline encoded index
case 1 :
switch ( * cur & 0xf ) {
case 0 : // literal key
return parse_lithdr_nvridx_v ( p , cur , end ) ;
case 0xf : // varint encoded key index
return parse_lithdr_nvridx_x ( p , cur , end ) ;
default : // inline encoded key index
return parse_lithdr_nvridx ( p , cur , end ) ;
}
// Update max table size.
// First byte format: 001xxxxx
// Where xxxxx:
// 11111 - max size is varint encoded
// other - max size is stored inline
case 2 :
// inline encoded max table size
return parse_max_tbl_size ( p , cur , end ) ;
case 3 :
if ( * cur = = 0x3f ) {
// varint encoded max table size
return parse_max_tbl_size_x ( p , cur , end ) ;
} else {
// inline encoded max table size
return parse_max_tbl_size ( p , cur , end ) ;
}
// Literal header with incremental indexing.
// First byte format: 01xxxxxx
// Where xxxxxx:
// 000000 - literal key
// 111111 - indexed key, varint encoded index
// other - indexed key, inline encoded index
case 4 :
if ( * cur = = 0x40 ) {
// literal key
return parse_lithdr_incidx_v ( p , cur , end ) ;
}
case 5 :
case 6 :
// inline encoded key index
return parse_lithdr_incidx ( p , cur , end ) ;
case 7 :
if ( * cur = = 0x7f ) {
// varint encoded key index
return parse_lithdr_incidx_x ( p , cur , end ) ;
} else {
// inline encoded key index
return parse_lithdr_incidx ( p , cur , end ) ;
}
// Indexed Header Field Representation
// First byte format: 1xxxxxxx
// Where xxxxxxx:
// 0000000 - illegal
// 1111111 - varint encoded field index
// other - inline encoded field index
case 8 :
if ( * cur = = 0x80 ) {
// illegal value.
return parse_illegal_op ( p , cur , end ) ;
}
case 9 :
case 10 :
case 11 :
case 12 :
case 13 :
case 14 :
// inline encoded field index
return parse_indexed_field ( p , cur , end ) ;
case 15 :
if ( * cur = = 0xff ) {
// varint encoded field index
return parse_indexed_field_x ( p , cur , end ) ;
} else {
// inline encoded field index
return parse_indexed_field ( p , cur , end ) ;
}
}
GPR_UNREACHABLE_CODE ( abort ( ) ) ;
}
/* stream dependency and prioritization data: we just skip it */