int SubstFormat::parse( const char * pCurLine, const char * pFormatStr, const char * pEnd, int isSSI, char varChar ) { while(( pFormatStr < pEnd )&&( isspace( *pFormatStr ))) ++pFormatStr; int err = 0; char achVarChar[2]; LinkedObj * pLast = head(); SubstItem * pItem; achVarChar[0] = varChar; achVarChar[1] = 0; while( pFormatStr < pEnd ) { pItem = new SubstItem(); if ( !pItem ) { ERR_NO_MEM( "new SubstItem()" ); return -1; } if ( *pFormatStr == varChar ) { if ( pFormatStr + 1 == pEnd ) { HttpLog::parse_error( pCurLine , "Line ended with '$'" ); err = 1; } if ( isdigit( *( pFormatStr + 1 ) ) ) { pItem->setType( REF_RULE_SUBSTR ); pItem->setIndex( *(pFormatStr + 1) - '0' ); pFormatStr += 2; } else { ++pFormatStr; if ( pItem->parseServerVar( pCurLine, pFormatStr, pEnd, isSSI ) ) { err = 1; } } } else { pItem->parseString( pFormatStr, pEnd, achVarChar ); } if ( err ) { delete pItem; return -1; } else { pLast->addNext( pItem ); pLast = pItem; } } return 0; }
int RewriteEngine::parseRules( char * &pRules, RewriteRuleList * pRuleList, const RewriteMapList * pMapList ) { LinkedObj * pLast = pRuleList->tail(); if ( !pLast ) pLast = pRuleList->head(); while( *pRules ) { while( isspace( *pRules ) ) ++pRules; if ( !*pRules ) break; if ((( strncasecmp( pRules, "RewriteCond", 11 ) == 0 )&& ( isspace( *(pRules + 11)) ))|| (( strncasecmp( pRules, "RewriteRule", 11 ) == 0 )&& ( isspace( *(pRules + 11)) ))) { RewriteRule * pRule = new RewriteRule(); if ( !pRule ) { ERR_NO_MEM( "new RewriteRule()" ); return -1; } int ret = pRule->parse( pRules, pMapList ); if ( ret ) { delete pRule; return 0; } pLast->addNext( pRule ); pLast = pRule; } else { char * pLineEnd = strchr( pRules, '\n' ); if ( pLineEnd ) *pLineEnd = 0; if ( *pRules != '#' ) { LOG_ERR(( "Invalid rewrite directive: %s", pRules )); } if ( pLineEnd ) *pLineEnd = '\n'; else break; pRules = pLineEnd + 1; } } return 0; }
int RewriteSubstFormat::parse( const char * pFormatStr, const char * pEnd, const RewriteMapList * pMaps ) { while(( pFormatStr < pEnd )&&( isspace( *pFormatStr ))) ++pFormatStr; int err = 0; LinkedObj * pLast = head(); RewriteSubstItem * pItem; while( pFormatStr < pEnd ) { pItem = new RewriteSubstItem(); if ( !pItem ) { ERR_NO_MEM( "new SubstItem()" ); return -1; } switch( *pFormatStr ) { case '$': if ( pFormatStr + 1 == pEnd ) { HttpLog::parse_error( s_pCurLine, "Line ended with '$'" ); err = 1; break; } if ( *( pFormatStr + 1 ) == '{' ) { if ( !pMaps ) { HttpLog::parse_error( s_pCurLine, "No rewrite map defined" ); err = 1; break; } pItem->setType( REF_MAP ); MapRefItem * pMapRef = new MapRefItem(); if ( !pMapRef ) { ERR_NO_MEM( "new MapRefItem()" ); err = 1; break; } if ( pMapRef->parse( pFormatStr, pEnd, pMaps ) ) { delete pMapRef; err = 1; break; } pItem->setMapRef( pMapRef ); } else if ( isdigit( *( pFormatStr + 1 ) ) ) { pItem->setType( REF_RULE_SUBSTR ); pItem->setIndex( *(pFormatStr + 1) - '0' ); pFormatStr += 2; } else { HttpLog::parse_error( s_pCurLine, "'$' should be followed by a digit for a RewriteRule backreference." ); pItem->setType( REF_STRING ); pItem->setStr( pFormatStr, 1 ); ++pFormatStr; } break; case '%': if ( pFormatStr + 1 == pEnd ) { HttpLog::parse_error( s_pCurLine, "Line ended with '%'" ); err = 1; break; } if ( *( pFormatStr + 1 ) == '{' ) { ++pFormatStr; if ( pItem->parseServerVar( s_pCurLine, pFormatStr, pEnd ) ) { err = 1; break; } } else if ( isdigit( *( pFormatStr + 1 ) ) ) { pItem->setType( REF_COND_SUBSTR ); pItem->setIndex( *(pFormatStr + 1) - '0' ); pFormatStr += 2; } else { HttpLog::parse_error( s_pCurLine, "'%' should be followed by a digit for a RewriteCond backreference." ); pItem->setType( REF_STRING ); pItem->setStr( pFormatStr, 1 ); ++pFormatStr; } break; case '\\': default: pItem->parseString( pFormatStr, pEnd, "$%" ); break; } if ( err ) { delete pItem; return -1; } else { pLast->addNext( pItem ); pLast = pItem; } } return 0; }
int RewriteRule::parse( char * &pRule, const RewriteMapList * pMaps ) { char * pCur; char * pLineEnd; LinkedObj * pLast = m_conds.head(); assert( pLast->next() == NULL ); while( *pRule ) { while( isspace( *pRule ) ) ++pRule; if ( !*pRule ) break; pCur = pRule; pLineEnd = strchr( pCur, '\n' ); if ( !pLineEnd ) { pLineEnd = pCur + strlen( pCur ); pRule = pLineEnd; } else { pRule = pLineEnd + 1; *pLineEnd = 0; } s_pCurLine = pCur; if ( *pCur != '#' ) { if (( strncasecmp( pCur, "RewriteCond", 11 ) == 0 )&& ( isspace( *(pCur + 11)) )) { RewriteCond * pCond = new RewriteCond(); if ( !pCond ) { ERR_NO_MEM( "new RewriteCond()" ); return -1; } if ( pCond->parse( pCur+12, pLineEnd, pMaps ) ) { delete pCond; HttpLog::parse_error( s_pCurLine, "invalid rewrite condition" ); return -1; } pLast->addNext( pCond ); pLast = pCond; } else if (( strncasecmp( pCur, "RewriteRule", 11 ) == 0 )&& ( isspace( *(pCur + 11)) )) { int ret = parseRule( pCur+12, pLineEnd, pMaps ); pCur = pLineEnd+1; return ret; } else { HttpLog::parse_error( s_pCurLine, "invalid rewrite directive " ); return -1; } } } return -1; }