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

📄 stressclient.cpp

📁 mini http server,可以集成嵌入到程序中,实现简单的web功能
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		--- */
		int iStatusCode = (int)PIDB_lookup( pR, PIDBTYPE_OPAQUE, KEY_HTTP_STATUSCODE, 0 );
		if ( iStatusCode !=	(int)PIDB_lookup( pQ, PIDBTYPE_OPAQUE, KEY_INT_STATUS, 0 ))
			{
			cout << "Server returned status " << iStatusCode <<	endl
				 << "expected status "
				 << (int)PIDB_lookup( pQ, PIDBTYPE_OPAQUE, KEY_INT_STATUS, 0 )
				 << " for Testcase " << iCurrentTest << endl;
			};
	    
	    /*
		** Read the rest of the response
	    */

		/* --- get length to read --- */
		unsigned long iRead = 0;
		unsigned long iToRead;
		int iBufRead;
		const char *pData;
		const char *pTE = (const char *)PIDB_lookup( pR, PIDBTYPE_RFC822,
			KEY_HTTP_TRANSFERENCODING, 0 );
		if ( pTE && !PIUtil_stricmp( pTE, KEY_HTTP_CHUNKED ))
			{
			pData = (const char *)PIUtil_malloc(0x4000);

			/* --- loop until no more bytes left --- */
			do
				{
				/* --- start new chunk --- */				
				iRead = 0;

				/* --- get chunk header with data size --- */				
				PIIOBuffer_getLine( pBuffer, szBuf, BUFSIZE );
				iToRead = hex2int(szBuf);
				if ( !iToRead )
					{
					PIIOBuffer_getLine( pBuffer, szBuf, BUFSIZE );
					break;
					};

				if ( iToRead > 0x4000 )
					{
					cout << "Received chunksize to large for internal buffer" << endl;
					iRet = 400;
					break;
					};

				/* --- read the whole chunk --- */				
				do
					{

					/* --- no more data or client timeout --- */
					if ( PIIOBuffer_pollBeforeRead( pBuffer ) < 0 ) break;

					/* --- read the data --- */
					iBufRead = PIIOBuffer_readToBuffer( pBuffer, (char *)pData,
						iToRead - iRead );
					if ( iRead == -1)
						{
						cout << "Error reading chunk into internal buffer" << endl;
						iRet = 400;
						break;
						};
					iRead += iBufRead;
					}
				while ( iToRead - iRead );

				PIIOBuffer_getLine( pBuffer, szBuf, BUFSIZE );
				}
			while ( iToRead );
			PIUtil_free( (void *)pData );
			}
		else
			{
			pData = (const char *)PIDB_lookup( pR, PIDBTYPE_RFC822,
				KEY_HTTP_CONTENTLENGTH, 0 );
			iToRead = pData ? strtol(pData, NULL, 10) : 0;

			/* --- loop until no more bytes left --- */
			do
				{
				if ( !iToRead ) break;

				/* --- no more data or client timeout --- */
				if ( PIIOBuffer_pollBeforeRead( pBuffer ) < 0 ) break;

				/* --- read the data --- */
				pData = PIIOBuffer_read( pBuffer, &iBufRead );
				iRead += iBufRead;

				/* --- this is an error --- */
				if ( !iBufRead ) break;
				}
			while ( iRead < iToRead );

			if (iRead < iToRead)
				{
				cout << "Could not read server response body" <<
					endl << "Testcase: " << iCurrentTest << endl;
				iRet = 400;
				goto exit_handle;
				};

			if (iRead > iToRead)
				{
				cout << "Server sent to much data in response" <<
					endl << "Testcase: " << iCurrentTest << endl;
				iRet = 400;
				goto exit_handle;
				};
			};

		pKeepOpen = (const char *)PIDB_lookup( pR, PIDBTYPE_RFC822,
			KEY_HTTP_CONNECTION, 0 );
		iServerProtocol = (int)PIDB_lookup( pR, PIDBTYPE_OPAQUE,
			KEY_HTTP_PROTOCOL, 0 );
		iDoKeepOpen = (( pKeepOpen && !PIUtil_stricmp( pKeepOpen, "Keep-Alive" ))
			|| ( !pKeepOpen && iServerProtocol == PR_HTTP11 )) ? 1: 0;

		PIDBIterator *pIter = PIDB_getIterator( pR, PIDBTYPE_RFC822, 0, 0 );
		if ( pIter ) {
			while ( PIDBIterator_atValidElement( pIter ) ) {
				PIDBIterator_removeCurrent( pIter );
			};
			PIDBIterator_delete( pIter );
		};

		pIter = PIDB_getIterator( pR, PIDBTYPE_OPAQUE, 0, 0 );
		if ( pIter ) {
			while ( PIDBIterator_atValidElement( pIter ) ) {
				PIDBIterator_removeCurrent( pIter );
			};
			PIDBIterator_delete( pIter );
		};

		iCurrentTest++;
		if ( iRet != PIAPI_COMPLETED || !iDoKeepOpen ) { break; };
		}; // for(;;)

		if ( iKeepAlive ) {
			PIDB_replace( pC, PIDBTYPE_OPAQUE, pFKRecvTimeout,
				(void *)iTimeout, PIDBFLAG_FASTKEY );
		};

