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

📄 isapi20.cpp

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

		/* ---
		Get file object
		--- */
		const char *pPath = (const char *)PIDB_lookup( pR, PIDBTYPE_STRING,
			KEY_INT_PATH, 0 );
		PIFInfo *pFInfo = HTTPCore_getCachedFile( pPath ); 
		if ( !pFInfo )
			{ return PIAPI_ERROR; };

		/* ---	
		This file must exist and be a regular file 
		--- */
		if ( !PIFInfo_exists( pFInfo ) ||
			!PIFInfo_isRegular( pFInfo ) )
			{
			HTTPCore_logError( &tPIHTTP, "ISAPI20: File with \
path '%s' does not \
exist or is not a regular file.", pPath );
			HTTPCore_releaseCachedFile( pFInfo );	
			return HTTPUtil_doHTTPError( &tPIHTTP, ST_INTERNALERROR );
			};

		PIDLL *pDLL = PIDLL_new( pPath );
		if ( !PIDLL_isLoaded( pDLL ) )
			{
			const char *pDesc = PIDLL_getErrorDescription( pDLL );
			HTTPCore_logError( &tPIHTTP, "ISAPI20: ISAPI DLL with \
path '%s' could not be loaded, error description is \
'%s'.", pPath, pDesc );
			HTTPCore_releaseCachedFile( pFInfo );	
			return HTTPUtil_doHTTPError( &tPIHTTP, ST_INTERNALERROR );
			};

		int iRet = DoISAPI( pDLL, pPath, &tPIHTTP );
		PIDLL_delete( pDLL );

		HTTPCore_releaseCachedFile( pFInfo );

		return iRet;
		};

	BOOL GetServerVariable( PIHTTP *pPIHTTP, LPSTR lpszVariableName,
		LPVOID lpvBuffer, LPDWORD lpdwSize, ISAPIContext *pContext )
		{
		if ( !lpszVariableName || !lpdwSize )
			{
			::SetLastError( ERROR_INVALID_PARAMETER );
			return FALSE;
			};

		/* ---
		Convert variable to upper case
		--- */
		PIString sTmp( lpszVariableName );
		sTmp.ConvertToUpperCase();

		Pi3Expression *pExpr = (Pi3Expression *)PIDB_lookup(pTypes, PIDBTYPE_OPAQUE,
			(const char *)sTmp, 0);

		if (pExpr)
			{
			int iWritten = Pi3Expression_write( pExpr, pPIHTTP, pContext, (char *)lpvBuffer,
				*lpdwSize );
			if ( iWritten==-1 )
				{
				*lpdwSize = 0;
				::SetLastError( ERROR_INVALID_INDEX );
				return 0;
				}

			/*
			** Skip empty variable fields, this allows an environment
			** variable to be added conditionally
			*/
			if ( iWritten>=0 )
				{
				if ( iWritten>=*lpdwSize )
					{
					*lpdwSize = iWritten;
					::SetLastError( ERROR_INSUFFICIENT_BUFFER );
					return 0;
					};
				((char *)lpvBuffer)[iWritten] = '\0';	
				*lpdwSize = iWritten;
				return 1;
				};
			}

		/* --- no variable found, try to find an extra header --- */
		if ( iExtraHeaders ) 
			{
			PIDB *pQ = pPIHTTP->pRequestDB;											
	
			/* --- loop over all RFC822 headers in request block --- */				
			PIDBIterator *pIter = PIDB_getIterator( pQ, PIDBTYPE_RFC822, 0, 0 );	
			if ( !pIter ) { return 0; }

			const char *pKey;													
			const char *pValue;
			for(; PIDBIterator_atValidElement( pIter ); PIDBIterator_next( pIter ) )
				{
				pValue = (const char *)PIDBIterator_current( pIter,	&pKey );
				assert( pKey && pValue );											

				if ( !pKey || !pValue ) { /* sanity */ continue; };

				if (checkIgnoreList(pKey)) continue;

				PIString sTest(sExtraHeadersPrefix);
				sTest.Concatenate(pKey);
				char *pBuf = (char *)(const char *)sTest;
				for( int i=0; i<sTest.Len(); i++ )							
					{																
					if ( isalnum( pBuf[i] ) )										
						{ pBuf[i]=toupper(pBuf[i]); }						
					else															
						{ pBuf[i]='_'; };		
					}

				if (!PIUtil_stricmp((const char *)sTest, (const char *)sTmp))
					{
					strncpy((char *)lpvBuffer, pValue, strlen(pValue));
					*lpdwSize = strlen(pValue);
					((char *)lpvBuffer)[*lpdwSize] = '\0';	
					return 1;
					}
				}
			PIDBIterator_delete( pIter );

			*(char *)lpvBuffer = '\0';
			*lpdwSize = 0;
			::SetLastError( ERROR_INVALID_INDEX );
			return 0;
			}
		
		::SetLastError( ERROR_INVALID_INDEX );
		*(char *)lpvBuffer = '\0';
		*lpdwSize = 0;
		return 0;
		};
};

