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

📄 sendssi.cpp

📁 mini http server,可以集成嵌入到程序中,实现简单的web功能
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		not 'internal/x-cgi'.
		--- */
		const char *pContentType = (const char *)PIDB_lookup(
			pChildHTTP->pResponseDB, PIDBTYPE_RFC822,
			KEY_HTTP_CONTENTTYPE, 0 );
		int iIsExec = (!pContentType ||
			!PIUtil_stricmp( pContentType, TYPE_MAGIC_CGI ) );
		if ( ( iIsExec && !iExec ) ||
			( !iIsExec && iExec ) )
			{
			PIHTTP_delete( pChildHTTP );
			return 0;
			};

		/* --- handle this request? --- */
		if ( iDoHandle )
			{
			/* --- handle this request --- */
			iRet = HTTPCore_dispatch( pChildHTTP, PH_HANDLE, PH_HANDLE );
			PIHTTP_delete( pChildHTTP );
			return iRet==PIAPI_COMPLETED ? 1 : 0;
			}
		else
			{
			/* --- get mapped path --- */
			const char *pPath = (const char *)PIDB_lookup(
				pChildHTTP->pResponseDB, PIDBTYPE_STRING,
				KEY_INT_PATH, 0 );

			assert( ppFInfo );
			if ( !ppFInfo )
				{ return 0; };
			*ppFInfo = HTTPCore_getCachedFile( pPath ); 
			PIHTTP_delete( pChildHTTP );
			return 1;
			};
		};

	/* --- 'config' directive --- */
	static int f_config( SendSSI &/* tThis */, PIHTTP &tPIHTTP,
			const char *pVar, int iVarLen, const char *pVal, int iValLen,
			SSIParam &tParam )
		{
		if ( !pVar )
			{}
		else if ( iVarLen==7 && !PIUtil_strncmpi( pVar, "timefmt", 7 ) )
			{
			PIString sTmp( pVal, iValLen );
			tParam.tConfig.sTimeFmt = sTmp;
			return 1;
			}
		else if ( iVarLen==7 && !PIUtil_strncmpi( pVar, "sizefmt", 7 ) )
			{
			PIString sTmp( pVal, iValLen );
			tParam.tConfig.sSizeFmt = sTmp;
			return 1;
			}
		else if ( iVarLen==6 && !PIUtil_strncmpi( pVar, "errmsg", 6 ) )
			{
			PIString sTmp( pVal, iValLen );
			tParam.tConfig.sErrMsg = sTmp;
			return 1;
			};

		/* --- error, no variable, or unknown variable --- */
		PIIOBuffer_write(
			tPIHTTP.pBuffer, 
			tParam.tConfig.sErrMsg,
			tParam.tConfig.sErrMsg.Len(),
			PIIOBUF_NONE );

		return 0;
		};

	/* --- 'echo' directive --- */
	static int f_echo( SendSSI &tThis, PIHTTP &tPIHTTP, const char *pVar,
			int iVarLen, const char *pVal, int iValLen,
			SSIParam &tParam )
		{
		if ( !pVar || iVarLen!=3 || PIUtil_strncmpi( pVar, "var", 3 ) )
			{
			PIIOBuffer_write(
				tPIHTTP.pBuffer, 
				tParam.tConfig.sErrMsg,
				tParam.tConfig.sErrMsg.Len(),
				PIIOBUF_NONE );
			return 0;
			};

		Pi3Expression *pExpr = 0;
		if ( pVal )
			{
			PIString sTmp( pVal, iValLen );
			pExpr = (Pi3Expression *)PIDB_lookup( tThis.pVariables,
				PIDBTYPE_OPAQUE, sTmp, 0 );
			};

		if ( !pExpr )
			{
			/* --- invalid variable --- */
			PIIOBuffer_write(
				tPIHTTP.pBuffer, 
				tParam.tConfig.sErrMsg,
				tParam.tConfig.sErrMsg.Len(),
				PIIOBUF_NONE );
			
			return 0;
			};

		/* --- write out variable --- */
		enum { BUF_SIZE=1024 };
		char szBuf[ BUF_SIZE ];
		int iLen = Pi3Expression_write( pExpr, &tPIHTTP, &tParam, szBuf, 
			BUF_SIZE );
		if ( iLen>BUF_SIZE )
			{
			/* --- buffer was not big enough, try again --- */
			char *pBuf = (char *)PIHTTP_allocMem( &tPIHTTP, iLen );
			Pi3Expression_write( pExpr, &tPIHTTP, &tParam, pBuf, iLen );
			PIIOBuffer_write(
				tPIHTTP.pBuffer, 
				pBuf,
				iLen,
				PIIOBUF_NONE );
			}
		else
			{
			PIIOBuffer_write(
				tPIHTTP.pBuffer, 
				szBuf,
				iLen,
				PIIOBUF_NONE );
			};
	
		return 1;
		};

	/* --- 'flastmod' last modification time of a file --- */
	static int f_flastmod( SendSSI &tThis, PIHTTP &tPIHTTP,
			const char *pVar, int iVarLen, const char *pVal, int iValLen,
			SSIParam &tParam )
		{
		enum { ERROR=-1, FILE=0, VIRTUAL=1 } iType = ERROR;
		if ( !pVar )
			{}
		else if ( iVarLen==7 && !PIUtil_strncmpi( pVar, "virtual", 7 ) )
			{ iType = VIRTUAL; }
		else if ( iVarLen==4 && !PIUtil_strncmpi( pVar, "file", 4 ) )
			{ iType = FILE; };

		if ( iType!=ERROR )
			{
			PIFInfo *pFile;
			if ( tThis.GetSSIFile( tPIHTTP, pVal, iValLen, iType,
				tParam, 0, 0, &pFile  ) )
				{
				enum { BUF_SIZE=1024 };
				char szBuf[ BUF_SIZE ];
				time_t tT = PIFInfo_getLastModified( pFile );
				HTTPCore_releaseCachedFile( pFile );
				int iLen = Internal_GMTTime( &tPIHTTP, tParam.tConfig, tT,
					szBuf, BUF_SIZE );
				if ( iLen>BUF_SIZE )
					{
					assert( 0 );		/* should never really happen */
					iLen = BUF_SIZE;
					};
				PIIOBuffer_write(
					tPIHTTP.pBuffer, 
					szBuf,
					iLen,
					PIIOBUF_NONE );
				return 1;
				};
			};

		/* --- error, no variable, or unknown variable --- */
		PIIOBuffer_write(
			tPIHTTP.pBuffer, 
			tParam.tConfig.sErrMsg,
			tParam.tConfig.sErrMsg.Len(),
			PIIOBUF_NONE );

		return 0;
		};

	/* --- 'fsize' size of a file --- */
	static int f_fsize( SendSSI &tThis, PIHTTP &tPIHTTP, const char *pVar,
			int iVarLen, const char *pVal, int iValLen,
			SSIParam &tParam )
		{
		enum { ERROR=-1, FILE=0, VIRTUAL=1 } iType = ERROR;
		if ( !pVar )
			{}
		else if ( iVarLen==7 && !PIUtil_strncmpi( pVar, "virtual", 7 ) )
			{ iType = VIRTUAL; }
		else if ( iVarLen==4 && !PIUtil_strncmpi( pVar, "file", 4 ) )
			{ iType = FILE; };

		if ( iType!=ERROR )
			{
			PIFInfo *pFile;
			if ( tThis.GetSSIFile( tPIHTTP, pVal, iValLen, iType,
				tParam, 0, 0, &pFile ) )
				{
				enum { BUF_SIZE=1024 };
				char szBuf[ BUF_SIZE ];
				sprintf( szBuf, "%lu", PIFInfo_getSize( pFile ) );
				HTTPCore_releaseCachedFile( pFile );
				int iLen = strlen( szBuf );
				PIIOBuffer_write(
					tPIHTTP.pBuffer, 
					szBuf,
					iLen,
					PIIOBUF_NONE );
				return 1;
				};
			};

		/* --- error, no variable, or unknown variable --- */
		PIIOBuffer_write(
			tPIHTTP.pBuffer, 
			tParam.tConfig.sErrMsg,
			tParam.tConfig.sErrMsg.Len(),
			PIIOBUF_NONE );

		return 0;
		};

	/* --- 'include' include a file --- */
	static int f_include( SendSSI &tThis, PIHTTP &tPIHTTP,
			const char *pVar, int iVarLen, const char *pVal, int iValLen,
			SSIParam &tParam )
		{
		enum { ERROR=-1, FILE=0, VIRTUAL=1 } iType = ERROR;
		if ( !pVar )
			{}
		else if ( iVarLen==7 && !PIUtil_strncmpi( pVar, "virtual", 7 ) )
			{ iType = VIRTUAL; }
		else if ( iVarLen==4 && !PIUtil_strncmpi( pVar, "file", 4 ) )
			{ iType = FILE; };

		/* ---
		Include file
		--- */
		if ( iType!=ERROR )
			{
			if ( tThis.GetSSIFile( tPIHTTP, pVal, iValLen, iType,
				tParam, 0, 1, 0 ) )
				{ return 1; };
			};

		/* --- error, no variable, or unknown variable --- */
		PIIOBuffer_write(
			tPIHTTP.pBuffer, 
			tParam.tConfig.sErrMsg,
			tParam.tConfig.sErrMsg.Len(),
			PIIOBUF_NONE );

		return 0;
		};

	/* --- 'exec' execute a cgi program --- */
	static int f_exec( SendSSI &tThis, PIHTTP &tPIHTTP,
			const char *pVar, int iVarLen, const char *pVal, int iValLen,
			SSIParam &tParam )
		{
		enum { ERROR=-1, FILE=0, VIRTUAL=1 } iType = ERROR;
		if ( !pVar )
			{}
		else if ( iVarLen==7 && !PIUtil_strncmpi( pVar, "virtual", 7 ) )
			{ iType = VIRTUAL; }
		else if ( iVarLen==4 && !PIUtil_strncmpi( pVar, "file", 4 ) )
			{ iType = FILE; };

		/* ---
		Exec file
		--- */
		if ( iType!=ERROR && tThis.iAllowExec )
			{
			/* ---
			Do the stuff
			--- */
			if ( tThis.GetSSIFile( tPIHTTP, pVal, iValLen, iType,
				tParam, 1, 1, 0 ) )
				{ return 1; };
			};

		/* --- error, no variable, or unknown variable --- */
		PIIOBuffer_write(
			tPIHTTP.pBuffer, 
			tParam.tConfig.sErrMsg,
			tParam.tConfig.sErrMsg.Len(),
			PIIOBUF_NONE );

		return 0;
		};

	/* --- 'pi3extn' directive (the obligatory proprietory extension) --- */
	static int f_pi3ext( SendSSI &/* tThis */, PIHTTP &tPIHTTP,
			const char *pVar, int iVarLen, const char *pVal, int iValLen,
			SSIParam &tParam )
		{
		if ( !pVar )
			{}
		else if ( iVarLen==4 && !PIUtil_strncmpi( pVar, "expr", 4 ) )
			{
			PIString sTmp( pVal, iValLen );
			Pi3String *pError = Pi3String_new( 0 );
			Pi3Expression *pTmpExpr = Pi3Expression_new( sTmp, aFunctions,
				pError );
			Pi3String_delete( pError );
			if ( pTmpExpr )
				{
				enum { BUF_SIZE=1024 };
				char szBuf[ BUF_SIZE ];
				int iLen = Pi3Expression_write( pTmpExpr, &tPIHTTP, 0, szBuf,
					BUF_SIZE );
				if ( iLen>BUF_SIZE )
					{
					/* --- buffer was not big enough, try again --- */
					char *pBuf = (char *)PIHTTP_allocMem( &tPIHTTP, iLen );
					Pi3Expression_write( pTmpExpr, &tPIHTTP, 0, pBuf, iLen );
					PIIOBuffer_write( tPIHTTP.pBuffer, pBuf, iLen,
						PIIOBUF_NONE );
					}
				else
					{
					PIIOBuffer_write( tPIHTTP.pBuffer, szBuf, iLen,
						PIIOBUF_NONE );
					};
				Pi3Expression_delete( pTmpExpr );
				return 1;
				};
			};

		/* --- some error --- */
		PIIOBuffer_write(
			tPIHTTP.pBuffer, 
			tParam.tConfig.sErrMsg,
			tParam.tConfig.sErrMsg.Len(),
			PIIOBUF_NONE );

		return 0;
		};

