2011-03-11 74 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