⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xslt.cpp

📁 mini http server,可以集成嵌入到程序中,实现简单的web功能
💻 CPP
📖 第 1 页 / 共 3 页
字号:

	// 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 + -