protected:
	/*___ +++++++++++++++++++++++++++++++++++++++++++++++++ ___ *

				Load an expression or condition

	 *___ +++++++++++++++++++++++++++++++++++++++++++++++++ ___ */
	int LoadExpression( const char *pName, Pi3Expression **ppExpression,
		FnPi3Write *pFunctions, const char *pValue, PIOStrStream &os )	
		{
		assert( ppExpression );
		Pi3Expression *pExpression = *ppExpression;
		if ( pExpression )
			{
			os << "'" << pName << "' may only be specified once." << ends;
			CONFIG_ERR( Object(), os.str() );
			return 0;
			};
		Pi3String *pError = Pi3String_new( 0 );
		pExpression = Pi3Expression_new( pValue, pFunctions, pError );
		if ( !pExpression )
			{
			os << "Error parsing expression: " <<
				Pi3String_getPtr( pError ) << ends;
			CONFIG_ERR( Object(), os.str() );
			Pi3Expression_delete( pExpression );
			Pi3String_delete( pError );
			return 0;
			};
		Pi3String_delete( pError );
		*ppExpression = pExpression;
		return 1;
		};

	int Parameter( const char *pVariable, const char *pValue,
		const char *pWhere )
		{
		assert( pVariable && pValue );
		PIOStrStream os;
		os << pWhere << "SendSSI: ";
		if ( !PIUtil_stricmp( KEY_CONF_EXEC, pVariable ) )
			{
			if ( !PIUtil_stricmp( pValue, KEY_VALUE_YES ) )
				{ iAllowExec = 1; };
			}
		else if ( !PIUtil_stricmp( KEY_CONF_HEADERPATTERN, pVariable ) )
			{
			if ( !LoadExpression( KEY_CONF_HEADERPATTERN, &pHeaderPattern,
				0, pValue, os ) )
				{ return 0; };
			assert( pHeaderPattern );
			}
		else if ( !PIUtil_stricmp( KEY_CONF_FOOTERPATTERN, pVariable ) )
			{
			if ( !LoadExpression( KEY_CONF_FOOTERPATTERN, &pFooterPattern,
				0, pValue, os ) )
				{ return 0; };
			assert( pFooterPattern );
			}
		else if ( !PIUtil_stricmp( KEY_CONF_EXECFILEFIXUP, pVariable ) )
			{
			if ( !LoadExpression( KEY_CONF_EXECFILEFIXUP, &pExecFileFixup,
				0, pValue, os ) )
				{ return 0; };
			assert( pExecFileFixup );
			}
		else
			{
			os << "Unknown directive '" << pVariable <<
				"'" << ends;
			CONFIG_ERR( Object(), os.str() );
			return 0;
			};

		return 1;
		};

