【发布时间】:2014-06-16 15:49:18
【问题描述】:
给定一个目标 URI,我如何以编程方式确定该 URI 的 HTTP GET 是否会向本地机器发出请求?
上下文:我需要这样做有两个原因。一是我有一个响应 HTTP 请求的 mod_perl2 应用程序。在这样做时,它有时需要发出 HTTP 请求以从目标 URI 中检索一些数据。为了避免 HTTP 请求的无限递归,如果目标 URI 实际上会解析到当前机器,我需要避免发出 HTTP 请求。这是为了防止用户意外射中自己的脚。它并非旨在作为安全检查。
第二个原因是,如果我的应用程序收到一个 HTTP 请求,我需要使用请求 URI 作为键来查找一些元数据。问题是几个 URI 同义词中的任何一个都可以用作创建元数据的键,所以我需要一种方法来解析同义词,但仅限于本地主机上的 URI。
问题并不像查看 URI 以查看域是“localhost”,还是它的 IP 地址是 127.0.0.1(或 127.0.1.1 或 127.*)那么简单,因为:(a)目标URI 可能使用完全限定的域名(例如 foo.example.com),它解析为当前机器上的 IP 地址; (b) 一台机器可以有多个 IP 地址。
操作系统必须拥有解决此问题所需的信息,因为它必须知道它所侦听的 IP 地址和端口。 This post 讨论了试图确定本地机器的 IP 地址(或地址,因为它可能有多个)的问题。也许我可以这样做来确定本地机器的 IP 地址,然后也许我可以将这些 IP 地址与目标 URI 中的 IP 地址(或 URI 域的 gethostbyname 返回的 IP 地址)进行比较。我真的需要这样做吗?这种方法有问题吗?有没有更好的办法?
This post 表示 C# 有一个函数 HttpContext.Current.Request.IsLocal 来做我需要的,但是我在 perl 中找不到类似的东西。
我之前在 perlmonks.org 上 asked this question(因为我使用的是 perl)但没有找到令人满意的答案。如果在 Linux 上通常可用的其他一些编程语言(例如 C、bash 或 python)中有可用的解决方案,那也足够了。我不需要保证在所有可能情况下都有效的解决方案,但如果它适用于大多数情况,那就太好了。
【问题讨论】:
-
它还可以指向负载均衡器的 IP 地址,该负载均衡器将重写数据包以指向本地机器。
-
第一种情况的随机建议:在您的应用程序生成的请求中,设置一些自定义 HTTP 标头。收到请求时检查它,如果存在则返回错误。请记住,您可以根据需要在自定义标头中放置尽可能多的跟踪信息(例如,请求通过的所有节点 - 如果 node2 收到 node1 请求,它会发送包含 node2 和 node1 的标头。Node3 可以,但 node1 或 node2 都会说“不”)
-
在 /robots.txt 中添加一个包含唯一字符串(例如系统 hostid 或 CPUID 的 md5 哈希)的注释。通过 http 检索它并与本地文件系统中的 robots.txt 进行比较。
-
到目前为止,HTTP 标头的想法似乎是最好的。 /robots.txt 的想法与需要额外的 HTTP 请求类似。但理想情况下,我希望完全避免额外的 HTTP 请求,即使它在负载均衡器存在的情况下无法正常工作。
-
.NET HttpRequest.IsLocal "如果请求发起者的 IP 地址是 127.0.0.1 或者请求的 IP 地址与服务器的 IP 地址相同,则 IsLocal 属性返回 true。"
标签: networking routing hostname interface url