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?
Code:
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:
Code:
result = HttpReceiveHttpRequest(
hReqQueue,
requestId,
HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY,
pRequest,
RequestBufferLength,
&bytesRead,
NULL
);
Code:
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;
}