/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
BOOL WINAPI fnGetServerVariable( HCONN hConn, LPSTR lpszVariableName,
	LPVOID lpvBuffer, LPDWORD lpdwSize )
{
	ISAPIContext *pContext = (ISAPIContext *)hConn;
	BOOL iRet = pContext->pISAPI20->GetServerVariable( pContext->pPIHTTP,
		lpszVariableName, lpvBuffer, lpdwSize, pContext );
	if ( HTTPCore_debugEnabled() )
		{
		HTTPCore_logDebug( DBG_MED, "ISAPI20: Return code<%d>, variable<%s>, \
value<%x>, size<%d>.",
			iRet, lpszVariableName ? lpszVariableName : "",
			(void *)lpvBuffer, lpdwSize ? *lpdwSize : 0 );
		};
	return iRet;
}

/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
BOOL WINAPI fnWriteClient( HCONN ConnID, LPVOID Buffer, LPDWORD	lpdwBytes,
	DWORD dwReserved )
{
	if ( !ConnID || !lpdwBytes || !Buffer )
		{
		::SetLastError( ERROR_INVALID_PARAMETER );
		return FALSE;
		};

	ISAPIContext *pContext = (ISAPIContext *)ConnID;
	int iWritten = PIIOBuffer_write( pContext->pPIHTTP->pBuffer,
		(char *)Buffer, *lpdwBytes, PIIOBUF_NONE );
	if ( iWritten==-1 )
		{
		/*
		** Socket must have been closed
		*/
		::SetLastError( ERROR_INVALID_HANDLE );
		return FALSE;
		};
	*lpdwBytes = iWritten;
	return TRUE;
}

/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
BOOL WINAPI fnReadClient( HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize )
{
	if ( !ConnID || !lpdwSize )
		{
		::SetLastError( ERROR_INVALID_PARAMETER );
		return FALSE;
		};

	ISAPIContext *pContext = (ISAPIContext *)ConnID;
	int iRet = PIIOBuffer_readToBuffer( pContext->pPIHTTP->pBuffer,
		(char *)lpvBuffer, *lpdwSize );
	if ( iRet>0 )
		{
		*lpdwSize = iRet;
		return TRUE;
		}
	else
		{
		return FALSE;
		};
}

