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

📄 dispatch.cpp

📁 mini http server,可以集成嵌入到程序中,实现简单的web功能
💻 CPP
📖 第 1 页 / 共 2 页
字号:
\*____________________________________________________________________________*/
class Dispatcher
{
private:
	PIObject *pObject;
	PIObject *pDefaultHost;
	bool bOK;
	int iKeepOpen;
	int iKeepOpenCount;
	int iKeepOpenTimeout;
	const char *pPort;
	
	/* ---
	Fast keys
	--- */
	const char *pFKRecvTimeout;
	const char *pFKKeepOpen;
	const char *pFKPort;
	const char *pFKKeySize;	
public:
	Dispatcher( PIObject *pTheObject, int, const char *[] )
	:
		pObject( pTheObject ),
		pDefaultHost( 0 ),
		bOK( false ),
		iKeepOpen( 1 ),
		iKeepOpenCount( 100 ),
		iKeepOpenTimeout( 5 ),
		pPort( 0 ),
		pFKRecvTimeout(
			PIDB_getFastKey( KEY_INT_RECVTIMEOUT, PIDBTYPE_OPAQUE ) ),
		pFKKeepOpen( PIDB_getFastKey( KEY_INT_KEEPOPEN, PIDBTYPE_OPAQUE ) ),
		pFKPort( PIDB_getFastKey( KEY_INT_SERVERPORT, PIDBTYPE_RFC822 ) ),
		pFKKeySize( PIDB_getFastKey( KEY_HTTPS_KEYSIZE, PIDBTYPE_STRING ) )
		{
		assert( pObject );
		if ( !pObject )
			{ return; };

		if ( HTTPCore_initServer( pObject ) )
			{
			return;
			};

		/* --- load up default virtual host object --- */
		const char *pDefaultHostName = PIConfig_lookupValue(
			PIObject_getConfigurationDB( pObject ),
			KEY_CONF_DEFAULTHOST, 0, 0 );
		if ( !pDefaultHostName )
			{
			CONFIG_ERR( pObject, "Dispatcher: 'DefaultHost' not defined" );
			return;
			};
		PIDB *pDB = PIObject_getDB( pObject );
		pDefaultHost = PIObject_loadFromLine(
			pDB, PIObject_getConfigurationDB( pObject ), pDefaultHostName );
		if ( !pDefaultHost )
			{/* --- error set by PIObject_loadFromLine() --- */return; };

		pPort = (const char *)PIDB_lookup( PIObject_getDB( pDefaultHost ),
			PIDBTYPE_RFC822, pFKPort, PIDBFLAG_FASTKEY );

		/* ---
		Check for connection keep open, optional
		--- */
		const char *pTmp = PIConfig_lookupValue(
			PIObject_getConfigurationDB( pObject ),
			KEY_CONF_KEEPOPEN, 0, 0 );
		if ( pTmp && !PIUtil_stricmp( pTmp, VALUE_OFF ) )
			{ iKeepOpen = 0; };

		/* ---
		Check for keep open count, optional
		--- */
		pTmp = PIConfig_lookupValue(
			PIObject_getConfigurationDB( pObject ),
			KEY_CONF_KEEPOPENCOUNT, 0, 0 );
		if ( pTmp ) { iKeepOpenCount = atoi( pTmp ); };

		/* ---
		Check for keep open timeout, optional
		--- */
		pTmp = PIConfig_lookupValue(
			PIObject_getConfigurationDB( pObject ),
			KEY_CONF_KEEPOPENTIMEOUT, 0, 0 );
		if ( pTmp ) { iKeepOpenTimeout = atoi( pTmp ); };

		bOK = true;
		};

	~Dispatcher()
		{
		PIObject_delete( pDefaultHost, 0, 0 );
		HTTPCore_cleanupServer();
		};

	/* ---
	Invoke all the steps on all the handlers
	--- */
	int HandleConnection( PIHTTP &tPIHTTP )
		{
		int iRet = HTTPCore_dispatch( &tPIHTTP, PH_INIT, PH_DESTROY );
		return iRet;
		};

