2011-03-11 75 views
0

我創建了一個使用WinInet向遠程主機發送HTTP請求的Win32服務。在我的計算機(WinXP SP2)上,在我們的QoS團隊(Win2003服務器)中的測試工作站上,它可以正常工作 - 通過代理服務器和直接服務器,代理服務器使用身份驗證服務器和無需代理服務器)。HttpSendRequest失敗,錯誤12015

但是我們的一些客戶,使用該服務and_proxy_with_authorization Win2003的服務器上,有一個問題 - 的HttpSendRequest失敗並GetLastError返回12015(ERROR_INTERNET_LOGIN_FAILURE,請求連接並登錄到FTP服務器失敗)的所有調用。因此,從IE地址行手動發送的相同的HTTP請求成功。

代理配置似乎是正確的。這裏是初始化代碼:

m_hNet = InternetOpen(m_strAgent.c_str(), 
      INTERNET_OPEN_TYPE_PRECONFIG, 
      NULL, 
      NULL, 
      0); 

     // Respect explicit proxy 
     if (Cfg::m_bUseProxy) 
     { 
      char szProxy[MAX_PATH] = {0}; 
      strncpy(szProxy, m_strProxyServer.c_str(), MAX_PATH - 1); 

      INTERNET_PROXY_INFO proxyinfo; 
      proxyinfo.dwAccessType = INTERNET_OPEN_TYPE_PROXY; 
      proxyinfo.lpszProxy = szProxy; 
      proxyinfo.lpszProxyBypass = NULL; 

      BOOL B = InternetSetOption(m_hNet, INTERNET_OPTION_PROXY, (LPVOID)(&proxyinfo), sizeof(proxyinfo)); 
      if (!B) 
      { 
       devent(TS::LL_HIGH, "[Wrn] InternetSetOption::Proxy failed <proxy=%s><le=%d>", 
        m_strProxyServer.c_str(), 
        GetLastError()); 
      } 
     } 


     // Validate handle 
     if (NULL == m_hNet) 
     { 
      devent(TS::LL_CRITICAL, "[Err] InternetOpen failed <le=%d>", 
       GetLastError()); 
      return false; 
     } 


     // Try to get connection handle 
     m_hConnect = InternetConnect(m_hNet, 
      m_strHostName.c_str(), 
      INTERNET_DEFAULT_HTTP_PORT, 
      NULL, 
      NULL, 
      INTERNET_SERVICE_HTTP, 
      0, 
      0); 


     // Validate handle 
     if (NULL == m_hConnect) 
     { 
      devent(TS::LL_CRITICAL, "[Err] InternetConnect failed <le=%d>", 
       GetLastError()); 
      Cleanup(); 
      return false; 
     } 

     // Respect proxy authentication 
     if (Cfg::m_bUseAuth) 
     { 
      BOOL B; 
      B = InternetSetOption(m_hConnect, INTERNET_OPTION_PROXY_USERNAME, (LPVOID*)Cfg::m_strProxyLogin.c_str(), Cfg::m_strProxyLogin.length() + 1); 
      if (!B) 
      { 
       devent(TS::LL_HIGH, "[Wrn] InternetSetOption::ProxyUserName failed <login=%s><le=%d>", 
        Cfg::m_strProxyLogin.c_str(), 
        GetLastError()); 
      } 

      B = InternetSetOption(m_hConnect, INTERNET_OPTION_PROXY_PASSWORD, (LPVOID*)Cfg::m_strProxyPassword.c_str(), Cfg::m_strProxyPassword.length() + 1); 
      if (!B) 
      { 
       devent(TS::LL_HIGH, "[Wrn] InternetSetOption::ProxyPassword failed <pass=%s><le=%d>", 
        Cfg::m_strProxyPassword.c_str(), 
        GetLastError()); 
      } 
     } 

,這是發送:

// Try to get request handle 
     m_hRequest = HttpOpenRequest(m_hConnect, 
      "POST", 
      m_strReqObject.c_str(), 
      NULL, 
      NULL, 
      NULL, 
      INTERNET_FLAG_NO_CACHE_WRITE, 
      0); 

     // Validate handle 
     if (NULL == m_hRequest) 
     { 
      devent(TS::LL_CRITICAL, "[Err] OpenRequest failed <le=%d>", 
       GetLastError()); 
      return false; 
     } 

     // Try to get response 
     BOOL bOk = HttpSendRequest(m_hRequest, 
      strSpecificHeaders.c_str(), 
      strSpecificHeaders.length(), 
      (LPVOID)strRequest.c_str(), 
      (DWORD)strRequest.length()); 

     if (0 == bOk) 
     { 
      devent(TS::LL_CRITICAL, "[Err] SendRequest failed <le=%d>", 
       GetLastError()); 

      CloseHandle(m_hRequest); 
      return false; 
     } 

我用Google搜索了兩天,但沒有發現不僅解決方案,而且任何人相似的問題。我也不能在類似的工作站上重現問題。最後,我不明白爲什麼「FTP服務器」在MSDN錯誤desc?

任何想法?

回答

1

WinInet旨在供應用程序空間用戶使用,並與WinInet選項的註冊表位置有關聯(基於登錄用戶帳戶)。

在線MSDN文檔每WinInet的頁面上明確指出:

注意的WinINet不支持服務器實現。另外,它不應該從服務中使用。對於服務器實現或服務使用Microsoft Windows HTTP Services (WinHTTP)

WinInet和WinHTTP之間的API差異很小,你會很快拿起它。

  • 改名功能(如HttpOpenRequest中 - > WinHttpOpenRequest)
  • 所有WINHTTP方法都是Unicode只
  • 採用WinHttp.lib,WinHttp.dll代替WinInet.lib,wininet.dll文件

還有其他一些微妙之處,但你不會掙扎。

我知道你的問題表明代碼適用於已經將它作爲服務運行的人。但是文檔明確指出「不這樣做」的事實可能表明某些版本的Windows可能不支持它,特別是更高版本,並且某些Service Pack或自動更新可能導致當前工作實例失敗。

我會猜測甚至可能有一些安全令牌和特權,WinInet需要在完成任務時進行操作,而且某些Windows Server 200x安裝可能會有默認設置,不會將這些令牌提供給運行的用戶一個服務帳戶。

我真的建議嘗試將一個快速測試服務移植到WinHTTP並在客戶端的Windows Server實施上進行測試以確定是否能解決問題。

0

在完全不同的方法上...... ERROR_INTERNET_LOGIN_FAILURE也可以表明防火牆已阻止該連接。

一種可能的方案在此描述在Egg Head Cafe

+0

的鏈接已斷開:( – nergeia 2015-06-15 12:12:13