Solved

Retrieving a file through http

Posted on 1997-10-28
2
252 Views
Last Modified: 2013-11-20
I'm trying to retrieve a file off a web site using MFC,
can you explain how to open a connection and retrieve a
specific file (in this case it's a JPEG graphics file).
0
Comment
Question by:nicholso
  • 2
2 Comments
 
LVL 2

Accepted Solution

by:
wpinto earned 100 total points
ID: 1309006
Hi nicholso,

Please look at the code below, it does what you want it to do. The argument to the function should a URL eg: http://www...
Note the http:// is necessary.

This code has been taken from the Tear example which comes with MFC & has been slightly modified to suit your needs.

This code is self-explanatory, please let me know if you face any problems while implementing it

You could also have a look at the Tear example

Hope this helps

Wilfred

------------------------------------------------------------------------------------------

BOOL GetFileFromNet(CString pszURL)
{
      BOOL bRetCode = TRUE;

      CHttpConnection* pServer = NULL;
      CHttpFile* pFile = NULL;
      CString strNewFileName("");

      try
      {
            // check to see if this is a reasonable URL

            CString strServerName;
            CString strObject;
            INTERNET_PORT nPort;
            DWORD dwServiceType;

            if (!AfxParseURL(pszURL, dwServiceType, strServerName, strObject, nPort) ||
                  dwServiceType != INTERNET_SERVICE_HTTP)
            {
                  cerr << _T("Error: can only use URLs beginning with http://") << endl;
                  return FALSE;
            }

            if (bProgressMode)
            {
                  cerr << _T("Opening Internet...");
                  VERIFY(session.EnableStatusCallback(TRUE));
            }

            // Retrieve the name of the file
            int index = strObject.ReverseFind('/');
            strNewFileName = strObject.Mid(index+1);

            // connect
            pServer = session.GetHttpConnection(strServerName, nPort);

            // request for file
            pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET,
                  strObject, NULL, 1, NULL, NULL, dwHttpRequestFlags);
            pFile->AddRequestHeaders(szHeaders);
            pFile->SendRequest();

            DWORD dwRet;
            pFile->QueryInfoStatusCode(dwRet);

            // if access was denied, prompt the user for the password

            if (dwRet == HTTP_STATUS_DENIED)
            {
                  DWORD dwPrompt;
                  dwPrompt = pFile->ErrorDlg(NULL, ERROR_INTERNET_INCORRECT_PASSWORD,
                        FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, NULL);

                  // if the user cancelled the dialog, bail out

                  if (dwPrompt != ERROR_INTERNET_FORCE_RETRY)
                  {
                        cerr << _T("Access denied: Invalid password\n");
                        return FALSE;
                  }

                  pFile->SendRequest();
                  pFile->QueryInfoStatusCode(dwRet);
            }

            CString strNewLocation;
            pFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strNewLocation);

            // were we redirected?
            // these response status codes come from WININET.H

            if (dwRet == HTTP_STATUS_MOVED ||
                  dwRet == HTTP_STATUS_REDIRECT ||
                  dwRet == HTTP_STATUS_REDIRECT_METHOD)
            {
                  CString strNewLocation;
                  pFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strNewLocation);

                  int nPlace = strNewLocation.Find(_T("Location: "));
                  if (nPlace == -1)
                  {
                        cerr << _T("Error: Site redirects with no new location") << endl;
                        return FALSE;
                  }

                  strNewLocation = strNewLocation.Mid(nPlace + 10);
                  nPlace = strNewLocation.Find('\n');
                  if (nPlace > 0)
                        strNewLocation = strNewLocation.Left(nPlace);

                  // close up the redirected site

                  pFile->Close();
                  delete pFile;
                  pServer->Close();

                  if (bProgressMode)
                  {
                        cerr << _T("Caution: redirected to ");
                        cerr << (LPCTSTR) strNewLocation << endl;
                  }

                  // figure out what the old place was
                  if (!AfxParseURL(strNewLocation, dwServiceType, strServerName, strObject, nPort))
                  {
                        cerr << _T("Error: the redirected URL could not be parsed.") << endl;
                        return FALSE;
                  }

                  if (dwServiceType != INTERNET_SERVICE_HTTP)
                  {
                        cerr << _T("Error: the redirected URL does not reference a HTTP resource.") << endl;
                        return FALSE;
                  }

                  // try again at the new location
                  pServer = session.GetHttpConnection(strServerName, nPort);
                  pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET,
                        strObject, NULL, 1, NULL, NULL, dwHttpRequestFlags);
                  pFile->AddRequestHeaders(szHeaders);
                  pFile->SendRequest();

                  pFile->QueryInfoStatusCode(dwRet);
                  if (dwRet != HTTP_STATUS_OK)
                  {
                        cerr << _T("Error: Got status code ") << dwRet << endl;
                        return FALSE;
                  }
            }

            cerr << _T("Status Code is ") << dwRet << endl;

            if (!strNewFileName.IsEmpty())
            {
                  // create new file
                  CFile pNewFile;
                  pNewFile.Open("c:\\temp\\"+ strNewFileName, CFile::modeCreate | CFile::modeWrite);

                  long nRead=0;
                  char sz[1024];

                  nRead = pFile->Read(sz, 1023);
                  while (nRead > 0)
                  {
                        pNewFile.Write(sz, nRead);
                        nRead = pFile->Read(sz, 1023);
                  }

                  pNewFile.Close();
            }

            pFile->Close();
            pServer->Close();
      }
      catch (CInternetException* pEx)
      {
            // catch errors from WinINet

            TCHAR szErr[1024];
            pEx->GetErrorMessage(szErr, 1024);

            cerr << _T("Error: (") << pEx->m_dwError << _T(") ");
            cerr << szErr << endl;

            bRetCode = FALSE;
            pEx->Delete();
      }

      if (pFile != NULL)
            delete pFile;
      if (pServer != NULL)
            delete pServer;
      session.Close();

      return bRetCode;
}

0
 
LVL 2

Expert Comment

by:wpinto
ID: 1309007
Hi nicholso,

Couple of things I forgot

Please add the following statement just after the try statement
ie.
try
{
      CInternetSession session(_T("Test app"));
      ...

Also remove the following code (in 2 places)
if (bProgressMode)
{
 ...
}

Hope this helps

Wilfred
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Define unique primary key 9 95
maxBlock challenge 30 142
Prevent this page from creating additional dialogs. 3 626
centeredAverage challenge 8 180
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

821 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question