exit_handle:
	PIIOBuffer_delete( pBuffer );
	PIDB_delete( pR );
	PI_MARK;
	return iRet;
}


/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
static const char *pProtocolMap[] = 
{
    PR_NAME_UNKNOWN,
    PR_NAME_HTTP09,
    PR_NAME_HTTP10,
    PR_NAME_HTTP11,
    0
};
int StressClient::SendRequestDB(PIIOBuffer *pBuffer, PIDB *pC, PIDB *pQ, int iKeepOpen )
	{
	int iRet = PIAPI_COMPLETED;

    /*
    ** Add some headers
    */
	PIDB_replace( pQ, PIDBTYPE_OPAQUE, KEY_HTTP_CONNECTION, (void *)iKeepOpen, 0 );
	PIDB_replace( pQ, PIDBTYPE_RFC822, KEY_HTTP_CONTENTLENGTH, (void *)"0", 0 );

	if (iProtocol != PR_UNKNOWN)
		{
		PIDB_replace( pQ, PIDBTYPE_OPAQUE, KEY_HTTP_PROTOCOL,
			(void *)iProtocol, 0 );
		PIDB_replace( pQ, PIDBTYPE_STRING, KEY_HTTP_PROTOCOL,
			(void *)pProtocolMap[iProtocol], 0);
		};	

	if ( sUserAgent.Len() )
		{
		PIDB_replace( pQ, PIDBTYPE_RFC822, "User-Agent",
			(void *)(const char *)sUserAgent, 0 );
		};

	if ( sVirtualHost.Len() )
		{
		PIDB_replace( pQ, PIDBTYPE_RFC822, pFKHost,
			(void *)(const char *)sVirtualHost, PIDBFLAG_FASTKEY );
		};

    /* ---
	Make sure the 'host' header is sent
	--- */
	if (!PIDB_lookup( pQ, PIDBTYPE_RFC822, pFKHost, PIDBFLAG_FASTKEY ) )
		{
	    const char *pPort = (const char *)PIDB_lookup( pC, PIDBTYPE_RFC822,
			KEY_INT_SERVERPORT, 0);
		if (!pPort) pPort = "80";

		const char *pHost = (const char *)PIDB_lookup( pC, PIDBTYPE_STRING,
			KEY_INT_REMOTEHOST, 0);
		if (!pHost) pHost = "localhost";

		PIOStrStream os;
		os << pHost;
		if ( atoi(pPort) != HTTP_DEFAULT_PORT )
	        {
		    os << ":" << pPort;
			};
	    os << ends;

		PIDB_replace( pQ, PIDBTYPE_RFC822, pFKHost, (void *)os.str(), PIDBFLAG_FASTKEY );
		};

    /*
    ** Make the request
    */
    iRet = HTTPUtil_doHTTPRequest( pBuffer, pQ );
    if ( iRet != PIAPI_COMPLETED )
        {
		cout << "doHTTPRequest failed" << endl;
        };

	return iRet;
	}


