Discussion:
using wininet to upload file for a password protected server
(too old to reply)
Oded
2008-02-18 21:42:00 UTC
Permalink
Hi,
I'm trying to use the wininet for uploading file to a server which requires
authentication. i checked a bit in the web and found that i have to first use
an empty request to perform the authentication and only afterward on the same
request send the data.
problem is - if i do that, the second request is sent empty (but it passes
the authentication), if i don't, the request is sent without the
authentication data (and failed).
any idea why?

here is the code:
hSession = InternetOpen("Test",
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
0);


hConnection = InternetConnect( hSession,
server, // Server
INTERNET_INVALID_PORT_NUMBER,
NULL, // Username
NULL, // Password
INTERNET_SERVICE_HTTP,
0, // Synchronous
NULL); // No Context


INTERNET_BUFFERS BufferIn = {0};
DWORD dwBytesRead;
DWORD dwBytesWritten;
BYTE pBuffer[1024]; // Read from file in 1K chunks
BOOL bRead, bRet;

BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS );

HINTERNET hRequest = HttpOpenRequest(hConnection, "POST", targetURL, NULL,
NULL, NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE |
INTERNET_FLAG_KEEP_CONNECTION, 0);
if (!hRequest)
return OnExit(GetLastError());

// cchUserLength is the length of strUsername and
// cchPasswordLength is the length of strPassword.
char strUsername[64], strPassword[64];
strcpy (strUsername,"username");
strcpy (strPassword,"password");

DWORD cchUserLength = sizeof(strUsername);
DWORD cchPasswordLength = sizeof(strUsername);
InternetSetOption(hRequest, INTERNET_OPTION_USERNAME, strUsername,
cchUserLength+1);
InternetSetOption(hRequest, INTERNET_OPTION_PASSWORD, strPassword,
cchPasswordLength+1);

// at this point normal authentication logic can be used. If
// credentials are supplied in InternetConnect, then Wininet will
// resubmit credentials itself. See HttpDump Internet Client SDK sample
// for more information.
if (!HttpSendRequest (hRequest, NULL, 0, NULL, 0))
return OnExit(GetLastError());


// Read all returned data with InternetReadFile ()
do
{
InternetReadFile (hRequest, pBuffer, sizeof(pBuffer), &dwBytesRead);
}
while ( dwBytesRead != 0);


HANDLE hFile = CreateFile (uploadFile, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return OnExit(GetLastError());

BufferIn.dwBufferTotal = GetFileSize (hFile, NULL);

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


DWORD sum = 0;
do
{
if (!(bRead = ReadFile (hFile, pBuffer, sizeof(pBuffer), &dwBytesRead,
NULL)))
break;

if (!(bRet=InternetWriteFile( hRequest, pBuffer, dwBytesRead,
&dwBytesWritten)))
break;

sum += dwBytesWritten;
progress = sum;
}
while (dwBytesRead == sizeof(pBuffer)) ;

CloseHandle (hFile);

if(!HttpEndRequest(hRequest, NULL, 0, 0))
return OnExit(GetLastError());

return OnExit(0);
Paul Baker [MVP, Windows - SDK]
2008-02-18 21:58:34 UTC
Permalink
If you have a reference to the instructions you found, please post it here
so that we may assess whether or not it is accurate.

The proper reference is this MSDN web page:
http://msdn2.microsoft.com/en-us/library/aa384220.aspx

You should be aware what type of authenticaton you are attempting, where you
will get the credentials from, and make sure you are following the
instructions in this article.

Paul
Post by Oded
Hi,
I'm trying to use the wininet for uploading file to a server which requires
authentication. i checked a bit in the web and found that i have to first use
an empty request to perform the authentication and only afterward on the same
request send the data.
problem is - if i do that, the second request is sent empty (but it passes
the authentication), if i don't, the request is sent without the
authentication data (and failed).
any idea why?
hSession = InternetOpen("Test",
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
0);
hConnection = InternetConnect( hSession,
server, // Server
INTERNET_INVALID_PORT_NUMBER,
NULL, // Username
NULL, // Password
INTERNET_SERVICE_HTTP,
0, // Synchronous
NULL); // No Context
INTERNET_BUFFERS BufferIn = {0};
DWORD dwBytesRead;
DWORD dwBytesWritten;
BYTE pBuffer[1024]; // Read from file in 1K chunks
BOOL bRead, bRet;
BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS );
HINTERNET hRequest = HttpOpenRequest(hConnection, "POST", targetURL, NULL,
NULL, NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE |
INTERNET_FLAG_KEEP_CONNECTION, 0);
if (!hRequest)
return OnExit(GetLastError());
// cchUserLength is the length of strUsername and
// cchPasswordLength is the length of strPassword.
char strUsername[64], strPassword[64];
strcpy (strUsername,"username");
strcpy (strPassword,"password");
DWORD cchUserLength = sizeof(strUsername);
DWORD cchPasswordLength = sizeof(strUsername);
InternetSetOption(hRequest, INTERNET_OPTION_USERNAME, strUsername,
cchUserLength+1);
InternetSetOption(hRequest, INTERNET_OPTION_PASSWORD, strPassword,
cchPasswordLength+1);
// at this point normal authentication logic can be used. If
// credentials are supplied in InternetConnect, then Wininet will
// resubmit credentials itself. See HttpDump Internet Client SDK sample
// for more information.
if (!HttpSendRequest (hRequest, NULL, 0, NULL, 0))
return OnExit(GetLastError());
// Read all returned data with InternetReadFile ()
do
{
InternetReadFile (hRequest, pBuffer, sizeof(pBuffer), &dwBytesRead);
}
while ( dwBytesRead != 0);
HANDLE hFile = CreateFile (uploadFile, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return OnExit(GetLastError());
BufferIn.dwBufferTotal = GetFileSize (hFile, NULL);
if(!HttpSendRequestEx( hRequest, &BufferIn, NULL, HSR_INITIATE, 0))
return OnExit(GetLastError());
DWORD sum = 0;
do
{
if (!(bRead = ReadFile (hFile, pBuffer, sizeof(pBuffer), &dwBytesRead,
NULL)))
break;
if (!(bRet=InternetWriteFile( hRequest, pBuffer, dwBytesRead,
&dwBytesWritten)))
break;
sum += dwBytesWritten;
progress = sum;
}
while (dwBytesRead == sizeof(pBuffer)) ;
CloseHandle (hFile);
if(!HttpEndRequest(hRequest, NULL, 0, 0))
return OnExit(GetLastError());
return OnExit(0);
Oded
2008-02-19 07:58:00 UTC
Permalink
thanks for the quick reply!
anyway, i was following these instructions:
http://support.microsoft.com/kb/194700/en-us
i basically did exatcly the same.
Note that i use digest authentication (not through proxy) and that the
authentication works just fine(!), but the file itself is not reaching the
server side (i use aspx file which is using the InputStream of the request to
receive the file).
Also note -
When i remove the first "empty request" (which is needed for the
authentication) the stream reaches the server just fine (if the
authenticaiton is tuned off), but the authentication is failing (the
"Authorization" header is empty).
Post by Paul Baker [MVP, Windows - SDK]
If you have a reference to the instructions you found, please post it here
so that we may assess whether or not it is accurate.
http://msdn2.microsoft.com/en-us/library/aa384220.aspx
You should be aware what type of authenticaton you are attempting, where you
will get the credentials from, and make sure you are following the
instructions in this article.
Paul
Post by Oded
Hi,
I'm trying to use the wininet for uploading file to a server which requires
authentication. i checked a bit in the web and found that i have to first use
an empty request to perform the authentication and only afterward on the same
request send the data.
problem is - if i do that, the second request is sent empty (but it passes
the authentication), if i don't, the request is sent without the
authentication data (and failed).
any idea why?
hSession = InternetOpen("Test",
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
0);
hConnection = InternetConnect( hSession,
server, // Server
INTERNET_INVALID_PORT_NUMBER,
NULL, // Username
NULL, // Password
INTERNET_SERVICE_HTTP,
0, // Synchronous
NULL); // No Context
INTERNET_BUFFERS BufferIn = {0};
DWORD dwBytesRead;
DWORD dwBytesWritten;
BYTE pBuffer[1024]; // Read from file in 1K chunks
BOOL bRead, bRet;
BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS );
HINTERNET hRequest = HttpOpenRequest(hConnection, "POST", targetURL, NULL,
NULL, NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE |
INTERNET_FLAG_KEEP_CONNECTION, 0);
if (!hRequest)
return OnExit(GetLastError());
// cchUserLength is the length of strUsername and
// cchPasswordLength is the length of strPassword.
char strUsername[64], strPassword[64];
strcpy (strUsername,"username");
strcpy (strPassword,"password");
DWORD cchUserLength = sizeof(strUsername);
DWORD cchPasswordLength = sizeof(strUsername);
InternetSetOption(hRequest, INTERNET_OPTION_USERNAME, strUsername,
cchUserLength+1);
InternetSetOption(hRequest, INTERNET_OPTION_PASSWORD, strPassword,
cchPasswordLength+1);
// at this point normal authentication logic can be used. If
// credentials are supplied in InternetConnect, then Wininet will
// resubmit credentials itself. See HttpDump Internet Client SDK sample
// for more information.
if (!HttpSendRequest (hRequest, NULL, 0, NULL, 0))
return OnExit(GetLastError());
// Read all returned data with InternetReadFile ()
do
{
InternetReadFile (hRequest, pBuffer, sizeof(pBuffer), &dwBytesRead);
}
while ( dwBytesRead != 0);
HANDLE hFile = CreateFile (uploadFile, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return OnExit(GetLastError());
BufferIn.dwBufferTotal = GetFileSize (hFile, NULL);
if(!HttpSendRequestEx( hRequest, &BufferIn, NULL, HSR_INITIATE, 0))
return OnExit(GetLastError());
DWORD sum = 0;
do
{
if (!(bRead = ReadFile (hFile, pBuffer, sizeof(pBuffer), &dwBytesRead,
NULL)))
break;
if (!(bRet=InternetWriteFile( hRequest, pBuffer, dwBytesRead,
&dwBytesWritten)))
break;
sum += dwBytesWritten;
progress = sum;
}
while (dwBytesRead == sizeof(pBuffer)) ;
CloseHandle (hFile);
if(!HttpEndRequest(hRequest, NULL, 0, 0))
return OnExit(GetLastError());
return OnExit(0);
Loading...