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 SSIEngine::processEcho(HttpSession *pSession, SSIComponent *pComponent) { SubstItem *pItem = (SubstItem *)pComponent->getFirstAttr(); char achBuf1[8192]; char achBuf[40960]; char *p; int len; int attr; int encode = SSI_ENC_ENTITY; while (pItem) { attr = pItem->getSubType(); p = achBuf1; len = 8192; switch (attr) { case SSI_ECHO_VAR: if ((pItem->getType() == REF_DATE_LOCAL) || (pItem->getType() == REF_LAST_MODIFIED) || (pItem->getType() == REF_DATE_GMT)) memccpy(p, pSession->getReq()->getSSIRuntime() ->getConfig()->getTimeFmt()->c_str(), 0, 4096); RequestVars::appendSubst(pItem, pSession, p, len, 0, pSession->getReq()->getSSIRuntime()->getRegexResult()); if (encode == SSI_ENC_URL) { len = HttpUtil::escape(achBuf1, p - achBuf1, achBuf, 40960); p = achBuf; } else if (encode == SSI_ENC_ENTITY) { len = HttpUtil::escapeHtml(achBuf1, p, achBuf, 40960); p = achBuf; } else { len = p - achBuf1; p = achBuf1; } if (len > 0) pSession->appendDynBody(p, len); break; case SSI_ENC_NONE: case SSI_ENC_URL: case SSI_ENC_ENTITY: encode = attr; break; } pItem = (SubstItem *) pItem->next(); } return 0; }
int SSIEngine::updateSSIConfig( HttpSession *pSession, SSIComponent * pComponent, SSIRuntime * pRuntime ) { SubstItem *pItem = (SubstItem *)pComponent->getFirstAttr(); char achBuf[4096]; char * p; int len; int attr; while( pItem ) { attr = pItem->getSubType(); p = achBuf; len = 4096; switch( attr ) { case SSI_ECHOMSG: case SSI_ERRMSG: case SSI_TIMEFMT: RequestVars::appendSubst( pItem, pSession, p, len, 0, NULL ); if ( attr == SSI_ERRMSG ) pRuntime->getConfig()->setErrMsg( achBuf, p - achBuf ); else if ( attr == SSI_ECHOMSG ) pRuntime->getConfig()->setEchoMsg( achBuf, p - achBuf ); else pRuntime->getConfig()->setTimeFmt( achBuf, p - achBuf ); break; case SSI_SIZEFMT: if ( pItem->getType() == REF_STRING ) { const AutoStr2 * pStr = pItem->getStr(); if (( pStr )&&( pStr->c_str() )) { pRuntime->getConfig()->setSizeFmt( pStr->c_str(), pStr->len() ); } } break; } pItem = (SubstItem *) pItem->next(); } return 0; }
int SSIEngine::processSet(HttpSession *pSession, SSIComponent *pComponent) { SubstItem *pItem = (SubstItem *)pComponent->getFirstAttr(); const AutoStr2 *pVarName; char achBuf1[8192]; char *p; int len; int attr; while (pItem) { attr = pItem->getSubType(); if (attr == SSI_SET_VAR) { pVarName = pItem->getStr(); pItem = (SubstItem *) pItem->next(); if (!pItem) break; if (pItem->getSubType() != SSI_SET_VALUE) continue; p = achBuf1; len = 8192; len = RequestVars::appendSubst(pItem, pSession, p, len, 0, pSession->getReq()->getSSIRuntime()->getRegexResult(), pSession->getReq()->getSSIRuntime() ->getConfig()->getTimeFmt()->c_str()); RequestVars::setEnv(pSession, pVarName->c_str(), pVarName->len(), achBuf1, p - achBuf1); } pItem = (SubstItem *) pItem->next(); } return 0; }
SubstItem::SubstItem( const SubstItem & rhs ) : LinkedObj(), m_type( rhs.m_type ) { if ( rhs.m_value.m_pStr ) { switch( rhs.m_type ) { case REF_STRING: case REF_ENV: m_value.m_pStr = new AutoStr2( *rhs.m_value.m_pStr ); break; case REF_FORMAT_STR: m_value.m_pAny = new SubstFormat( *rhs.getFormatStr() ); default: m_value.m_index = rhs.m_value.m_index; break; } } else m_value.m_index = 0; }
int SSIEngine::processFileAttr(HttpSession *pSession, SSIComponent *pComponent) { SubstItem *pItem = (SubstItem *)pComponent->getFirstAttr(); if (!pItem) return 0; int len; int attr = pItem->getSubType(); char achBuf[4096]; char *p = achBuf; len = 4096; if ((attr != SSI_INC_FILE) && (attr != SSI_INC_VIRTUAL)) return 0; SSIRuntime *pRuntime = pSession->getReq()->getSSIRuntime(); RequestVars::appendSubst(pItem, pSession, p, len, 0, pRuntime->getRegexResult()); { if (achBuf[0] == 0) { len = snprintf(achBuf, 4096, "[an error occurred while processing this directive]\n"); pSession->appendDynBody(achBuf, len); return 0; } HttpReq *pReq = pSession->getReq(); const char *pURI ; const char *p1; if ((attr == SSI_INC_FILE) || (achBuf[0] != '/')) { pURI = pReq->getRealPath()->c_str(); p1 = pURI + pReq->getRealPath()->len(); while ((p1 > pReq->getRealPath()->c_str()) && p1[-1] != '/') --p1; } else { pURI = pReq->getDocRoot()->c_str(); p1 = pURI + pReq->getDocRoot()->len(); } int prefix_len = p1 - pURI; memmove(&achBuf[prefix_len], achBuf, p - achBuf); memmove(achBuf, pURI, prefix_len); p += prefix_len; } *p = 0; p = achBuf; struct stat st; if (ls_fio_stat(achBuf, &st) == -1) { pSession->appendDynBody("[error: stat() failed!\n", 23); return 0; } if (pComponent->getType() == SSIComponent::SSI_FSize) { long long size = st.st_size; len = snprintf(achBuf, 1024, "%lld", size); } else //SSIComponent::SSI_Flastmod { struct tm *tm; tm = localtime(&st.st_mtime); len = strftime(achBuf, 1024, pRuntime ->getConfig()->getTimeFmt()->c_str(), tm); } pSession->appendDynBody(achBuf, len); return 0; }