📄 xslt.cpp
字号:
// end stream
if (ctx->state == STATE_ENDSTREAM) {
strcpy(buffer, END_FORM);
ctx->state = STATE_END;
return strlen(END_FORM);
}
int iRet = len < ctx->clength - ctx->read ? len : ctx->clength - ctx->read;
const char *inbuf = PIIOBuffer_read( ctx->iobuf, &iRet );
if (iRet) {
char *outbuf = buffer;
// 1st form field
if (!ctx->read) {
strcpy(outbuf, START_FIELD_A);
outbuf += strlen(START_FIELD_A);
}
for (int i=0;i<iRet;i++) {
if ( inbuf[i] == '=' ) {
strcpy(outbuf, START_FIELD_B);
outbuf += strlen(START_FIELD_B);
continue;
};
// next form field
if ( inbuf[i] == '&') {
strcpy(outbuf, END_FIELD);
outbuf += strlen(END_FIELD);
strcpy(outbuf, START_FIELD_A);
outbuf += strlen(START_FIELD_A);
} else {
if (inbuf[i] == '+')
{
*(outbuf++) = ' ';
}
else if (inbuf[i] == '%')
{
if ( ((i+1)<iRet) && inbuf[i+1]=='%' )
{ *(outbuf++) = inbuf[i]; i++; }
else if ( (i+2)<iRet )
{
char szBuf[3];
strncpy( szBuf, &(inbuf[i+1]), 2 );
szBuf[2]='\0';
*(outbuf++) = (char)strtol( szBuf, (char **)0, 16 );
i+=2;
};
}
else
{
*(outbuf++) = inbuf[i];
}
}
}
ctx->read += iRet;
// last form field
if (ctx->read == ctx->clength) {
strcpy(outbuf, END_FIELD);
outbuf += strlen(END_FIELD);
ctx->state = STATE_ENDSTREAM;
}
return outbuf - buffer;
};
return 0;
}
/*____________________________________________________________________________*\
*
Description: Parser function for POST'ed input of type
application/x-www-form-urlencoded
\*____________________________________________________________________________*/
xmlDocPtr
xmlIOParseFormEntity( void *ioctx, xmlCharEncoding enc ) {
xmlDocPtr ret;
xmlParserCtxtPtr ctxt =
xmlCreateIOParserCtxt(
NULL,
NULL,
xmlReadFormCB,
NULL,
ioctx,
enc
);
if (!ctxt) return(NULL);
xmlParseExtParsedEnt(ctxt);
if (ctxt->wellFormed)
ret = ctxt->myDoc;
else {
ret = NULL;
xmlFreeDoc(ctxt->myDoc);
ctxt->myDoc = NULL;
}
xmlFreeParserCtxt(ctxt);
return(ret);
}
/*____________________________________________________________________________*\
*
Description: Parser function for POST'ed input of type text/plain
\*____________________________________________________________________________*/
xmlDocPtr
xmlIOParsePlainEntity( void *ioctx, xmlCharEncoding enc ) {
xmlDocPtr ret;
xmlParserCtxtPtr ctxt =
xmlCreateIOParserCtxt(
NULL,
NULL,
xmlReadPlainCB,
NULL,
ioctx,
enc
);
if (!ctxt) return(NULL);
xmlParseExtParsedEnt(ctxt);
if (ctxt->wellFormed)
ret = ctxt->myDoc;
else {
ret = NULL;
xmlFreeDoc(ctxt->myDoc);
ctxt->myDoc = NULL;
}
xmlFreeParserCtxt(ctxt);
return(ret);
}
/*____________________________________________________________________________*\
*
Description: Parser function for HTML file input
\*____________________________________________________________________________*/
xmlDocPtr
xmlPi3ParseHtmlFile( const char *filename, PIHTTP *pPIHTTP) {
xmlDocPtr ret;
docbParserCtxtPtr c =
htmlCreateFileParserCtxt(filename, (const char *)XML_CHAR_ENCODING_NONE);
if (c == NULL) return NULL;
c->_private = pPIHTTP;
htmlParseDocument(c);
if (c->wellFormed) {
ret = c->myDoc;
ret->_private = (void *)c->valid;
} else {
ret = NULL;
xmlFreeDoc(c->myDoc);
c->myDoc = NULL;
}
xmlFreeParserCtxt(c);
return ret;
}
/*____________________________________________________________________________*\
*
Description: Parser function for Docbook SGML file input
\*____________________________________________________________________________*/
xmlDocPtr
xmlPi3ParseDocbookFile( const char *filename, PIHTTP *pPIHTTP) {
xmlDocPtr ret;
docbParserCtxtPtr c =
docbCreateFileParserCtxt(filename, (const char *)XML_CHAR_ENCODING_NONE);
if (c == NULL) return NULL;
c->_private = pPIHTTP;
docbParseDocument(c);
if (c->wellFormed) {
ret = c->myDoc;
ret->_private = (void *)c->valid;
} else {
ret = NULL;
xmlFreeDoc(c->myDoc);
c->myDoc = NULL;
}
xmlFreeParserCtxt(c);
return ret;
}
/*____________________________________________________________________________*\
*
Description: Parser function for XML file input
\*____________________________________________________________________________*/
xmlDocPtr
xmlPi3ParseXmlFile( const char *filename, PIHTTP *pPIHTTP) {
xmlDocPtr ret;
xmlParserCtxtPtr c =
xmlCreateFileParserCtxt(filename);
if (c == NULL) return NULL;
c->_private = pPIHTTP;
xmlParseDocument(c);
if (c->wellFormed) {
ret = c->myDoc;
ret->_private = (void *)c->valid;
} else {
ret = NULL;
xmlFreeDoc(c->myDoc);
c->myDoc = NULL;
}
xmlFreeParserCtxt(c);
return ret;
}
/*____________________________________________________________________________*\
*
Description: Callback hook to write output data to client
\*____________________________________________________________________________*/
static int xmlWriteCB (void * context, const char * buffer, int len) {
return PIIOBuffer_write((PIIOBuffer *)context, buffer, len,
(int)PIIOBuffer_getUserData((PIIOBuffer *)context) );
}
/*____________________________________________________________________________*\
*
Description: Callback hook to flush output data to client
\*____________________________________________________________________________*/
static int xmlOutCloseCB (void * context) {
return PIIOBuffer_flush((PIIOBuffer *)context);
}
/*____________________________________________________________________________*\
*
Description: Callback hook to write error to client
\*____________________________________________________________________________*/
static void xmlErrorCB (void * context, const char * msg, ...) {
enum { BUF_SIZE=1024 };
char szBuf[BUF_SIZE+1];
va_list tvList;
va_start( tvList, msg );
#if WIN32
_vsnprintf( &(szBuf[0]), BUF_SIZE, msg, tvList );
#else
vsnprintf( &(szBuf[0]), BUF_SIZE, msg, tvList );
#endif
va_end( tvList );
if (szBuf[strlen(&(szBuf[0]))-1] == 10)
szBuf[strlen(&(szBuf[0]))-1] = 0;
HTTPCore_logError( (PIHTTP *)context, &(szBuf[0]) );
}
/*____________________________________________________________________________*\
*
Description: Callback hook to write data to debug log
\*____________________________________________________________________________*/
static void xmlDebugCB (void * context, const char * msg, ...) {
enum { BUF_SIZE=1024 };
char szBuf[BUF_SIZE+1];
va_list tvList;
va_start( tvList, msg );
#if WIN32
_vsnprintf( &(szBuf[0]), BUF_SIZE, msg, tvList );
#else
vsnprintf( &(szBuf[0]), BUF_SIZE, msg, tvList );
#endif
va_end( tvList );
if (szBuf[strlen(&(szBuf[0]))-1] == 10)
szBuf[strlen(&(szBuf[0]))-1] = 0;
HTTPCore_logDebug( DBG_MED, &(szBuf[0]) );
}
/*____________________________________________________________________________*\
*
Description: Helper function to create a URI from given path using escaping
\*____________________________________________________________________________*/
static PIString getFileURI(const char *pPath) {
if (!pPath) return NULL;
PIString sURI = pPath;
char *pPtr = (char *)(const char *)sURI;
while (strchr(pPtr, '\\'))
{
pPtr[strchr(pPtr,'\\')-pPtr] = '/';
}
xmlChar *pURI = xmlURIEscape((const xmlChar *)pPtr);
sURI = "file://";
if (pPath[0] != '/') sURI.Concatenate('/');
sURI.Concatenate((char *)pURI);
return sURI;
}
/*____________________________________________________________________________*\
*
Description: Static storage for origin registered entity loader function
\*____________________________________________________________________________*/
static xmlExternalEntityLoader OriginEntityLoader = 0;
/*____________________________________________________________________________*\
*
Description: Customized entity loader, which takes care, that external entities
URI's don't leave the webroot of the current HTTP connection
\*____________________________________________________________________________*/
static xmlParserInputPtr xmlEntityLoader(
const char *URL,
const char *ID,
xmlParserCtxtPtr context
)
{
if (!URL) return NULL;
if (!strncmp(URL, "http://", 7))
return OriginEntityLoader( URL, ID, context );
if (!strncmp(URL, "ftp://", 6))
return OriginEntityLoader( URL, ID, context );
PIHTTP *pPIHTTP = (PIHTTP *)context->_private;
if ( pPIHTTP ) {
/* --- make sub request context --- */
PIHTTP *pChildHTTP = PIHTTP_newChild( pPIHTTP );
// Someone has mapped the URL already
if (!strncmp(URL, "file://", 7)) {
PIDB_replace( pChildHTTP->pResponseDB, PIDBTYPE_STRING,
KEY_INT_PATH, (void *)"/", 0 );
} else {
PIDB_replace( pChildHTTP->pResponseDB, PIDBTYPE_STRING,
KEY_INT_PATH, (void *)URL, 0 );
}
/* --- dispatch the sub request across the mapping phase --- */
int iRet = HTTPCore_dispatch( pChildHTTP, PH_MAPPING, PH_MAPPING );
/* --- copy the childs script name to variable script name --- */
if ( iRet != PIAPI_COMPLETED ) {
PIHTTP_delete( pChildHTTP );
return NULL;
};
char *pPath = (char *)PIDB_lookup( pChildHTTP->pResponseDB,
PIDBTYPE_STRING, KEY_INT_PATH, 0 );
PIHTTP_delete( pChildHTTP );
if (!pPath) return NULL;
while (strchr(pPath, '\\'))
{
pPath[strchr(pPath,'\\')-pPath] = '/';
}
#if WIN32
// assume leading slash before the drive letter
int offset = (URL[7]== '/') ? 8 : 7;
#else
int offset = 7;
#endif
// check, if the URI is a subpath of the WebRoot
return strncmp( xmlURIUnescapeString(URL, 0, NULL) + offset,
pPath, strlen(pPath)) ? NULL : OriginEntityLoader( URL, ID, context );
#undef OFFSET
} else {
// assume, we're not in a web server request
return OriginEntityLoader( URL, ID, context );
}
}
/*____________________________________________________________________________*\
*
Class: XSLT
Description: The XSLT handler class
\*____________________________________________________________________________*/
class XSLT : public HandlerBaseXSLT
{
private:
/* ---
Configuration data
--- */
PIDB *pTypes; /* DB for variable types */
PIString sExtraHeadersPrefix; /* Extra Header for environment values, */
/* by default "HTTP_" */
int iExtraHeaders; /* whether or not to send extra headers */
DblList lIgnoreHeaders; /* extra headers to ignore */
xsltStylesheetPtr default_style;
int iOptions;
int iParams;
PIString sContentType;
inline int checkIgnoreList(const char *pKey)
{
/* --- exclude the variables in lIgnoreHeaders --- */
const char *pExclude;
for( DblListIterator l( lIgnoreHeaders ); !l.BadIndex(); l++ )
{
pExclude = (const char *)l.Current();
if (!PIUtil_stricmp(pKey, pExclude))
{
return 1;
}
};
return 0;
}
protected:
int Parameter( const char *pVariable, const char *pValue,
const char *pWhere )
{
assert( pVariable && pValue );
PIOStrStream os;
os << pWhere << "XSLT: ";
if ( !PIUtil_stricmp( KEY_CONF_DEFAULTSTYLESHEET, pVariable ) )
{
default_style =
xsltParseStylesheetFile((const xmlChar *)(const char *)DeQuote( pValue ));
}
else if ( !PIUtil_stricmp( KEY_CONF_OPTIONS, pVariable ) )
{
/* ---
Split the options up by the bar ('|') character and then
strip trailing and leading whitespace from option before
attempting to match it.
--- */
StringTokenizer tTokens( pValue, "|" );
for(int i=0; i<tTokens.NumTokens(); i++)
{
const char *pToken = tTokens.GetToken( i );
/* --- skip leading whitespace --- */
for( ; *pToken && (isspace(*pToken)); pToken++ );
/* ---
include only to first whitespace trailing whitespace
--- */
int j=0;
for( ; pToken[j] && !(isspace(pToken[j])); j++ );
/* ---
j now contains the length of the first word in pToken
--- */
/* ---
cycle through the list of available flags
comparing them with this one
--- */
int i=0;
for( ; aFlagMap[i].pName; i++ )
{
if ( !PIUtil_strncmpi( aFlagMap[i].pName, pToken, j ) )
{ break; };
};
if ( !aFlagMap[i].pName )
{
/* --- flag not found --- */
PIString sTmp( pToken, j );
os << "Unknown option flag '" << sTmp << "'." << ends;
CONFIG_ERR( Object(), os.str() );
return 0;
};
iOptions |= aFlagMap[i].iFlag;
}; /* --- loop over tokens seperated by '|' --- */
}
else if ( !PIUtil_stricmp( KEY_CONF_VARIABLE, pVariable ) )
{
if (iParams < MAX_PARAMETERS - 1)
{
const char *pK;
const char *pV;
StringTokenizer tTokens( (const char *)DeQuote(pValue), "=" );
if (tTokens.NumTokens() < 2)
{
os << "Invalid Variable '" << pValue <<
"'" << ends;
CONFIG_ERR( Object(), os.str() );
return 0;
}
pK = tTokens.GetToken( 0 );
pV = tTokens.GetToken( 1 );
Pi3String *pError = Pi3String_new( 0 );
Pi3Expression *pExpr = Pi3Expression_new( pV, NULL, pError );
if ( !pExpr )
{
os << Pi3String_getPtr( pError ) << ends;
Pi3String_delete( pError );
CONFIG_ERR( Object(), os.str() );
return 0;
};
Pi3String_delete( pError );
PIDB_add( pTypes, PIDBTYPE_OPAQUE, pK, (void *)pExpr, 0 );
}
else
{
os << "Too much parameters" << ends;
CONFIG_ERR( Object(), os.str() );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -