/**
* httpresp
* A CGI program to simulate various HTTP responses.
* Features:
*
* If you found this useful, please add a note of acknowledgement to my * guestbook. * If you would like to report a bug or suggest some improvements, * you are most welcome. I will be happy to help you use this piece of code. *
*
* @author Tanmay K. Mohapatra
* @version 1.00, 18th Dec, 1999
*
* Modification log:
* 1.00 Tanmay 18th Dec 1999 Original Version
*/
#ifdef UNIX
#include
\
Example: http://myserver.on.nt/httpresp.exe?status=404 Not Found&string=File Not Found
\
\
\
"
typedef struct
{
char *pStatus;
char *pFileToSend;
char *pStringToSend;
char *pHeaders[20]; // 20 headers should be sufficient
int iDelayHeader;
int iDelayContent;
} tstHttpResp;
static int checkForSendStatus (tstHttpResp *pstHttpResp, CCGIEnv *pCGIEnv);
static int checkForFileToSend (tstHttpResp *pstHttpResp, CCGIEnv *pCGIEnv);
static int checkForStringToSend (tstHttpResp *pstHttpResp, CCGIEnv *pCGIEnv);
static int checkForHeaders (tstHttpResp *pstHttpResp, CCGIEnv *pCGIEnv);
static int checkWhetherToDelayHeader (tstHttpResp *pstHttpResp, CCGIEnv *pCGIEnv);
static int checkWhetherToDelayContent (tstHttpResp *pstHttpResp, CCGIEnv *pCGIEnv);
static char * getValueAnyWay (const char *sName, CCGIEnv *pCGIEnv);
static int checkEmptyCallAndSetHelp (tstHttpResp *pstHttpResp);
static int doHeaderSendDelay (tstHttpResp *pstHttpResp);
static int doContentSendDelay (tstHttpResp *pstHttpResp);
static int setContent (tstHttpResp *pstHttpResp, CCGIEnv *pCGIEnv);
static int setHeaders (tstHttpResp *pstHttpResp, CCGIEnv *pCGIEnv);
int main(int argc, char **argv)
{
tstHttpResp stHttpResp;
pCGIEnv = new CCGIEnv();
pCGIEnv->readQueryData();
pCGIEnv->readCGIEnv();
pCGIEnv->readPostData();
memset(&stHttpResp, 0, sizeof(stHttpResp));
checkForSendStatus (&stHttpResp, pCGIEnv);
checkForFileToSend (&stHttpResp, pCGIEnv);
checkForStringToSend (&stHttpResp, pCGIEnv);
checkForHeaders (&stHttpResp, pCGIEnv);
checkWhetherToDelayHeader (&stHttpResp, pCGIEnv);
checkWhetherToDelayContent (&stHttpResp, pCGIEnv);
checkEmptyCallAndSetHelp(&stHttpResp);
setHeaders(&stHttpResp, pCGIEnv);
setContent(&stHttpResp, pCGIEnv);
doHeaderSendDelay(&stHttpResp);
pCGIEnv->sendHeaders();
doContentSendDelay(&stHttpResp);
pCGIEnv->sendResponse();
return 0;
}
static int checkEmptyCallAndSetHelp(tstHttpResp *pstHttpResp)
{
if(!pstHttpResp->pStatus)
{
pstHttpResp->pStatus = "200 Ok";
}
if( (!pstHttpResp->pFileToSend) && (!pstHttpResp->pStringToSend) )
{
int iNumHeaders;
for (iNumHeaders=0; (iNumHeaders < (sizeof(pstHttpResp->pHeaders)-1)) && pstHttpResp->pHeaders[iNumHeaders]; iNumHeaders++);
if(!iNumHeaders)
{
// no headers and no data, set our own help
pstHttpResp->pStringToSend = HTTPRESP_USAGE_MSG;
}
}
return 0;
}
static int doHeaderSendDelay(tstHttpResp *pstHttpResp)
{
if(pstHttpResp->iDelayHeader > 0)
{
#ifdef UNIX
sleep(pstHttpResp->iDelayHeader);
#else /* WIN32 */
Sleep(1000*pstHttpResp->iDelayHeader);
#endif
}
return 0;
}
static int doContentSendDelay(tstHttpResp *pstHttpResp)
{
if(pstHttpResp->iDelayContent > 0)
{
#ifdef UNIX
sleep(pstHttpResp->iDelayContent);
#else /* WIN32 */
Sleep(1000*pstHttpResp->iDelayContent);
#endif
}
return 0;
}
static int setContent(tstHttpResp *pstHttpResp, CCGIEnv *pCGIEnv)
{
if(pstHttpResp->pStringToSend)
{
pCGIEnv->accumulateResponse(pstHttpResp->pStringToSend);
}
if(pstHttpResp->pFileToSend)
{
// read the file and append to output
char sBuff[2048];
FILE *fp;
int iRead;
if(fp = fopen(pstHttpResp->pFileToSend, "r"))
{
while(!feof(fp))
{
if((iRead = fread(sBuff, 1, sizeof(sBuff), fp)) > 0)
{
pCGIEnv->accumulateResponse(sBuff, iRead);
}
}
fclose(fp);
}
}
return 0;
}
static int setHeaders(tstHttpResp *pstHttpResp, CCGIEnv *pCGIEnv)
{
int iIndex;
char *sHeader;
if(pstHttpResp->pStatus)
{
char *pEndCode;
if(sHeader = strdup(pstHttpResp->pStatus))
{
if(pEndCode = strchr(sHeader, ' '))
{
int iCode;
*pEndCode = 0;
iCode = atoi(sHeader);
pCGIEnv->setHTTPResponseCode(iCode, pEndCode+1);
}
free(sHeader);
}
}
for (iIndex=0; (iIndex < (sizeof(pstHttpResp->pHeaders)-1)) && pstHttpResp->pHeaders[iIndex]; iIndex++)
{
if(sHeader = strdup(pstHttpResp->pHeaders[iIndex]))
{
char *pNameValSep;
if(pNameValSep = strchr(sHeader, '='))
{
*pNameValSep = 0;
pCGIEnv->setResponseHeader(sHeader, pNameValSep+1);
}
free(sHeader);
}
}
return 0;
}
static char * getValueAnyWay(const char *sName, CCGIEnv *pCGIEnv)
{
char *pValue;
if(!(pValue = pCGIEnv->pQueryData->getValueFor(sName)))
{
pValue = pCGIEnv->pPostData->getValueFor(sName);
}
return pValue;
}
static int checkForSendStatus(tstHttpResp *pstHttpResp, CCGIEnv *pCGIEnv)
{
pstHttpResp->pStatus = getValueAnyWay(ACTION_SEND_STATUS, pCGIEnv);
return 0;
}
static int checkForFileToSend(tstHttpResp *pstHttpResp, CCGIEnv *pCGIEnv)
{
pstHttpResp->pFileToSend = getValueAnyWay(ACTION_SEND_FILE, pCGIEnv);
return 0;
}
static int checkForStringToSend(tstHttpResp *pstHttpResp, CCGIEnv *pCGIEnv)
{
pstHttpResp->pStringToSend = getValueAnyWay(ACTION_SEND_STRING, pCGIEnv);
return 0;
}
static int checkForHeaders(tstHttpResp *pstHttpResp, CCGIEnv *pCGIEnv)
{
int iIndex;
char sName[32];
char *sValue;
for (iIndex=0; iIndex < (sizeof(pstHttpResp->pHeaders)-1); iIndex++)
{
sprintf(sName, "%s%d", ACTION_SEND_HEADER, iIndex);
sValue = getValueAnyWay(sName, pCGIEnv);
if(!sValue) break;
pstHttpResp->pHeaders[iIndex] = strdup(sValue);
}
return 0;
}
static int checkWhetherToDelayHeader(tstHttpResp *pstHttpResp, CCGIEnv *pCGIEnv)
{
char *sDelayHeader = getValueAnyWay(ACTION_DELAY_HEADER, pCGIEnv);
if(sDelayHeader)
{
pstHttpResp->iDelayHeader = atoi(sDelayHeader);
}
return 0;
}
static int checkWhetherToDelayContent(tstHttpResp *pstHttpResp, CCGIEnv *pCGIEnv)
{
char *sDelayContent = getValueAnyWay(ACTION_DELAY_CONTENT, pCGIEnv);
if(sDelayContent)
{
pstHttpResp->iDelayContent = atoi(sDelayContent);
}
return 0;
}
\
status: HTTP status code to send (e.g. "200 Ok" for success) \
file: The file will be read and its contents sent in the response. It should NOT have HTTP headers \
string: The will be sent in the response. It should NOT have HTTP headers \
delayheader: Do not send headers till so many secs. Can be used to test timeout. \
delaycontent: Do not send content till so many secs. Can be used to test timeout. \
header[0-20]: Header strings - header1 to header20. Each string is one line of the header. (e.g. "Content-length: 1000")