/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
int StressClient::SendRequestFile(PIIOBuffer *pBuffer, const char *pPath )
	{
    int iRet = PIAPI_COMPLETED;
	
	/* ---
	Get file object
	--- */
	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_releaseCachedFile( pFInfo );	
		cout << "PIFInfo_exists || PIFInfo_isRegular failed" << endl;
		return PIAPI_ERROR;
		};

	/* ---	
	Send the file
	--- */
	iRet = HTTPUtil_sendFile( pBuffer, pFInfo, PIIOBUF_NONE, 0 );
	if (iRet != PIAPI_COMPLETED)
	    {
		cout << "HTTPUtil_sendFile returned: " << iRet << endl;
	    }

	HTTPCore_releaseCachedFile( pFInfo );
	return iRet;
	}


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


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


/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int StressClient_constructor( PIObject *pObj, int iArgc, const char *ppArgv[] )
{
	StressClient *pStressClient = new StressClient( pObj, iArgc, ppArgv );

	if (!( pStressClient && pStressClient->IsOK() ))
		{
		delete pStressClient;
		return PIAPI_ERROR;
		};

	if ( PIObject_setUserData( pObj, pStressClient ) )
		{
		delete pStressClient;
		CONFIG_ERR( pObj, "StressClient_constructor: PIObject_setUserData() failed" );
		return PIAPI_ERROR;
		};
	return PIAPI_COMPLETED;
}


/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int StressClient_copyConstructor( PIObject *pObj, int, const char *[] )
{
	/* --- forbid copy constructor --- */
	return PIAPI_ERROR;
}


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

#if 0
/*___+++CNF_BEGIN+++___*/

	<Class>
		Name StressClientClass
		Type LogicExtension
		Library StressClient
		OnClassLoad StressClient_onClassLoad
		Constructor StressClient_constructor
		CopyConstructor StressClient_copyConstructor
		Destructor StressClient_destructor
		Execute StressClient_execute
	</Class>

	<Object>
		Name StressClient
		Class StressClientClass
		TestCase "GET /?param1=value1 HTTP/1.1"
		TestCase "GET /icons/Pi3Tile.gif HTTP/1.1"
		TestCase "GET /icons/Pi3Web_earth1.gif HTTP/1.1"
		TestCase "GET /index.htm HTTP/1.1"
		TestCase "GET /samples.htm HTTP/1.0"
#		TestCase "GET /pidocs/Features/test1.php3 HTTP/1.0"
#		TestCase "GET /pidocs/Features/test2.php3 HTTP/1.1"
#		TestCase "GET /pidocs/Features/test3.php3 HTTP/1.1"
#		TestCase "GET /pidocs/Features/test4.php3 HTTP/1.1:401"
#		TestFile "..\Tests\t1.dat"
#		TestFile "..\Tests\t10.dat"
#		TestFile "..\Tests\t100.dat:404"
#		TestFile "..\Tests\t11.dat:401"
#		TestFile "..\Tests\t12.dat"
#		TestFile "..\Tests\t13.dat:301"
#		TestFile "..\Tests\t14.dat"
#		TestFile "..\Tests\t15.dat"
#		TestFile "..\Tests\t16.dat"
#		TestFile "..\Tests\t17.dat"
#		TestFile "..\Tests\t18.dat"
#		TestFile "..\Tests\t19.dat"
#		TestFile "..\Tests\t2.dat"
#		TestFile "..\Tests\t3.dat:301"
#		TestFile "..\Tests\t31.dat:500"
#		TestFile "..\Tests\t4.dat"
#		TestFile "..\Tests\t41.dat:301"
#		TestFile "..\Tests\t42.dat:301"
#		TestFile "..\Tests\t43.dat:301"
#		TestFile "..\Tests\t44.dat:301"
#		TestFile "..\Tests\t45.dat:301"
#		TestFile "..\Tests\t5.dat"
#		TestFile "..\Tests\t50.dat"
#		TestFile "..\Tests\t6.dat"
#		TestFile "..\Tests\t61.dat"
#		TestFile "..\Tests\t7.dat"
#		TestFile "..\Tests\t71.dat"
#		TestFile "..\Tests\t8.dat"
#		TestFile "..\Tests\t81.dat"
#		TestFile "..\Tests\t9.dat"
#		FileMask "..\Tests\*.dat"
#		FileMask "..\Tests2\*.dat"
		Random Off
		KeepOpen On
		KeepOpenCount 10
		KeepOpenTimeout 5
	</Object>

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

⌨️ 快捷键说明

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