5

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

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

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

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

4

2 回答 2

5

一个合理的算法是这样的:

  1. 尝试使用用户当前的代理设置(IE 使用的代理设置)进行连接。这些是最有可能工作的。请参阅WinHttpGetIEProxyConfigForCurrentUser()MSDN 以获取这些设置,或参阅INTERNET_OPEN_TYPE_PRECONFIGWinINet。

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

  3. 如果失败,请尝试使用WinHttpGetProxyForUrl进行 WPAD 自动检测。(WPAD是客户端可以在网络上找到代理自动配置 (PAC)文件的自动化方式,通常是公司网络。)您需要选择选项来检查代理文件的 DHCP 和 DNS。WinHTTP AutoProxy FunctionsMSDN 上包含使用此 API 的代码示例和大量支持信息。如果此操作成功,您将取回代理信息,然后您可以将其插入您的 HTTP 下载代码。AFAIK,没有等效的 WinINet 选项可以自动进行新的 WPAD 检测——只有 WinHTTP。

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

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

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

请注意,代理检测没有什么魔力——您可以选择使用用户设置、使用默认计算机设置、使用直接连接、使用 WPAD 查找 PAC 文件或询问用户。不幸的是,没有办法“在不需要处理代理的情况下建立 HTTP 连接”。

顺便说一句,尽管您可以仅将 WinHTTP 用于代理检测,然后使用 WinINet 获取文件,但我建议对这两个部分都使用 WinHTTP。当您想要最大的灵活性和对 HTTP 交互的控制(以及比 WinINet 更好的稳定性)时,WinHTTP 是更可取的。

更新 2:

JJ 上面有一个好主意——我添加了一个检查 Firefox 代理设置的步骤。由于奇怪的代理通常存在于公司环境中(倾向于在 IE 上标准化),因此这不太可能有所帮助,但值得一试。

更新:我刚刚编辑了上面的部分以回应弗朗西斯的正确评论:WinHTTP 不是严格意义上的 WinINet 的“继任者”(意味着 WinINet 的 100% 功能在 WinHTTP 中可用)。相反,WinHTTP 是为使用 HTTP 进行数据交换并且不关心与 Internet Explorer 的缓存、cookie、拨号 UI 等集成的应用程序设计的。

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

WinHTTP 更亲力亲为(例如,您需要调用一个 API 来获取代理信息,而另一个调用才能使用该代理信息),但是这种额外程度的控制允许您执行 WinINet 无法执行的操作,例如强制忽略用户的代理设置并尝试新的 WPAD 检测。

于 2009-12-25T04:29:54.647 回答
1

我发现对 IE 本身使用的进程的最佳描述是Windows Update 客户端如何确定使用哪个代理服务器连接到 Windows Update 网站。将使用 IE 访问 Windows Update 时的顺序与您对 WinINet 或 WinHTTP WinHttpGetIEProxyConfigForCurrentUserWinHttpDetectAutoProxyConfigUrlWinHttpGetProxyForUrlWinHttpGetDefaultProxyConfiguration的知识相结合,以使您的应用程序连接。

这是知识库文章中的序列:

  1. 如果用户配置为自动检测设置,请使用 WPAD 查找 PAC 文件。
  2. 没有找到 PAC 文件?如果用户设置了 IE 自动配置脚本,请使用该 PAC 文件。
  3. 还是没有找到 PAC 文件?寻找代理。如果用户手动配置了 IE 代理设置,请使用它们。
  4. 没有配置 IE 代理?检查默认代理配置。
  5. 没有配置默认代理?使用直接连接。
于 2012-04-04T16:03:11.520 回答