Discussion:
wininet problems on windows vista and windows 7
(too old to reply)
Maya
2009-11-16 12:53:01 UTC
Permalink
Hi,
we are using wininet API for HTTP communication to upload files to a
password protected server. all works well, but on windows Vista and windows 7
for some reason we keep getting error 12031
(ERROR_INTERNET_CONNECTION_RESET) when writing the file
(InternetWriteFile call).
A few more details:
- for some reason the content-size is 0, although we call HttpSendRequestEx
with the correct size
- we are able to pass some of the file bytes before we recieve this error.

We created a simple example following the guidelines from the below article:
http://support.microsoft.com/default.aspx/kb/194700/en-us
and we get the same result (see below). Note that all is working ok on XP.
any ideas?

the code we use is:
(argv[1] - the domain, argv[2] - user name, argv[3] - password, argv[4] -
the page, argv[5] - the file)


#include<windows.h>
#include<wininet.h>
#include <iostream>
using namespace std;

//--------------------
// HandleResponse
//--------------------
int HandleResponse(HINTERNET hRequest)
{
// first we look for the status code
char pszBuffer[32];
DWORD dwBufferSize = sizeof(pszBuffer);
BOOL retval = HttpQueryInfo(hRequest,
HTTP_QUERY_STATUS_CODE,
pszBuffer,
&dwBufferSize,
NULL);

// check for failures
if (!retval)
return -1;//kFailed;

// read response
DWORD dwBytesRead;
char result[524288];
char* resultPtr = &result[0];
do
{
if (!InternetReadFile (hRequest, resultPtr, sizeof(result), &dwBytesRead))
break;

resultPtr+=dwBytesRead;
}
while ( dwBytesRead != 0);
resultPtr[0] = '\0';

// check the response code first
int statusCode = atoi(pszBuffer);
if (statusCode == 401)
{
// check if this is authentication failure or password expired case
std::string strResult(result);
if (strResult.find("Password Expired") != std::string::npos)
return -3;//kPasswordExpired;
else
return -2;//kAuthenticationFailed;
}
else if (statusCode >= 400)
return -1;//kFailed;

// check response contains data
return (resultPtr == &result[0]) ? -1/*kFailed*/ : 4/*kSuccess*/;
}

//--------------------
// OnExit
//--------------------
bool OnExit(int newStatus, HINTERNET hRequest, HANDLE hFile)
{
// make sure we close the request if needed
if (hRequest)
{
InternetCloseHandle(hRequest);
hRequest = NULL;
}

// make sure we close the file if needed
if (hFile)
{
CloseHandle(hFile);
hFile = NULL;
}
//return /*newStatus == 4/*kSuccess*/ || newStatus == 0/*kNone*/;*/ status;
return newStatus;
}


//--------------------
// main
//--------------------
//(argv[1] - Server, argv[2] - user name, argv[3] - password, argv[4] -
page, argv[5] - file)
int main(int argc, char *argv[])
{
HINTERNET hSession = InternetOpen("test",
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
0);
// increase the defauls timeout
DWORD dwLength = sizeof(DWORD);
DWORD dwTimeut = 3600000; // 1 hour (3600 seconds)
InternetSetOption(hSession, INTERNET_OPTION_SEND_TIMEOUT, &dwTimeut,
sizeof(DWORD));
InternetSetOption(hSession, INTERNET_OPTION_RECEIVE_TIMEOUT, &dwTimeut,
sizeof(DWORD));


// in case of POST we have to first send a request without credentials
// an only than send the authenticated one (don't ask me why...)
HINTERNET hConnection = InternetConnect( hSession,
argv[1], // Server
INTERNET_INVALID_PORT_NUMBER,
argv[2], // Username
argv[3], // Password
INTERNET_SERVICE_HTTP,
0, // Synchronous
NULL); // No Context

if (!hConnection)
return OnExit(GetLastError(), NULL, NULL);

DWORD flags = INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE |
INTERNET_FLAG_KEEP_CONNECTION;
HINTERNET hRequest = HttpOpenRequest(hConnection, "POST" , argv[4], NULL,
NULL, NULL, flags , 0);
if (!hRequest)
return OnExit(GetLastError(), hRequest, NULL);

// we first send an empty request, it will fail on credentials although we
set it
// only the following request will actually be sent with the credentials
and succeed
INTERNET_BUFFERS BufferIn = {0};
BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS );

DWORD cchUserLength = strlen(argv[2])*sizeof(char);
DWORD cchPasswordLength = strlen(argv[3])*sizeof(char);
InternetSetOption(hRequest, INTERNET_OPTION_USERNAME, (void*)argv[2],
cchUserLength+1);
InternetSetOption(hRequest, INTERNET_OPTION_PASSWORD, (void*)argv[3],
cchPasswordLength+1);

if (!HttpSendRequestEx( hRequest, &BufferIn, NULL, HSR_INITIATE, 0))
return OnExit(GetLastError(), hRequest, NULL);

// this for some reason fails (return false) when IE6 is installed (IE7
works fine)
// so we ignore the return value, since we do not care much about it
HttpEndRequest(hRequest, NULL, 0, 0);

// we only allow authentication failure. otherwise it might be conenciton
problems etc.
int result = HandleResponse(hRequest);
if (result != -2/*kAuthenticationFailed*/)
return OnExit(GetLastError(), hRequest, NULL);

// count the number of attempts
int attempts = 0;

again:
attempts++;

cout << "file path: " << endl;
cout << argv[5] << endl;

// now send the initial request (asynchroniously)
HANDLE hFile = CreateFile (argv[5], GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return OnExit(GetLastError(), hRequest, hFile);

BufferIn.dwBufferTotal = GetFileSize (hFile, NULL);

cout << "File size" << endl;
cout << BufferIn.dwBufferTotal << endl;

if (!HttpSendRequestEx( hRequest, &BufferIn, NULL, HSR_INITIATE, 0))
return OnExit(GetLastError(), hRequest, hFile);

DWORD dwBytesRead;
DWORD dwBytesWritten;
BYTE pBuffer[16*1024]; // Read from file in 1K chunks
BOOL bRead, bRet;

// now start in loop to write data
DWORD totalSent = 0;
do
{
if (!(bRead = ReadFile (hFile, pBuffer, sizeof(pBuffer), &dwBytesRead,
NULL)))
{
cout << "Failed to read data" << endl;
cout << GetLastError() << endl;
break;
}

if (!(bRet=InternetWriteFile( hRequest, pBuffer, dwBytesRead,
&dwBytesWritten)))
{
cout << "Failed to send data" << endl;
cout << GetLastError() << endl;
break;
}

totalSent += dwBytesWritten;
//progress = totalSent * 100 / BufferIn.dwBufferTotal;
}
while (dwBytesRead == sizeof(pBuffer)) ;

cout << "totalSent" << endl;
cout << totalSent << endl;

CloseHandle (hFile);
hFile = NULL;

if(!HttpEndRequest(hRequest, NULL, 0, 0))
{
// we allow up to 3 attempts
int lastError = GetLastError();
if ( ERROR_INTERNET_FORCE_RETRY == lastError && attempts < 3)
{
goto again;
}

return OnExit(lastError, hRequest, hFile);
}
else
{
// currentStatus = kInProgress;
cout << OnExit(HandleResponse(hRequest), hRequest, hFile) << endl;
return OnExit(HandleResponse(hRequest), hRequest, hFile);
}
}
DU
2013-04-15 13:47:01 UTC
Permalink
Hey, did you found any solution?? Even i'm facing similar kind of problem....my HTTP upload is working on XP but on Win7 its not :( and on Win7 InternetWriteFile function of WinInet library is succeeding but not able to write.
Loading...