PRB: CInternetSession::OpenURL() Fails with File Protocol

Last reviewed: August 12, 1997
Article ID: Q172551
The information in this article applies to:
  • The Microsoft Foundation Classes (MFC) included with: - Microsoft Visual C++, 32-bit Editions, version 5.0

SYMPTOMS

CInternetSession::OpenURL() fails if you use a URL that specifies a file that contains spaces or other unsafe characters. For example, the following will fail:

   CMyInternetSession s("");
   CStdioFile* p = s.OpenURL("file://c:/temp/Text Document.txt");

As a result, a File Exception is thrown and the following message appears:

   c:\temp\Text%20Document.txt was not found.

CAUSE

The specifications for a URL designate certain characters that must be escaped when they are present in a URL. The space character is one of the characters that must be escaped.

The function CInternetSession::OpenURL() calls a function that converts unsafe characters in the URL to their escape sequences before processing the URL further. If the URL is using the file protocol it creates a CStdioFile and returns a pointer to this object. However, CStdioFile does not understand the escaped path and, as a result, an exception is thrown.

RESOLUTION

When you use the file protocol, you must not convert unsafe characters to their escape sequences. The following code demonstrates how to do this by writing a CInternetSession derived class to override OpenURL().

   // class definition
   class CMyInternetSession : CInternetSession
   {
   public:
      CMyInternetSession::CMyInternetSession(LPCTSTR pstrAgent = NULL,
         DWORD dwContext = 1, DWORD dwAccessType =
         PRE_CONFIG_INTERNET_ACCESS, LPCTSTR pstrProxyName = NULL,
         LPCTSTR pstrProxyBypass = NULL, DWORD dwFlags = 0);

      CStdioFile* CMyInternetSession::OpenURL(LPCTSTR pstrURL,
         DWORD dwContext = 1, DWORD dwFlags =
         INTERNET_FLAG_TRANSFER_ASCII, LPCTSTR pstrHeaders = NULL,
         DWORD dwHeadersLength = 0);
   };

   // CMyInternetSession constructor
   CMyInternetSession::CMyInternetSession(LPCTSTR pstrAgent,
      DWORD dwContext, DWORD dwAccessType, LPCTSTR pstrProxyName,
      LPCTSTR pstrProxyBypass, DWORD dwFlags)
   {
      CInternetSession(pstrAgent, dwContext, dwAccessType, pstrProxyName,
         pstrProxyBypass, dwFlags);
   }

   CStdioFile* CMyInternetSession::OpenURL(LPCTSTR pstrURL,
      DWORD dwContext, DWORD dwFlags, LPCTSTR pstrHeaders,
      DWORD dwHeadersLength)
   {
      ASSERT(pstrURL != NULL);
      ASSERT(dwHeadersLength == 0 || pstrHeaders != NULL);

      // must have TRANSFER_BINARY or TRANSFER_ASCII but not both
      #define _AFX_TRANSFER_MASK (INTERNET_FLAG_TRANSFER_BINARY \
         | INTERNET_FLAG_TRANSFER_ASCII)

      ASSERT((dwFlags & _AFX_TRANSFER_MASK) != 0);
      ASSERT((dwFlags & _AFX_TRANSFER_MASK) != _AFX_TRANSFER_MASK);

      DWORD dwServiceType;
      CString strServer;
      CString strObject;
      INTERNET_PORT nPort;

      BOOL bParsed = AfxParseURL(pstrURL, dwServiceType,
         strServer, strObject, nPort);

      // if it turns out to be a file...
      if (bParsed && dwServiceType == AFX_INET_SERVICE_FILE)
      {
         CString userName;
         CString password;

         // Get the normalized file name with out converting
         // unsafe characters to escape sequence.

         AfxParseURLEx(pstrURL, dwServiceType, strServer,
            strObject, nPort, userName, password, ICU_NO_ENCODE);

         int nMode = CFile::modeRead | CFile::shareCompat;
         if (dwFlags & INTERNET_FLAG_TRANSFER_BINARY)
            nMode |= CFile::typeBinary;
         else
            nMode |= CFile::typeText;

         return new CStdioFile(strObject, nMode);
      }

      return CInternetSession::OpenURL(pstrURL,   dwContext, dwFlags,
         pstrHeaders, dwHeadersLength);
   }

REFERENCES

The specification for URL's are published by The World Wide Web Consortium (W3C). The specifications define the escape sequences and unsafe characters. Its URL is:

   http://www.w3.org/

NOTE: Web links may change without notice.


Additional query words: 4.20b space file OpenURL filename
Keywords : MfcMisc kbcode kberrmsg
Version : WINDOWS NT:5.0
Platform : NT WINDOWS
Issue type : kbprb


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: August 12, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.