使用WinINET为虚拟用户创建可靠的HTTP连接

时间:2009-12-08 09:10:14

标签: winapi proxy wininet winhttp

我正在制作一个程序,可以在Windows上通过互联网下载一个简单的文件 Wininet系列API,因为我想利用其IE兼容的代理行为。众所周知,目前的IE有几个代理设置:自动检测(WPAD),自动配置(PAC),手动单URL,每个协议的代理服务器,袜子,直接,...对于大多数用户,“直接下载“ 工作良好;但是对于某些用户(特别是那些在防火墙/ NAT后面的用户),他们在建立连接时总是需要特殊的代理设置。

编写代码来处理所有这些情况是很痛苦的,所以我希望WinINET InternetOpen (INTERNET_OPEN_TYPE_PRECONFIG)可以帮助我。它适用于大多数用户,但我仍然发现一些用户抱怨连接失败。这些用户可能拥有非常特殊的网络环境(例如,需要用户名/密码auth代理),直接连接对他们不起作用。

有时虚拟用户配置错误,我想让wininet为我尝试“全部”可能的代理设置;不幸的是,INTERNET_OPEN_TYPE_PRECONFIG只会尝试用户配置的那个,而不是“每个可能的代理设置”。

所以我的问题是,如何让一个程序具有最强大的能力来解决虚拟用户的所有http连接(特别是代理配置)(即,他们不了解如何配置他们的系统)? 是否有任何建议的方式来建立HTTP连接而无需处理代理内容? (即,将尝试所有可能的代理设置的“超级”连接解算器),或者是否有任何方法告诉WinINET启用其所有代理设置来创建连接?

2 个答案:

答案 0 :(得分:5)

合理的算法是这样的:

  1. 使用用户当前的代理设置(IE使用的设置)尝试连接。这些是最有可能工作的。请参阅MSDN上的WinHttpGetIEProxyConfigForCurrentUser()以获取这些设置,或在WinINet中查看INTERNET_OPEN_TYPE_PRECONFIG

  2. 如果失败,请尝试直接连接。

  3. 如果失败,请尝试使用WinHttpGetProxyForUrl进行WPAD自动检测。 (WPAD是客户端可以在网络上找到Proxy Auto-Config (PAC)文件的自动方式,通常是公司网络。)您需要选择检查代理文件的DHCP和DNS的选项。 MSDN上的WinHTTP AutoProxy Functions包含使用此API的代码示例和大量支持信息。如果成功,您将获得代理信息,然后插入HTTP下载代码。 AFAIK,没有相同的WinINet选项可以自动执行新的WPAD检测 - 只有WinHTTP。

  4. 接下来,您可以尝试查找Firefox代理设置。 This SO answer详细说明了有关这些设置的位置和格式的信息,以便您以编程方式访问它们。

  5. 如果仍然失败,请让用户(在您的用户界面中)检查他们的互联网连接是否已实际连接。实际上,用户断开连接比上述所有代理检测步骤失败更常见。要求用户打开他们的浏览器,以确保他们可以访问互联网站点 - 如果上述步骤失败,他们的浏览器可能无法看到网络。一旦用户声称他们已连接,请重复步骤1-3。

  6. 如果上述所有方法都失败了,那么您真的别无选择,只能要求用户手动指定其代理信息。您可能希望克隆IE或firefox的代理UI,并将这些UI设置转换为适当的参数,以便在下载该文件时配置代理选项。

  7. 请注意,代理检测没有神奇之处 - 您的选择是使用用户的设置,使用默认计算机设置,使用直接连接,使用WPAD查找PAC文件或询问用户。遗憾的是,没有办法“在不需要处理代理内容的情况下建立HTTP连接”。

    顺便说一下,虽然你可以只使用WinHTTP进行代理检测,然后使用WinINet来获取文件,但我建议将WinHTTP用于这两个部分。当您希望最灵活地控制HTTP交互(以及比WinINet更好的稳定性)时,WinHTTP更可取。

    更新2:

    J.J。上面有一个好主意 - 我添加了检查Firefox代理设置的步骤。由于奇怪的代理通常出现在企业环境中(它们倾向于在IE上标准化),所以这有点不太可能有所帮助,但值得一试。

    更新:我刚刚编辑了以上部分以回应Francis的正确评论:WinHTTP不是严格意义上的WinINet的“继承者”(意味着WinINet的100%功能可用于WinHTTP的)。相反,WinHTTP是为使用HTTP进行数据交换的应用而设计的,并不关心与Interet Explorer的缓存,cookie,拨号UI等集成。

    服务器应用程序肯定属于这一类(WinHTTP,与WinINet不同,在服务器应用程序中使用是安全的),但许多客户端软件也使用它,例如每台现代PC上的Windows Update客户端。通常,WinHTTP更适用于需要通过HTTP下载文件并需要对网络进行更细粒度控制并希望控制自己的UI的客户端应用程序。

    WinHTTP更实际操作(例如,您需要进行一次API调用以获取代理信息,另一次使用该代理信息)但是额外的控制程度允许您执行使用WinINet无法执行的操作就像强制忽略用户的代理设置并尝试新的WPAD检测一样。

答案 1 :(得分:1)

我发现IE过程中使用的最佳描述是How the Windows Update client determines which proxy server to use to connect to the Windows Update Web site。在使用IE访问Windows Update时,结合序列,了解WinINet或WinHTTP WinHttpGetIEProxyConfigForCurrentUserWinHttpDetectAutoProxyConfigUrlWinHttpGetProxyForUrlWinHttpGetDefaultProxyConfiguration,以便连接应用程序。

以下是知识库文章的序列:

  1. 如果用户配置为自动检测设置,请使用WPAD查找PAC文件。
  2. 找不到PAC文件?如果用户设置了IE自动配置脚本,请使用该PAC文件。
  3. 仍然没有找到PAC文件?寻找代理。如果用户已手动配置IE代理设置,请使用它们。
  4. 没有配置IE代理?检查默认代理配置。
  5. 没有配置默认代理?使用直接连接。