我创建了一个Win32服务,它使用WinInet将HTTP请求发送到远程主机。在我的计算机(WinXP SP2)上,在我们的QoS团队(Win2003服务器)中的测试工作站上,它可以正常工作 - 通过代理和直接代理,使用auth和不使用)。
但是我们的一些客户在Win2003服务器上使用此服务 and_proxy_with_authorization 有问题 - 所有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;
}
我用谷歌搜索了两天,但不仅没有找到解决方案,也没有找到任何人类似的问题。此外,我无法在类似的工作站上重现问题。最后,我无法理解为什么msdn error desc中的“FTP-Server”?
有什么想法吗?
答案 0 :(得分:1)
WinInet旨在供应用程序空间用户使用,并且与WinInet选项的注册表位置有关(基于登录用户帐户)。
在线MSDN文档清楚地在每个WinInet页面上说明:
注意 WinINet不支持服务器实施。此外,它不应该从服务中使用。对于服务器实现或服务,请使用Microsoft Windows HTTP Services (WinHTTP)。
WinInet和WinHTTP之间的API差异非常小,您可以非常快速地获取它。
还有其他一些细微之处,但你不会挣扎。
我知道您的问题表明该代码适用于已经将其作为服务运行的人。但是文档明确说“不要这样做”的事实可能表明某些版本的Windows可能不支持它,特别是更高版本,并且某些Service Pack或自动更新可能导致当前工作实例失败。 / p>
我认为甚至可能会有一些WinInet需要的安全令牌和权限来完成任务,而某些安装的Windows Server 200x可能有默认设置,不能将这些令牌提供给作为服务帐户。
我真的建议尝试将快速测试服务移植到WinHTTP并测试客户端的Windows Server实现,看看是否能解决问题。
答案 1 :(得分:0)
完全不同的问题...... ERROR_INTERNET_LOGIN_FAILURE也可以暗示防火墙已阻止该连接。
这里描述了一种可能的解决方案Egg Head Cafe