/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
BOOL WINAPI fnServerSupportFunction( HCONN ConnID, DWORD dwHSERRequest,
	LPVOID lpvBuffer, LPDWORD lpdwSize, LPDWORD	lpdwDataType )
{
	if ( !ConnID )
		{
		::SetLastError( ERROR_INVALID_PARAMETER );
		return FALSE;
		};

	ISAPIContext *pContext = (ISAPIContext *)ConnID;

	if ( !pContext )
		{
		::SetLastError( ERROR_INVALID_PARAMETER );
		return FALSE;
		};

	PIHTTP *pPIHTTP = pContext->pPIHTTP;

	switch( dwHSERRequest )
		{
		case HSE_REQ_SEND_URL_REDIRECT_RESP:
			if ( !lpvBuffer )
				{
				::SetLastError( ERROR_INVALID_PARAMETER );
				return FALSE;
				};
			PIDB_replace( pPIHTTP->pResponseDB, PIDBTYPE_RFC822,
				KEY_HTTP_LOCATION, lpvBuffer, 0 );
			pPIHTTP->iStatus = ST_PERMANENTREDIRECT;
			HTTPCore_sendGeneralHeaders( pPIHTTP );
			HTTPCore_sendEntityHeaders( pPIHTTP, pPIHTTP->pResponseDB );
			pContext->iRc = PIAPI_COMPLETED;
			return TRUE;

		case HSE_REQ_SEND_URL:
			if ( !lpvBuffer )
				{
				::SetLastError( ERROR_INVALID_PARAMETER );
				return FALSE;
				};
			pContext->iRc = HTTPUtil_doHTTPError( pPIHTTP, ST_PERMANENTREDIRECT);
			pPIHTTP->iStatus = ST_PERMANENTREDIRECT;
			PIDB_replace( pPIHTTP->pResponseDB, PIDBTYPE_STRING,
				KEY_INT_PATH, lpvBuffer, 0 );
			return TRUE;

		case HSE_REQ_SEND_RESPONSE_HEADER:
			{
			/*
			** Assume Content-Length could not be set, disable
			** keep open
			*/
			PIDB_replace( pPIHTTP->pConnectionDB, PIDBTYPE_OPAQUE,
				KEY_INT_KEEPOPEN, 0, 0 );
			int iStatus = lpvBuffer ? atoi( (char *)lpvBuffer ) : 200;	
			pPIHTTP->iStatus = iStatus;
			pContext->dwHttpStatusCode = iStatus;
			pContext->iRc = PIAPI_COMPLETED;

			/*
			** Send server specific headers
			*/
			HTTPCore_sendGeneralHeaders( pPIHTTP );
			if ( !PIHTTP_isChild( pPIHTTP ) && lpdwSize && *lpdwSize && lpdwDataType )
				{
				// workaround for ambigous Delphi behaviour
				if ( strlen((const char *)lpdwDataType) < *lpdwSize ) {
					*lpdwSize = strlen((const char *)lpdwDataType);
				};
				PIIOBuffer_write( pPIHTTP->pBuffer, (const char *)lpdwDataType,
					*lpdwSize, PIIOBUF_NONE );
				};
			};
			return TRUE;

		case HSE_REQ_DONE_WITH_SESSION:
			pContext->iRc = *(LPDWORD)lpvBuffer;
			if ((pContext->Finish() == PIAPI_ERROR) && HTTPCore_debugEnabled())
				{
				/*
				** The unlock of the semaphore failed somehow
				*/
				HTTPCore_logError( pPIHTTP, "ISAPI20: Unlock semaphore failed \
with error code %d", PIPlatform_getLastError());
				};
			return TRUE;

		default:
			/*
			** Unhandled/unknown function code
			*/
			if ( HTTPCore_debugEnabled() )
				{
				HTTPCore_logError( pPIHTTP, "ISAPI20: Server support function \
called with unknown function code %d", dwHSERRequest );
				};
		};
	return FALSE;
}

#endif /* WIN32 */

/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int ISAPI20_constructor( PIObject *pObj,
	int iArgc, const char *ppArgv[] )
{
#if WIN32
	return HandlerBaseISAPI_constructor( pObj, PI_NEW( ISAPI20( pObj,
		iArgc, ppArgv ) ) );
#elif POSIX
	(void)pObj;
	(void)iArgc;
	(void)ppArgv;
	return PIAPI_COMPLETED;
#endif
}


/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int ISAPI20_destructor( PIObject *pObj, int,
	const char *[] )
{
#if WIN32
	delete (ISAPI20 *)PIObject_getUserData( pObj );
#endif
	return PIAPI_COMPLETED;
}


#if 0
/*___+++CNF_BEGIN+++___*/
	<Class>
		Name ISAPI20Class
		Type LogicExtension
		Library ISAPI
		OnClassLoad HandlerBaseISAPI_onClassLoad
		Constructor ISAPI20_constructor
		CopyConstructor HandlerBaseISAPI_copyConstructor
		Destructor ISAPI20_destructor
		Execute HandlerBaseISAPI_execute
	</Class>

	<Object>
		Name ISAPI20
		Class ISAPI20Class
	</Object>

/*___+++CNF_END+++___*/
#endif

⌨️ 快捷键说明

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