📄 stressclient.cpp
字号:
--- */
/* ---
path and query string.
--- */
for(; i<iLineLen && pLine[i]!='?' && !(isspace(pLine[i])); i++);
*ppPath = pLine;
if ( pLine[i]=='?' )
{
pLine[i++] = '\0';
*ppQueryString = &(pLine[i]);
for(; i<iLineLen && !(isspace(pLine[i])); i++);
}
else
{ *ppQueryString = ""; };
if ( i==iLineLen ) { return INT_CONTINUE; };
pLine[i++]='\0';
for(; i<iLineLen && (isspace(pLine[i])); i++);
pLine = &( pLine[i] ); iLineLen -= i; i=0;
/* ---
pLine now points at the component following the URL path and
query string.
--- */
/* ---
protocol is last component on the line, skip components until the last
--- */
for(;;)
{
for(; i<iLineLen && !(isspace(pLine[i])); i++);
*ppProtocol = pLine;
for(; i<iLineLen && (isspace(pLine[i])); i++);
if ( i==iLineLen ) { return INT_CONTINUE; }; /* this should be true */
/* --- I guess not --- */
pLine = &( pLine[i] ); iLineLen -= i; i=0;
};
/* -- OK --- */
return INT_CONTINUE;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
int StressClient::ReadRequestLine( PIDB *pDB, const char *pLine )
{
const char *pMethod = 0;
const char *pProxyProtocol = 0;
const char *pProxyHost = 0;
int iProxyHostLen = 0;
const char *pProxyPort = 0;
int iProxyPortLen = 0;
const char *pURI = 0;
const char *pQueryString = 0;
const char *pProtocol = 0;
int iStatus = SplitRequestLine(
(char *)pLine,
strlen(pLine),
&pMethod,
&pProxyProtocol,
&pProxyHost,
&iProxyHostLen,
&pProxyPort,
&iProxyPortLen,
&pURI,
&pQueryString,
&pProtocol
);
if ( iStatus ) { return iStatus; };
if ( !pMethod || !pURI || !pQueryString || !pProtocol )
{ return ST_BADREQUEST; };
/* --- store these headers --- */
PIDB_add( pDB, PIDBTYPE_STRING, KEY_HTTP_METHOD, (void *)pMethod, 0 );
PIDB_add( pDB, PIDBTYPE_STRING, KEY_HTTP_URI, (void *)pURI, 0 );
PIDB_add( pDB, PIDBTYPE_STRING, KEY_HTTP_QUERYSTRING, (void *)pQueryString, 0 );
PIDB_add( pDB, PIDBTYPE_STRING, KEY_HTTP_PROTOCOL, (void *)pProtocol, 0 );
/* --- Is this a proxy request? --- */
if ( pProxyProtocol )
{
PIDB_add( pDB, PIDBTYPE_STRING, KEY_HTTP_PROXYPROTOCOL,
(void *)pProxyProtocol, 0 );
PIString sProxyHost( pProxyHost, iProxyHostLen );
PIDB_add( pDB, PIDBTYPE_STRING, KEY_HTTP_PROXYHOST,
(void *)(const char *)sProxyHost, 0 );
PIString sProxyPort( pProxyPort, iProxyPortLen );
PIDB_add( pDB, PIDBTYPE_STRING, KEY_HTTP_PROXYPORT,
(void *)(const char *)sProxyPort, 0 );
};
/* ---
Convert method and status into internal numeric form
--- */
int iMethod = MD_UNKNOWN;
int iProtocol = PR_UNKNOWN;
if ( !PIUtil_stricmp( pMethod, MD_NAME_GET ) )
{ iMethod = MD_GET; }
else if ( !PIUtil_stricmp( pMethod, MD_NAME_POST ) )
{ iMethod = MD_POST; }
else if ( !PIUtil_stricmp( pMethod, MD_NAME_HEAD ) )
{ iMethod = MD_HEAD; }
else if ( !PIUtil_stricmp( pMethod, MD_NAME_PUT ) )
{ iMethod = MD_PUT; }
else if ( !PIUtil_stricmp( pMethod, MD_NAME_DELETE ) )
{ iMethod = MD_DELETE; }
else if ( !PIUtil_stricmp( pMethod, MD_NAME_OPTIONS ) )
{ iMethod = MD_OPTIONS; }
else if ( !PIUtil_stricmp( pMethod, MD_NAME_TRACE ) )
{ iMethod = MD_TRACE; };
if ( *pProtocol )
{
/* --- any protocol is not HTTP/0.9 --- */
if ( !PIUtil_stricmp( pProtocol, PR_NAME_HTTP10 ) )
{ iProtocol = PR_HTTP10; }
else if ( !PIUtil_stricmp( pProtocol, PR_NAME_HTTP11 ) )
{ iProtocol = PR_HTTP11; };
}
else
{ iProtocol = PR_HTTP09; };
/* --- Do we support this method and protocol ? --- */
if ( iMethod == MD_UNKNOWN ) { return ST_NOTIMPLEMENTED; };
if ( iProtocol == PR_UNKNOWN ) { iProtocol = PR_HTTP10; };
/* --- Do we support the method for version < HTTP/1.1 ? --- */
if ((iProtocol != PR_HTTP11) && (iMethod > MD_HEAD))
{ return ST_BADREQUEST; }; // maybe better ST_NOTIMPLEMENTED?
/* --- set the numeric method and protocol --- */
PIDB_add( pDB, PIDBTYPE_OPAQUE, KEY_HTTP_METHOD, (void *)iMethod, 0 );
PIDB_add( pDB, PIDBTYPE_OPAQUE, KEY_HTTP_PROTOCOL, (void *)iProtocol, 0 );
return iStatus;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
int StressClient::ReadFileMask( const char *pValue, int iStatus )
{
PIFInfo *pInfo = PIFInfo_new( pValue );
PIString sFilePath = PIFInfo_getPathRoot( pInfo );
PIString sFileMask = PIFInfo_getName( pInfo );
if ( sFileMask && sFilePath )
{
PIFInfo *pDir = HTTPCore_getCachedFile( (const char *)sFilePath );
if ( pDir && PIFInfo_isDirectory( pDir ) )
{
PIFInfo *pFile = PIFInfo_getFirstFileInDirectory( pDir );
enum { BUFSIZE=15 };
char szBuf[BUFSIZE+1];
while( pFile )
{
/* ---
Check file is allowed, if mask pattern matches
then include this file
--- */
if ( PIFInfo_isReadable( pFile ) )
{
/* ---
Get filename
--- */
PIString sFileName( PIFInfo_getName( pFile ) );
if ( HTTPUtil_regexMatch( sFileMask, sFileMask.Len(),
sFileName, sFileName.Len() ))
{
sprintf( szBuf, "%lu", iCurrentTest++ );
PIString sTestFile = sFilePath;
sTestFile.Concatenate( PIPlatform_getDirectorySeparator());
sTestFile.Concatenate( sFileName );
PIDB *pDB = PIDB_new( pTestcaseDB, szBuf );
PIDB_add( pDB, PIDBTYPE_STRING, KEY_INT_TESTFILE,
(void *)(const char *)sTestFile, 0 );
PIDB_add( pDB, PIDBTYPE_OPAQUE, KEY_INT_STATUS,
(void *)iStatus, 0 );
};
};
if ( !PIFInfo_getNextFileInDirectory( pFile ) )
{ PIFInfo_delete( pFile ); pFile = 0; };
}; //while
HTTPCore_releaseCachedFile( pDir );
};
};
return PIAPI_COMPLETED;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
int StressClient::Parameter( const char *pVariable, const char *pValue,
const char *pWhere )
{
assert( pVariable && pValue );
PIOStrStream os;
os << pWhere << "StressClient: ";
if ( !PIUtil_stricmp( KEY_CONF_USERAGENT, pVariable ) )
{
sUserAgent = (const char *)DeQuote( pValue );
}
else if ( !PIUtil_stricmp( KEY_CONF_PROTOCOL, pVariable ) )
{
iProtocol = (!PIUtil_stricmp((const char *)DeQuote( pValue ),
"HTTP/1.1")) ? PR_HTTP11 : PR_HTTP10;
}
else if ( !PIUtil_stricmp( KEY_CONF_VIRTUALHOST, pVariable ) )
{
sVirtualHost = (const char *)DeQuote( pValue );
}
else if ( !PIUtil_stricmp( KEY_CONF_KEEPOPEN, pVariable ) )
{
iKeepAlive = !PIUtil_stricmp((const char *)DeQuote( pValue ), "On");
}
else if ( !PIUtil_stricmp( KEY_CONF_KEEPOPENTIMEOUT, pVariable ) )
{
iAliveTimeout = atoi((const char *)DeQuote( pValue ));
}
else if ( !PIUtil_stricmp( KEY_CONF_KEEPOPENCOUNT, pVariable ) )
{
iKeepOpenCount = atoi((const char *)DeQuote( pValue ));
}
else if ( !PIUtil_stricmp( KEY_CONF_RANDOM, pVariable ) )
{
iRandom = !PIUtil_stricmp((const char *)DeQuote( pValue ), "On");
}
else if ( !PIUtil_stricmp( KEY_CONF_FILEMASK, pVariable ) )
{
StringTokenizer tTokens( (const char *)DeQuote( pValue ),":" );
int iStatus = tTokens.NumTokens() > 1 ? atoi( tTokens.GetToken( 1 ) ) : 200;
ReadFileMask( (const char *)tTokens.GetToken( 0 ), iStatus );
}
else if ( !PIUtil_stricmp( KEY_CONF_TESTFILE, pVariable ) )
{
enum { BUFSIZE=15 };
char szBuf[BUFSIZE+1];
sprintf( szBuf, "%lu", iCurrentTest++ );
StringTokenizer tTokens( (const char *)DeQuote( pValue ), ":" );
PIDB *pDB = PIDB_new( pTestcaseDB, szBuf );
PIDB_add( pDB, PIDBTYPE_STRING, KEY_INT_TESTFILE,
(void *)(const char *)tTokens.GetToken( 0 ), 0 );
int iStatus = tTokens.NumTokens() > 1 ? atoi( tTokens.GetToken( 1 ) ) : 200;
PIDB_add( pDB, PIDBTYPE_OPAQUE, KEY_INT_STATUS, (void *)iStatus, 0 );
}
else if ( !PIUtil_stricmp( KEY_CONF_TESTCASE, pVariable ) )
{
enum { BUFSIZE=15 };
char szBuf[BUFSIZE+1];
sprintf( szBuf, "%lu", iCurrentTest++ );
PIDB *pDB = PIDB_new( pTestcaseDB, szBuf );
StringTokenizer tTokens( (const char *)DeQuote( pValue ), ":" );
if ( !ReadRequestLine( pDB, (const char *)tTokens.GetToken( 0 ) ) == INT_CONTINUE )
{
// ErrorMsg!
iOK = 0;
}
else
{
int iStatus = tTokens.NumTokens() > 1 ? atoi( tTokens.GetToken( 1 ) ) : 200;
PIDB_add( pDB, PIDBTYPE_OPAQUE, KEY_INT_STATUS,
(void *)iStatus, 0 );
};
}
else if ( !PIUtil_stricmp( KEY_CONF_LOGFILE, pVariable ) )
{
sLogfile = (const char *)DeQuote( pValue );
}
else if ( !PIUtil_stricmp( KEY_CONF_OPENMODE, pVariable ) )
{
sOpenMode = (const char *)DeQuote( pValue );
}
else
{
os << "Unknown directive '" << pVariable <<
"'" << ends;
CONFIG_ERR( Object(), os.str() );
return 0;
};
return 1;
};
int hex2int(char *s)
{
int iRes = 0;
for (unsigned int i=0;i<strlen(s);i++)
{
s[i] = toupper(s[i]);
iRes <<= 4;
iRes += (s[i]<'A') ? s[i]-48 : s[i]-55;
}
return iRes;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
int StressClient::Execute( int iArgc, const char *ppArgv[] )
{
PI_MARK;
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 );
int iRet;
int iTimeout;
PIIOBuffer *pBuffer = PIIOBuffer_new( pIO );
if ( !pBuffer ) return PIAPI_ERROR;
if ( iKeepAlive ) {
assert( pFKRecvTimeout );
iTimeout = (int)PIDB_lookup( pC, PIDBTYPE_OPAQUE,
pFKRecvTimeout, PIDBFLAG_FASTKEY );
PIDB_replace( pC, PIDBTYPE_OPAQUE, pFKRecvTimeout,
(void *)iAliveTimeout, PIDBFLAG_FASTKEY );
};
if (iRandom) srand( (unsigned)time( NULL ) );
int iDoKeepOpen = iKeepAlive;
int iDoKeepOpenCount = iKeepOpenCount;
int iServerProtocol = PR_HTTP11;
const char *pKeepOpen = 0;
PIDB *pR = PIDB_new( 0, "R" );
for(;;)
{
/* ---
Disallow more than the specified number of connection reuses
--- */
if ( !iDoKeepOpenCount )
iDoKeepOpen = 0;
else
iDoKeepOpenCount--;
/* ---
Get the testcase from DB
--- */
if ( !pTestcaseDB ) break;
enum { BUFSIZE=16 };
char szBuf[BUFSIZE+1];
if ( iRandom )
{
iCurrentTest = rand() % (iMaxTest + 1);
}
else
{
if (iCurrentTest > iMaxTest ) { iCurrentTest = 0; };
}
sprintf( szBuf, "%lu", iCurrentTest );
PIDB *pQ = (PIDB *)PIDB_lookup( pTestcaseDB, PIDBTYPE_TREE, szBuf, 0 );
if ( !pQ ) return PIAPI_ERROR;
/* --- get ready for new request --- */
const char *pPath = (const char *)PIDB_lookup( pQ, PIDBTYPE_STRING,
pFKTestfile, PIDBFLAG_FASTKEY );
iRet = pPath ? SendRequestFile( pBuffer, pPath )
: SendRequestDB( pBuffer, pC, pQ, iDoKeepOpen );
/* --- send the whole thing on its way --- */
PIIOBuffer_flush( pBuffer );
iRet = PIIOBuffer_pollBeforeRead( pBuffer );
if (iRet < 0)
{
cout << "PIIOBuffer_pollBeforeRead failed" <<
endl << "Testcase: " << iCurrentTest << endl;
goto exit_handle;
}
/*
** Read the response
*/
iRet = HTTPCore_readHeaders( pBuffer, pR, RH_RESPONSE );
if ( iRet )
{
cout << "HTTPCore_readHeaders failed: " << iRet <<
endl << "Testcase: " << iCurrentTest << endl;
goto exit_handle;
};
/* ---
Check out status line from remote server
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -