CHttpFile problem

I'd like to write a program to download files using CHttpFile. I have no problem downloading text files (html, txt). But when trying to download binary file (like jpg, gif), I can only download a fraction of it. Here is the relevant code (error checking code has been omitted):


CWinApp* pApp = ::AfxGetApp();
CInternetSession session(::AfxGetAppName(), 1, PRE_CONFIG_INTERNET_ACCESS);
CHttpConnection* pServer = NULL;
CHttpFile* pFile = NULL;
LPCTSTR rtype = "*/*";
CString strServerName = "www.myserver.com";
CString strObject = "test.jpg";
INTERNET_PORT nPort = 80;
pServer = session.GetHttpConnection(strServerName, nPort);                  
pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET, strObject, NULL, 1, &rtype, NULL, INTERNET_FLAG_EXISTING_CONNECT | INTERNET_FLAG_NO_AUTO_REDIRECT);
pFile->SendRequest();
char sz[1024];
CString filename = pFile->GetFileName();
ofstream filestream((LPCTSTR)filename, ios::out, ios::binary);
while (pFile->Read(sz, 1023))
{
      filestream << sz;
}
cout << (LPCTSTR)filename;
                  
filestream.close();
pFile->Close();
pServer->Close();
wyldsjAsked:
Who is Participating?
 
mikeblasConnect With a Mentor Commented:

The immediate problem is that you're misusing filestream. The put-to operator takes a null-terminated string, but you want to write a block of bytes. So, what ends up happening is that you read 1023 bytes from your internet connection and then write only up to the first null terminated character in that block.

Further, your constructor to build filestream is wrong. You need to or together the ios::values you use. Passing ios::binary for the 3rd parameter is bogus. The third parameter is for protection flags, not file type flags.

So, the fixed code looks like this:

   ofstream filestream((LPCTSTR) filename, ios::out | ios::binary);

   int nRead;
   while ( (nRead = pFile->Read(sz, 1023)) > 0)
   {
      filestream.write(sz, nRead);
   }

And that fixes your problem.

There's lots more I'd call "wrong" with your code, though.

Why are you using ofstream in the first place? CFile is already linked into your application, and it would do this job in a grand fashion. In fact, you'll find it to be far more efficient than ofstream in this application. You should use it, instead.

More glaringly, you don't catch any exectpions. All of the functions you're calling in MFC, and even those in ofstream, can throw exceptions. Essentially, this is as bad as not checking error return codes.

..B ekiM
0
 
wyldsjAuthor Commented:
Thanks so much mikeblas! This is the best answer I've ever got in expert-exchange :) I learnt much more than the question itself.
0
 
mikeblasCommented:
Thank you for your kind words.  It's easy to provide clear help in response to a concise and specific question.

..B ekiM
0
All Courses

From novice to tech pro — start learning today.