	/* ---
	Invoke all the steps on all the handlers
	--- */
	inline int Execute( int iArgc, const char *ppArgv[] )
		{
		if ( iArgc<1 )
			{ return PIAPI_ERROR; };
		PIObject *pIO = (PIObject *)*ppArgv;
		if ( !pIO )
			{ return PIAPI_ERROR; };

		/* ---
		Get the DB from the IO object to monitor the KeepOpen flag
		--- */
		PIDB *pC = PIObject_getDB( pIO );
		PIDB_add( pC, PIDBTYPE_OPAQUE, pFKKeepOpen, (void *)iKeepOpen,
			PIDBFLAG_FASTKEY );

		int iDoKeepOpen = 0;
		int iDoKeepOpenCount = iKeepOpenCount;
		int iRet;

		PIHTTP tPIHTTP( pIO, PIObject_getDB( pDefaultHost ) );

		/* --- set the port variable in host db if not yet done --- */
		/* ( assume the server port won't change between connections) */
		if (!pPort)
			{
			pPort = (const char *)PIDB_lookup( tPIHTTP.pConnectionDB,
				PIDBTYPE_RFC822, pFKPort, PIDBFLAG_FASTKEY );

			if (pPort)
				{
				const char *pKeySize = (const char *)PIDB_lookup( tPIHTTP.pConnectionDB,
					PIDBTYPE_STRING, pFKKeySize, PIDBFLAG_FASTKEY );

				int iDefaultPort = pKeySize ? HTTPS_DEFAULT_PORT : HTTP_DEFAULT_PORT;
				if ( atoi(pPort) != iDefaultPort )
					{
					PIDB_replace( tPIHTTP.pHostDB, PIDBTYPE_RFC822, pFKPort,
						(void *)pPort, PIDBFLAG_FASTKEY );
					pPort = (const char *)PIDB_lookup( tPIHTTP.pHostDB,
						PIDBTYPE_RFC822, pFKPort, PIDBFLAG_FASTKEY );
					};
				};
			};

		for(;;)
			{
			/* ---
			Disallow more than the specified number of connection reuses
			--- */
			if ( !iDoKeepOpenCount )
				{
				PIDB_replace( pC, PIDBTYPE_OPAQUE, pFKKeepOpen, 0,
					PIDBFLAG_FASTKEY );
				}
			else
				{ iDoKeepOpenCount--; };

			/* --- get ready for new request --- */
			tPIHTTP.NewRequest();

			iRet = HandleConnection( tPIHTTP );
		
			/* --- make sure all data was flushed --- */
			tPIHTTP.GetIOBuffer().Flush();
			if ( iRet==PIAPI_COMPLETED )
				{
				/* ---
				Look at what the headers told the browser would happen
				--- */
				iDoKeepOpen = (int)PIDB_lookup( pC, PIDBTYPE_OPAQUE,
					pFKKeepOpen, PIDBFLAG_FASTKEY );
				}
			else
				{
				return iRet;
				};

			/* --- close connection ? --- */
			if ( !iDoKeepOpen )
				{
				return iRet;
				};

			/* ---
			Get the current timeout and set it low for poll on next
			request
			--- */
			assert( pFKRecvTimeout );
			int iTimeout = (int)PIDB_lookup( pC, PIDBTYPE_OPAQUE,
				pFKRecvTimeout, PIDBFLAG_FASTKEY );
			/* --- 
			NOTE: This keep open timeout should be moved to the
			configuration
			--- */
			PIDB_replace( pC, PIDBTYPE_OPAQUE, pFKRecvTimeout,
				(void *)5, PIDBFLAG_FASTKEY );

			/* ---
			If there're 2 bytes more data in the input queue ...
			--- */
			if ( tPIHTTP.GetIOBuffer().getBufferLen() == 2 )
				{
				/* ---
				... fix browser bug with extra CR/LF
				--- */
				char pTmp[2];
				tPIHTTP.GetIOBuffer().Read( (char *)pTmp, 2);
				};

			/* --- poll for new data --- */
			if ( tPIHTTP.GetIOBuffer().PollBeforeRead()<= 0 )
				{ 
				/* --- record error conditions? --- */
				iRet = PIAPI_COMPLETED;
				break;
				};

			/* ---
			Reset the recv timeout
			--- */
			PIDB_replace( pC, PIDBTYPE_OPAQUE, pFKRecvTimeout,
				(void *)iTimeout, PIDBFLAG_FASTKEY );
			};
		return iRet;		/* ---
							NOTE: there are other return points in this fn.
							--- */
		};

	inline int IsOK() 		{ return bOK; };
};

/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int Dispatcher_execute( PIObject *pObj,
	int iArgc, const char *ppArgv[] )
{
	if ( !pObj ) return PIAPI_ERROR;
	return ((Dispatcher *)PIObject_getUserData(pObj))->Execute( iArgc,
		ppArgv );
}

/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int Dispatcher_onClassLoad( PIClass_LoadAction eLoad, void * )
{
	switch( eLoad )
		{
		case STARTUP:
		default:;
		};
	return PIAPI_COMPLETED;
}

/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int Dispatcher_constructor( PIObject *pObj,
	int iArgc, const char *ppArgv[] )
{
	Dispatcher *pDisp = new Dispatcher( pObj, iArgc, ppArgv );
	if (!( pDisp && pDisp->IsOK() ))
		{
		delete pDisp;
		return PIAPI_ERROR;
		};
	if ( PIObject_setUserData( pObj, pDisp ) )
		{
		delete pDisp;
		CONFIG_ERR( pObj, "Dispatcher_constructor: \
PIObject_setUserData() failed" );
		return PIAPI_ERROR;
		};
	return PIAPI_COMPLETED;
}

/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int Dispatcher_copyConstructor( PIObject *, int, const char *[] )
{
	return PIAPI_ERROR;
}

/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int Dispatcher_destructor( PIObject *pObj, int,
	const char *[] )
{
	delete (Dispatcher *)PIObject_getUserData( pObj );
	return PIAPI_COMPLETED;
}

⌨️ 快捷键说明

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