HTTP server problem when running two clients



I wrote an HTTP server and a client.
A client sends 100 requests in a sequentially order.
When I run the HTTP server with one client it works ok.
But, when I run the HTTP server with two clients (each sends requests to a
different port) the server get all the requests (200 requests) but the body
of some of the requests is empty.
I run the 3 processes on the same computer with windows XP.
Does anyone know why the body is empty?

Client code is the following:

int main (int argc, char *argv[])
{
BOOL bResults = FALSE;
HINTERNET hSession = NULL;
HINTERNET hConnect = NULL;
HINTERNET hRequest = NULL;
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;

for (int i = 1; i<=100; i++)
{
hSession = NULL;
hConnect = NULL;
hRequest = NULL;

// Use WinHttpOpen to obtain a session handle.
hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);

// Specify an HTTP server.
if (hSession)
hConnect = WinHttpConnect( hSession, L"localhost",
80, 0);

// Create an HTTP Request handle.
if (hConnect)
hRequest = WinHttpOpenRequest( hConnect, L"POST", L"/index.html",
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES, 0);

// Send a Request.
if (hRequest)
bResults = WinHttpSendRequest( hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS, 0,
"ABC", 4, 4, 0);

// Place additional code here.


// Report errors.
if (!bResults)
printf("Error %d has occurred.\n",GetLastError());

// End the request.
if (bResults)
bResults = WinHttpReceiveResponse( hRequest, NULL);

// Keep checking for data until there is nothing left.
if (bResults)
do
{

// Check for available data.
dwSize = 0;
if (!WinHttpQueryDataAvailable( hRequest, &dwSize))
printf("Error %u in WinHttpQueryDataAvailable.\n",GetLastError());

// Allocate space for the buffer.
pszOutBuffer = new char[dwSize+1];
if (!pszOutBuffer)
{
printf("Out of memory\n");
dwSize=0;
}
else
{
// Read the Data.
ZeroMemory(pszOutBuffer, dwSize+1);

if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer,
dwSize, &dwDownloaded))
printf("Error %u in WinHttpReadData.\n", GetLastError());
else
printf("%s",pszOutBuffer);

// Free the memory allocated to the buffer.
delete [] pszOutBuffer;
}

} while (dwSize>0);

// Close open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
}

return 0;
};

Part of the server code (taken from msdn):
I use the following function as a listner:

result = HttpReceiveHttpRequest(
hReqQueue,
requestId,
HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY,
pRequest,
RequestBufferLength,
&bytesRead,
NULL
);

And for each request do

if(pRequest->Flags & HTTP_REQUEST_FLAG_MORE_ENTITY_BODY_EXISTS)
{

if(GetTempFileName(L".\",L"New",0, szTempName) == 0)
{
result = GetLastError();
wprintf(L"GetTempFileName failed with %lu \n", result);
goto Done;
}

hTempFile = CreateFile(szTempName, GENERIC_READ | ENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

if(hTempFile == INVALID_HANDLE_VALUE)
{
result = GetLastError();
wprintf(L"Could not create temporary file. Error %lu \n", result);
goto Done;
}

do
{
//
// Read the entity chunk from the request.
//
BytesRead = 0;
result = HttpReceiveRequestEntityBody(
hReqQueue,
pRequest->RequestId,
0,
pEntityBuffer,
EntityBufferLength,
&BytesRead,
NULL
);

switch(result)
{
case NO_ERROR:

if(BytesRead != 0)
{
TotalBytesRead += BytesRead;
WriteFile(
hTempFile,
pEntityBuffer,
BytesRead,
&TempFileBytesWritten,
NULL
);

}
break;

case ERROR_HANDLE_EOF:


if(BytesRead != 0)
{
TotalBytesRead += BytesRead;
WriteFile(
hTempFile,
pEntityBuffer,
BytesRead,
&TempFileBytesWritten,
NULL
);
}



StringCchPrintfA(
szContentLength,
sizeof(szContentLength),
"%lu",
TotalBytesRead
);

ADD_KNOWN_HEADER(
response,
HttpHeaderContentLength,
szContentLength
);

result =
HttpSendHttpResponse(
hReqQueue, // ReqQueueHandle
pRequest->RequestId, // Request ID
HTTP_SEND_RESPONSE_FLAG_MORE_DATA,
&response, // HTTP response
NULL, // pReserved1
&bytesSent, // bytes sent (optional)
NULL, // pReserved2
0, // Reserved3
NULL, // LPOVERLAPPED
NULL // pReserved4
);

if(result != NO_ERROR)
{
wprintf(L"HttpSendHttpResponse failed with %lu \n",
result);
goto Done;
}

//
// Send entity body from a file handle.
//
dataChunk.DataChunkType =
HttpDataChunkFromFileHandle;

dataChunk.FromFileHandle.
ByteRange.StartingOffset.QuadPart = 0;

dataChunk.FromFileHandle.
ByteRange.Length.QuadPart = HTTP_BYTE_RANGE_TO_EOF;

dataChunk.FromFileHandle.FileHandle = hTempFile;

result = HttpSendResponseEntityBody(
hReqQueue,
pRequest->RequestId,
0, // This is the last
send.
1, // Entity Chunk Count.
&dataChunk,
NULL,
NULL,
0,
NULL,
NULL
);

if(result != NO_ERROR)
{
wprintf(
L"HttpSendResponseEntityBody failed with %lu \n",
result
);
}

goto Done;

break;


default:
wprintf(L"HttpReceiveRequestEntityBody failed with %lu
\n",
result);
goto Done;
}

} while(TRUE);
}
else
{
// This request does not have any entity body.
//

result = HttpSendHttpResponse(
hReqQueue, // ReqQueueHandle
pRequest->RequestId, // Request ID
0,
&response, // HTTP response
NULL, // pReserved1
&bytesSent, // bytes sent (optional)
NULL, // pReserved2
0, // Reserved3
NULL, // LPOVERLAPPED
NULL // pReserved4
);
if(result != NO_ERROR)
{
wprintf(L"HttpSendHttpResponse failed with %lu \n", result);
}
}

Done:

if(pEntityBuffer)
{
FREE_MEM(pEntityBuffer);
}

if(INVALID_HANDLE_VALUE != hTempFile)
{
CloseHandle(hTempFile);
//DeleteFile(szTempName);
}

return result;
}

.



Relevant Pages

  • Re: HTTP server problem when running two clients
    ... I don't see how you allocate buffer on the server side. ... When I run the HTTP server with one client it works ok. ... HINTERNET hRequest = NULL; ... // Create an HTTP Request handle. ...
    (microsoft.public.win32.programmer.networks)
  • [NT] Multiple Vulnerabilities in PY Software Active Webcam WebServer
    ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... including Denial of Service and Information Disclosure. ... Floppy Disk Request Denial of Service: ... be paused, that means the other user cannot access the HTTP Server, thus ...
    (Securiteam)
  • HTTP client socket inputstream help
    ... resource from an http server. ... the InputStream from the socket is coming up empty after requesting the ... the request has been received from the http server because I'm also ...
    (comp.lang.java.programmer)
  • HTTP SERVER (httpsv1.6.2) 404 Denial of Service
    ... HTTP SERVER 404 Denial of Services ... If u send to the server between 40-1000 requests to nonexisting pages the process will die. ... Bug Found By Prili - impriligmail.com ... print $socket $request; ...
    (Bugtraq)
  • Re: interconnection between two processes
    ... PB> The HTTP server will fork a new CGI process for each request. ... PB> - unix sockets ...
    (comp.unix.programmer)

Loading