How To Handle Proxy Authorization with WinInet

Retired KB Content Disclaimer
This article was written about products for which Microsoft no longer offers support. Therefore, this article is offered "as is" and will no longer be updated.
WinInet applications attempting to access files through a proxy thatrequires a login will fail unless the proxy is provided with a validusername and password. This article will explain the different optionsavailable to handle this situation.
More information
For the sake of clarity, error handling has been removed from most of thecode 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 Tearsamples for complete implementations of WinInet coding.

The following code snippet was taken from the HttpDump sample. Itillustrates how to capture a proxy authorization request(HTTP_STATUS_PROXY_AUTH_REQ):

HttpSendRequest (hReq, NULL, 0, NULL, 0);HttpQueryInfo (hReq, HTTP_QUERY_STATUS_CODE |      HTTP_QUERY_FLAG_NUMBER, &dwCode, &dwSize, NULL);if (dwCode == HTTP_STATUS_PROXY_AUTH_REQ)				

A check for HTTP_STATUS_PROXY_AUTH_REQ can be added to the Tear MFC sampleto check for HTTP_STATUS_PROXY_AUTH_REQ:
pFile->SendRequest();pFile->QueryInfoStatusCode(dwRet);if (dwRet == HTTP_STATUS_PROXY_AUTH_REQ)				

Both samples can successfully handle HTTP_STATUS_PROXY_AUTH_REQ byproviding a user interface to collect the username and password for proxyauthorization. The HttpDump sample does so with the following code:

WinInet will query hReq to determine the type of error and in the case ofHTTP_STATUS_PROXY_AUTH_REQ, will present the user with the dialog box tocollect the username and password for proxy authorization.

MFC wraps the InternetErrorDlg call and will attempt the proxyauthorization with the following code:

Unfortunately, CHttpFile::ErrorDlg is broken in the MFC that ships withVisual C++ versions prior to 6.0. For additional information on how to callInternetErrorDlg from an MFC application, please see the following articlein the Microsoft Knowledge Base:
189094 Calling CHttpFile::ErrorDlg Function Causes Errors 127 & 2
The drawback of the using InternetErrorDlg is that the function calldisplays a user interface. In some cases, this is not desirable.

There are several ways to handle HTTP_STATUS_PROXY_AUTH_REQ withoutdisplaying a user interface. By far the easiest way to do this is by usingthe InternetSetOption function with the flagsINTERNET_OPTION_PROXY_PASSWORD and INTERNET_OPTION_PROXY_USERNAME. Thisoption can be used only on clients that have Internet Explorer 4.0 or laterloaded as the WinInet that shipped before Internet Explorer 4.0 did notimplement this functionality. It will also be necessary to link with theupdated WinInet.h and WinInet.lib from the Internet Client SDK or MicrosoftPlatform SDK. The following code illustrates how to implement thisfunctionality with straight WinInet:
if (dwCode == HTTP_STATUS_PROXY_AUTH_REQ)   {      // read the data off the request handle and setup buffer see      // handler HttpDump handler for HTTP_STATUS_DENIED for details      ...       InternetSetOption (hConnect, INTERNET_OPTION_PROXY_USERNAME,            (LPVOID) szUser, lstrlen (szUser);      InternetSetOption (hConnect, INTERNET_OPTION_PROXY_PASSWORD,            (LPVOID) szPass, lstrlen (szPass);       // calls HttpSendRequest again - see HttpDump      goto again;				

The same functionality can be accomplished in an MFC application bydetecting 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 gooddeal more work will be necessary to avoid using InternetErrorDlg. In thiscase, it will be necessary to Base64 encrypt the proxy username andpassword and add the Proxy-Authorization header as follows. In thisexample, "wWdkd2284lwwdj" is a Base64 encrypted user username:passwordcombination.
char* rangeHeader = "Proxy-Authorization: Basic wWdkd2284lssdj\r\n";DWORD dwBuffSize = strlen(rangeHeader);if (dwCode == HTTP_STATUS_PROXY_AUTH_REQ){   HttpAddRequestHeaders(hReq, rangeHeader, dwBuffSize,           HTTP_ADDREQ_FLAG_ADD );   // calls HttpSendRequest again - see HttpDump   goto again;				

A sample is available that implements a Base54 encryption algorithm. Foradditional information, see the following article in the MicrosoftKnowledge Base:
191239 SAMPLE: Sample Base 64 Encoding and Decoding
The 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.

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 therequest with CHttpFile::SendRequest.
RFC 2068 / Hypertext Transfer Protocol -- HTTP/1.1

(c) Microsoft Corporation 1998, All Rights Reserved. Contributions byRobert Duke, Microsoft Corporation

Article ID: 195650 - Last Review: 06/22/2014 19:21:00 - Revision: 3.0

  • kbhowto KB195650