Article ID: 195650
WinInet applications attempting to access files through a proxy that requires a login will fail unless the proxy is provided with a valid username and password. This article will explain the different options available to handle this situation.
For the sake of clarity, error handling has been removed from most of the code in this article. If you use any of this code in your own program, please implement error handling appropriately. As well, anywhere you find "...", code has been removed. Please reference the HttpDump and Tear samples for complete implementations of WinInet coding.
The following code snippet was taken from the HttpDump sample. It illustrates how to capture a proxy authorization request (HTTP_STATUS_PROXY_AUTH_REQ):
A check for HTTP_STATUS_PROXY_AUTH_REQ can be added to the Tear MFC sample to check for HTTP_STATUS_PROXY_AUTH_REQ:
Both samples can successfully handle HTTP_STATUS_PROXY_AUTH_REQ by providing a user interface to collect the username and password for proxy authorization. The HttpDump sample does so with the following code:
WinInet will query hReq to determine the type of error and in the case of HTTP_STATUS_PROXY_AUTH_REQ, will present the user with the dialog box to collect the username and password for proxy authorization.
MFC wraps the InternetErrorDlg call and will attempt the proxy authorization with the following code:
Unfortunately, CHttpFile::ErrorDlg is broken in the MFC that ships with Visual C++ versions prior to 6.0. For additional information on how to call InternetErrorDlg from an MFC application, please see the following article in the Microsoft Knowledge Base:
189094The drawback of the using InternetErrorDlg is that the function call displays a user interface. In some cases, this is not desirable.
(http://support.microsoft.com/kb/189094/EN-US/ )Calling CHttpFile::ErrorDlg Function Causes Errors 127 & 2
There are several ways to handle HTTP_STATUS_PROXY_AUTH_REQ without displaying a user interface. By far the easiest way to do this is by using the InternetSetOption function with the flags INTERNET_OPTION_PROXY_PASSWORD and INTERNET_OPTION_PROXY_USERNAME. This option can be used only on clients that have Internet Explorer 4.0 or later loaded as the WinInet that shipped before Internet Explorer 4.0 did not implement this functionality. It will also be necessary to link with the updated WinInet.h and WinInet.lib from the Internet Client SDK or Microsoft Platform SDK. The following code illustrates how to implement this functionality with straight WinInet:
The same functionality can be accomplished in an MFC application by detecting HTTP_STATUS_PROXY_AUTH_REQ, calling CHttpConnection::SetOption, then re-calling CHttpFile::SendRequest.
If the client computer does not have Internet Explorer 4 installed, a good deal more work will be necessary to avoid using InternetErrorDlg. In this case, it will be necessary to Base64 encrypt the proxy username and password and add the Proxy-Authorization header as follows. In this example, "wWdkd2284lwwdj" is a Base64 encrypted user username:password combination.
A sample is available that implements a Base54 encryption algorithm. For additional information, see the following article in the Microsoft Knowledge Base:
191239The format of the username and password that needs to be encrypted is "username:password" including the colon. Please reference RFC2068 - "Hypertext Transfer Protocol -- HTTP/1.1" for further details on this.
(http://support.microsoft.com/kb/191239/EN-US/ )SAMPLE: Sample Base 64 Encoding and Decoding
MFC WinInet applications can implement the same functionality. To do so, the application should call CHttpFile::AddRequestHeaders and add the Proxy- Authorization header as above. The application should then resubmit the request with CHttpFile::SendRequest.
RFC 2068 / Hypertext Transfer Protocol -- HTTP/1.1
(c) Microsoft Corporation 1998, All Rights Reserved. Contributions by Robert Duke, Microsoft Corporation
Article ID: 195650 - Last Review: June 22, 2014 - Revision: 3.0