I have some code (its actually for sending SMS messages via a web interface, but that's not relevant). The code works fine in the absence of a proxy server, but one customer wants to use this configuration. I've been testing with our proxy, but can't get it working. When slogging through the help, I found MSKB article 195650 (How To Handle Proxy Authorization with WinInet), which contains this pearl of wisdom:
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...
...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.
So I implemented this solution in my code, detecting the 407 error from a proxy requiring authentication, and then supplying the basic authentication via SetOption calls:
if (AfxParseURL (m_csServerUrl, dwServiceType, csServerName, csObjectName, nPort))
{
CString csProxy = m_pOwner->GetProxyServerSetting();
if (csProxy.GetLength() > 0)
{
pSession = new CMyInternetSession (TEXT("SmGen"),
1,
INTERNET_OPEN_TYPE_PROXY,
csProxy,
NULL,
INTERNET_FLAG_KEEP_CONNECTION);
}
else
{
pSession = new CMyInternetSession (TEXT("SmGen"),
1,
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
0);
}
if (pSession)
{
pSession->SetOwnerDialog (m_pOwner);
pHttpConn = pSession->GetHttpConnection (csServerName, (INTERNET_PORT)nPort, NULL, NULL);
if (pHttpConn)
{
dwFlags = INTERNET_FLAG_RELOAD |
INTERNET_FLAG_DONT_CACHE;
pHttpFile = pHttpConn->OpenRequest (CHttpConnection::HTTP_VERB_GET,
csObjectName + TEXT("?") + csHTTP,
NULL,
1,
NULL,
NULL,
dwFlags);
if (pHttpFile)
{
pHttpFile->AddRequestHeaders (csHeaders);
if (pHttpFile->SendRequest ())
{
pHttpFile->QueryInfoStatusCode (dwResult);
bRetryWithAuth = FALSE;
switch (dwResult)
{
case HTTP_STATUS_OK:
// log success
break;
case HTTP_STATUS_PROXY_AUTH_REQ:
bRetryWithAuth = TRUE;
break;
default:
// log failure
break;
}
if (bRetryWithAuth)
{
csProxyUsr = m_pOwner->GetProxyUsername();
csProxyPwd = m_pOwner->GetProxyPassword();
pHttpConn->SetOption (INTERNET_OPTION_PROXY_USERNAME,
csProxyUsr.GetBuffer(1),
csProxyUsr.GetLength());
csProxyUsr.ReleaseBuffer();
pHttpConn->SetOption (INTERNET_OPTION_PROXY_PASSWORD,
csProxyPwd.GetBuffer(1),
csProxyPwd.GetLength());
csProxyPwd.ReleaseBuffer();
if (pHttpFile->SendRequest ())
{
// ... TIMEOUT
Now for the problem. The issue is that the second SendRequest doesn't fail or throw another error, it just times out. After a little while I get CInternetException 12002 (timeout) thrown via my wrapper handler. This is a little annoying. Needless to say, the SMS never arrives.
The proxy server address is of the form a.b.c.d:8080 to eliminate DNS as a causative factor. My MIS department assures me that the username and password I'm supplying are valid (if I pass a bad uid/pwd it simply reverts to a 407 error, so I know they're getting to the proxy, at least).
I've been through everything I can find both on here and online, and I'm getting nowhere. Simply using INTERNET_OPEN_TYPE_PRECONFIG and hoping that the system will fetch everything it needs automagically doesn't work if all you have is a proxy, sadly.
Remember, there's nothing wrong with the non-proxy-related functionality of the code, because if I eliminate the proxy by wiping the registry entry that supplies the server ip:port, it all leaps into life again.
I'm completely stumped. Has anyone seen this before? I'm not hopeful, given the number of queries about proxy authentication with no replies...
Edit:
I've converted this code to use WinHttp, since there is an MS sample which covers proxy (with authentication), and WinInet is deprecated anyway. All works fine now.