@ -90,7 +90,7 @@ bool readFilter(AmConfigReader& cfg, const char* cfg_key_filter, const char* cfg
return true ;
}
int skip_header ( const std : : string & hdr , size_t start_pos ,
int skip_header ( std : : string & hdr , size_t start_pos ,
size_t & name_end , size_t & val_begin ,
size_t & val_end , size_t & hdr_end ) {
/* adapted from sip/parse_header.cpp */
@ -111,8 +111,11 @@ int skip_header(const std::string& hdr, size_t start_pos,
int st = H_NAME ;
int saved_st = 0 ;
/* iterate till actual name, if space(s)/tab(s) in front of hf name */
bool iteration_till_name = true ;
size_t p = start_pos ;
for ( ; p < hdr . length ( ) & & st ! = ST_LF & & st ! = ST_CRLF ; p + + )
for ( ; p < hdr . length ( ) & & st ! = ST_LF & & st ! = ST_CRLF ; p + + )
{
switch ( st )
{
@ -128,9 +131,20 @@ int skip_header(const std::string& hdr, size_t start_pos,
case SP :
case HTAB :
st = H_HCOLON ;
name_end = p ;
/* skip spaces/tabs at the beginning of the line (if now expected hf name) */
if ( ! iteration_till_name ) {
st = H_HCOLON ;
name_end = p ;
} else {
/* remove space from the name */
hdr . erase ( p - - , 1 ) ;
}
break ;
/* other letters apart space, tab and colon */
default :
/* means - no spaces at the beginning of hf name found, start reading the name */
iteration_till_name = false ;
}
break ;
@ -156,9 +170,52 @@ int skip_header(const std::string& hdr, size_t start_pos,
case_CR_LF ;
} ;
if ( st = = ST_CR | | st = = ST_LF )
val_end = p ;
/* trying to guess, if this is a multi-line header */
if ( st = = ST_CR | | st = = ST_LF ) {
/* if next line of SIP message begins with a space, then we should check for a multi-value */
if ( hdr [ p ] = = CR & & hdr [ p + 1 ] = = LF & & ( hdr [ p + 2 ] = = SP | | hdr [ p + 2 ] = = HTAB ) )
{
printf ( " Checking whether the value is multi-line \n " ) ;
/* next line must not contain colon. No colon - is a clear sign of multi-line value */
size_t tmp = p ;
tmp + = 2 ;
bool colon_found = false ;
for ( ; tmp < hdr . length ( ) & & hdr [ tmp ] ! = CR & & hdr [ tmp ] ! = LF ; tmp + + )
{
if ( hdr [ tmp ] = = HCOLON ) {
colon_found = true ;
break ;
}
}
if ( colon_found ) {
/* next line is definitely another header, stop parsing as a value */
val_end = p ;
} else {
/* next line is a part of multi-line value */
hdr . erase ( p , 2 ) ; /* remove CR and LF from the string */
st = H_VALUE ;
}
break ;
/* definitely not a multi-value */
} else {
val_end = p ;
}
}
/* Beginning of the next part of multi-line value.
* By RFC3261 ( section 7.4 .1 ) , as well as by RFC2616 , multi - line value of hf ,
* must begin either with at least one space or tab .
*/
if ( hdr [ p ] = = SP | | hdr [ p ] = = HTAB ) {
while ( hdr [ p ] = = SP | | hdr [ p ] = = HTAB )
p + + ;
}
break ;
case H_HCOLON :
@ -188,7 +245,7 @@ int skip_header(const std::string& hdr, size_t start_pos,
}
hdr_end = p ;
if ( p = = hdr . length ( ) & & st = = H_VALUE ) {
if ( p = = hdr . length ( ) & & st = = H_VALUE ) {
val_end = p ;
}
@ -213,7 +270,7 @@ int inplaceHeaderFilter(string& hdrs, const vector<FilterEntry>& filter_list) {
/* todo: multi-line header support */
size_t start_pos = 0 ;
while ( start_pos < hdrs . length ( ) )
while ( start_pos < hdrs . length ( ) )
{
size_t name_end , val_begin , val_end , hdr_end ;
int res ;
@ -223,10 +280,15 @@ int inplaceHeaderFilter(string& hdrs, const vector<FilterEntry>& filter_list) {
return res ;
}
string hdr_name = hdrs . substr ( start_pos , name_end - start_pos ) ;
string hdr_name = hdrs . substr ( start_pos , name_end - start_pos ) ;
std : : transform ( hdr_name . begin ( ) , hdr_name . end ( ) , hdr_name . begin ( ) , : : tolower ) ;
bool erase = ( f_type = = Whitelist ) ;
string hdr_value = hdrs . substr ( val_begin , val_end - val_begin ) ;
DBG ( " hdr name parsed: '%s' \n " , hdr_name . c_str ( ) ) ;
DBG ( " hdr value parsed: '%s' \n " , hdr_value . c_str ( ) ) ;
for ( set < string > : : iterator it = headerfilter_list . begin ( ) ;
it ! = headerfilter_list . end ( ) ; + + it )
{
@ -237,9 +299,10 @@ int inplaceHeaderFilter(string& hdrs, const vector<FilterEntry>& filter_list) {
}
if ( erase ) {
DBG ( " erasing header '%s' by %s\n " , hdr_name . c_str ( ) , FilterType2String ( f_type ) ) ;
DBG ( " erasing header '%s' by filter ' %s' \n " , hdr_name . c_str ( ) , FilterType2String ( f_type ) ) ;
hdrs . erase ( start_pos , hdr_end - start_pos ) ;
} else {
DBG ( " header accepted '%s' by filter '%s' \n " , hdr_name . c_str ( ) , FilterType2String ( f_type ) ) ;
start_pos = hdr_end ;
}
}