public:
	SendSSI( PIObject *pObject, int iArgc, const char *ppArgv[] )
	:
		HandlerBaseHTTP( pObject ),
		pFunctions( PIDB_new( 0, "SSI Functions" ) ),
		pVariables( PIDB_new( 0, "SSI Variables" ) ),
		iAllowExec( 0 ),
		pHeaderPattern( 0 ),
		pFooterPattern( 0 ),
		pExecFileFixup( 0 )
		{
		ReadParameters( iArgc, ppArgv );

		if ( !IsOK() )
			{ return; };

		/* --- insert SSI directives --- */
		PIDB_add( pFunctions, PIDBTYPE_OPAQUE, "CONFIG", (void *)f_config, 0 );
		PIDB_add( pFunctions, PIDBTYPE_OPAQUE, "ECHO", (void *)f_echo, 0 );
		PIDB_add( pFunctions, PIDBTYPE_OPAQUE, "FLASTMOD", (void *)f_flastmod, 0 );
		PIDB_add( pFunctions, PIDBTYPE_OPAQUE, "FSIZE", (void *)f_fsize, 0 );
		PIDB_add( pFunctions, PIDBTYPE_OPAQUE, "INCLUDE", (void *)f_include, 0 );
		PIDB_add( pFunctions, PIDBTYPE_OPAQUE, "EXEC", (void *)f_exec, 0 );
		PIDB_add( pFunctions, PIDBTYPE_OPAQUE, "PI3EXT", (void *)f_pi3ext, 0 );

		/* ---
		insert SSI variables

		Each variable is mapped to a Pi3Expression. Not the fastest, but
		pretty convienient.

		--- */
		Pi3String *pDummy = Pi3String_new( 0 );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -