我有一些代碼(它實際上是通過Web界面發送SMS消息,但這不相關)。該代碼在代理服務器的缺席中正常工作,但一個客戶想要使用此配置。我一直在使用我們的代理進行測試,但無法正常工作。當通過幫助下苦讀,我發現MSKB文章195650(如何處理代理授權與WinInet的),其中包含的智慧這顆珍珠:MFC + Wininet +代理身份驗證=問題
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.
所以我實現我的這個代碼的解決方案,檢測來自一個407錯誤代理需要身份驗證,然後通過SetOption調用提供基本身份驗證:
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
現在解決問題。問題是第二個SendRequest不會失敗或拋出另一個錯誤,它只是超出。過了一會兒,我得到了通過我的包裝處理程序拋出的CInternetException 12002(超時)。這有點煩人。不用說,SMS永遠不會到達。
代理服務器地址的格式爲a.b.c.d:8080,以消除DNS作爲致病因素。我的MIS部門向我保證,我提供的用戶名和密碼是有效的(如果我傳遞了錯誤的uid/pwd,它只會回覆到407錯誤,所以我知道他們至少會得到代理)。
我已經經歷過在這裏和在線上都能找到的一切,而且我無處可去。只要使用INTERNET_OPEN_TYPE_PRECONFIG,並希望系統能夠自動獲取所需的所有內容,如果你擁有的只是一個代理服務器,就不會起作用。
請記住,代碼的非代理相關功能沒有任何問題,因爲如果我通過擦除提供服務器ip:port的註冊表項來消除代理,則它將再次躍入生命。
我完全難住了。有沒有人見過這個?我不抱希望,因爲大約有沒有回覆代理認證查詢的數量...
編輯:
我已經轉換該代碼使用WINHTTP,因爲有一個MS樣本覆蓋代理(與身份驗證),並且WinInet反正被棄用。現在一切正常。
如果你知道你到了代理......也許用Wireshark探聽會產生一些有用的信息?或者也許小提琴手? – dgnorton