@ -124,6 +124,32 @@ static void hs_add_error(const char* error_name, grpc_error** cumulative,
* cumulative = grpc_error_add_child ( * cumulative , new_err ) ;
}
// Metadata equality within this filter leverages the fact that the sender was
// likely using the gRPC chttp2 transport, in which case the encoder would emit
// indexed values, in which case the local hpack parser would intern the
// relevant metadata, allowing a simple pointer comparison.
//
// That said, if the header was transmitted sans indexing/encoding, we still
// need to do the right thing.
//
// Assumptions:
// 1) The keys for a and b_static must match
// 2) b_static must be a statically allocated metadata object.
// 3) It is assumed that the remote end is indexing, but not necessary.
// TODO(arjunroy): Revisit this method when grpc_mdelem is strongly typed.
static bool md_strict_equal ( grpc_mdelem a , grpc_mdelem b_static ) {
// Hpack encoder on the remote side should emit indexed values, in which case
// hpack parser on this end should pick up interned values, in which case the
// pointer comparison alone is enough.
//
if ( GPR_LIKELY ( GRPC_MDELEM_IS_INTERNED ( a ) ) ) {
return a . payload = = b_static . payload ;
} else {
return grpc_slice_eq_static_interned ( GRPC_MDVALUE ( a ) ,
GRPC_MDVALUE ( b_static ) ) ;
}
}
static grpc_error * hs_filter_incoming_metadata ( grpc_call_element * elem ,
grpc_metadata_batch * b ) {
call_data * calld = static_cast < call_data * > ( elem - > call_data ) ;
@ -131,19 +157,18 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem,
static const char * error_name = " Failed processing incoming headers " ;
if ( b - > idx . named . method ! = nullptr ) {
if ( grpc_mdelem_static_value_eq ( b - > idx . named . method - > md ,
GRPC_MDELEM_METHOD_POST ) ) {
if ( md_strict_equal ( b - > idx . named . method - > md , GRPC_MDELEM_METHOD_POST ) ) {
* calld - > recv_initial_metadata_flags & =
~ ( GRPC_INITIAL_METADATA_CACHEABLE_REQUEST |
GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST ) ;
} else if ( grpc_mdelem_static_value_eq ( b - > idx . named . method - > md ,
GRPC_MDELEM_METHOD_PUT ) ) {
} else if ( md_strict_equal ( b - > idx . named . method - > md ,
GRPC_MDELEM_METHOD_PUT ) ) {
* calld - > recv_initial_metadata_flags & =
~ GRPC_INITIAL_METADATA_CACHEABLE_REQUEST ;
* calld - > recv_initial_metadata_flags | =
GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST ;
} else if ( grpc_mdelem_static_value_eq ( b - > idx . named . method - > md ,
GRPC_MDELEM_METHOD_GET ) ) {
} else if ( md_strict_equal ( b - > idx . named . method - > md ,
GRPC_MDELEM_METHOD_GET ) ) {
* calld - > recv_initial_metadata_flags | =
GRPC_INITIAL_METADATA_CACHEABLE_REQUEST ;
* calld - > recv_initial_metadata_flags & =
@ -154,7 +179,7 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem,
GRPC_ERROR_CREATE_FROM_STATIC_STRING ( " Bad header " ) ,
b - > idx . named . method - > md ) ) ;
}
grpc_metadata_batch_remove ( b , b - > idx . named . method ) ;
grpc_metadata_batch_remove ( b , GRPC_BATCH_METHOD ) ;
} else {
hs_add_error (
error_name , & error ,
@ -171,7 +196,7 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem,
GRPC_ERROR_CREATE_FROM_STATIC_STRING ( " Bad header " ) ,
b - > idx . named . te - > md ) ) ;
}
grpc_metadata_batch_remove ( b , b - > idx . named . te ) ;
grpc_metadata_batch_remove ( b , GRPC_BATCH_TE ) ;
} else {
hs_add_error ( error_name , & error ,
grpc_error_set_str (
@ -180,10 +205,8 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem,
}
if ( b - > idx . named . scheme ! = nullptr ) {
if ( ! grpc_mdelem_static_value_eq ( b - > idx . named . scheme - > md ,
GRPC_MDELEM_SCHEME_HTTP ) & &
! grpc_mdelem_static_value_eq ( b - > idx . named . scheme - > md ,
GRPC_MDELEM_SCHEME_HTTPS ) & &
if ( ! md_strict_equal ( b - > idx . named . scheme - > md , GRPC_MDELEM_SCHEME_HTTP ) & &
! md_strict_equal ( b - > idx . named . scheme - > md , GRPC_MDELEM_SCHEME_HTTPS ) & &
! grpc_mdelem_static_value_eq ( b - > idx . named . scheme - > md ,
GRPC_MDELEM_SCHEME_GRPC ) ) {
hs_add_error ( error_name , & error ,
@ -191,7 +214,7 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem,
GRPC_ERROR_CREATE_FROM_STATIC_STRING ( " Bad header " ) ,
b - > idx . named . scheme - > md ) ) ;
}
grpc_metadata_batch_remove ( b , b - > idx . named . scheme ) ;
grpc_metadata_batch_remove ( b , GRPC_BATCH_SCHEME ) ;
} else {
hs_add_error (
error_name , & error ,
@ -227,7 +250,7 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem,
gpr_free ( val ) ;
}
}
grpc_metadata_batch_remove ( b , b - > idx . named . content_type ) ;
grpc_metadata_batch_remove ( b , GRPC_BATCH_CONTENT_TYPE ) ;
}
if ( b - > idx . named . path = = nullptr ) {
@ -282,12 +305,13 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem,
grpc_linked_mdelem * el = b - > idx . named . host ;
grpc_mdelem md = GRPC_MDELEM_REF ( el - > md ) ;
grpc_metadata_batch_remove ( b , el ) ;
hs_add_error ( error_name , & error ,
grpc_metadata_batch_add_head (
b , el ,
grpc_mdelem_from_slices (
GRPC_MDSTR_AUTHORITY ,
grpc_slice_ref_internal ( GRPC_MDVALUE ( md ) ) ) ) ) ;
hs_add_error (
error_name , & error ,
grpc_metadata_batch_add_head (
b , el ,
grpc_mdelem_from_slices ( GRPC_MDSTR_AUTHORITY ,
grpc_slice_ref_internal ( GRPC_MDVALUE ( md ) ) ) ,
GRPC_BATCH_AUTHORITY ) ) ;
GRPC_MDELEM_UNREF ( md ) ;
}
@ -301,7 +325,7 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem,
channel_data * chand = static_cast < channel_data * > ( elem - > channel_data ) ;
if ( ! chand - > surface_user_agent & & b - > idx . named . user_agent ! = nullptr ) {
grpc_metadata_batch_remove ( b , b - > idx . named . user_agent ) ;
grpc_metadata_batch_remove ( b , GRPC_BATCH_USER_AGENT ) ;
}
return error ;
@ -392,15 +416,17 @@ static grpc_error* hs_mutate_op(grpc_call_element* elem,
if ( op - > send_initial_metadata ) {
grpc_error * error = GRPC_ERROR_NONE ;
static const char * error_name = " Failed sending initial metadata " ;
hs_add_error ( error_name , & error ,
grpc_metadata_batch_add_head (
op - > payload - > send_initial_metadata . send_initial_metadata ,
& calld - > status , GRPC_MDELEM_STATUS_200 ) ) ;
hs_add_error (
error_name , & error ,
grpc_metadata_batch_add_head (
op - > payload - > send_initial_metadata . send_initial_metadata ,
& calld - > status , GRPC_MDELEM_STATUS_200 , GRPC_BATCH_STATUS ) ) ;
hs_add_error ( error_name , & error ,
grpc_metadata_batch_add_tail (
op - > payload - > send_initial_metadata . send_initial_metadata ,
& calld - > content_type ,
GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC ) ) ;
GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC ,
GRPC_BATCH_CONTENT_TYPE ) ) ;
hs_add_error (
error_name , & error ,
hs_filter_outgoing_metadata (