何时从 http 请求规范中使用 absoluteUri?

When is absoluteUri used from the http request specs?

我一直在研究具有 getRequestURI 和 getRequestURL 方法的 HttpServletRequest API (Java)。这让我调查: https://www.rfc-editor.org/rfc/rfc7230#section-5.3 据我了解 getRequestURI returns 来自 http 请求第一行的值在大多数情况下是资源的相对路径,除非源服务器位于入站代理后面,在这种情况下它必须是绝对 URI。我想互联网上流行网站的大多数原始服务器都属于该类别,这意味着原始 http 请求中的 URI 应该是 absoluteUri(来自 http 规范),但我还没有设法在任何地方找到这样的例子。浏览器真的能知道它是将请求发送到入站代理还是直接发送到原始服务器? http 规范中的 absoluteUri 概念是否有任何实用价值?因为 Host 头字段总是在 HTTP 1.1 请求中发送。在HTTP 1.0 还没有Host 头字段的时候,规范的那部分是否有一些实用价值?

我认为您可能对所讨论的代理类型感到困惑。看起来 RFC 指的是转发代理,您可以在其中通过另一台服务器向另一台服务器发出请求(并且客户端告诉代理将流量转发到何处)。

使用反向代理,你是对的,客户端不知道请求已被代理到另一台服务器。

Difference between proxy server and reverse proxy server

来自 http 协议 1.0 规范

The absoluteURI form is only allowed when the request is being made to a proxy. The proxy is requested to forward the request and return the response. If the request is GET or HEAD and a prior response is cached, the proxy may use the cached message if it passes any restrictions in the Expires header field. Note that the proxy may forward the request on to another proxy or directly to the server specified by the absoluteURI. In order to avoid request loops, a proxy must be able to recognize all of its server names, including any aliases, local variations, and the numeric IP address. An example Request-Line would be: GET /TheProject.html HTTP/1.0

The most common form of Request-URI is that used to identify a resource on an origin server or gateway. In this case, only the absolute path of the URI is transmitted (see Section 3.2.1, abs_path). For example, a client wishing to retrieve the resource above directly from the origin server would create a TCP connection to port 80 of the host "www.w3.org" and send the line: GET /pub/WWW/TheProject.html HTTP/1.0 followed by the remainder of the Full-Request. Note that the absolute path cannot be empty; if none is present in the original URI, it must be given as "/" (the server root).

所以是的,所有这一切都具有实际意义,但前提是您知道您实际上是在代理服务器上发帖。浏览器无法真正知道他正在向代理提交信息,但由于这是最常见的情况,这就是为什么您始终传输主机和 uri 属性但不传输显式路径的原因。现代(和不太现代)代理从主机、协议、端口加上 URI

重建 URL

举个例子

GET /standards/ HTTP/1.1
Host: www.w3.org
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://www.w3.org/
Connection: keep-alive
Upgrade-Insecure-Requests: 1

代理将重建用于发出请求的 URL 客户端。返回的 URL 将包含协议、服务器名称、端口号和服务器路径。

在java中做了类似的事情。如果您查看 servletapi specs,您也会看到相同的行为。

因此,根据经验,只有在向代理发出请求时才允许使用 absoluteURI 形式。该请求不一定来自浏览器,但如果代理没有收到绝对路径,它会使用 header 中的其余数据构造 URL,类似于 java得到URL.

好的,Daniel Scott 已经确定了我最初困惑的根源。我会记下一些我不太清楚并妨碍我正确理解规范的要点:

  1. 转发代理通常简称为 "proxies"。
  2. 反向代理通常被称为 "gateways"。
  3. 出于某种原因,我认为正向代理与出站代理同义,而反向代理与入站代理同义。我想我在某处有关代理的文章中看到过它,但我不知道这些术语是否被广泛使用。
  4. 在 TCP/IP 级别,当我们在转发代理后面时,所有网络流量都发送到该代理。浏览器从不直接与源服务器通信,必须以某种方式将地址(IP 或域名)发送给转发代理,以便它可以代表客户端与源服务器通信。这发生在 Request-Line 中的 HTTP 协议级别。当我们不在转发代理后面时,我们可以直接通过 TCP/IP 与源服务器通信,并且不需要 HTTP 级别 Request-Line 中的绝对 url。
  5. Request-Line 中的绝对 Url 是从 HTTP/1.0 开始设计的,用于处理转发代理背后的通信问题。 HTTP/1.1 规范将主机 header 字段引入为强制性 header,该规范引入了对虚拟主机的支持。我想 HTTP/1.1 可以简单地强制执行绝对 url 并用一块石头杀死两只鸟,但出于某种原因,它决定主机 header 解决方案更好。
  6. 我知道除了正向和反向代理之外还有 "transparent" 代理。这些是 ISP 等使用的 CDN 或代理。它们既不是正向的也不是反向的,并且不需要两个通信方都进行配置。他们与这个问题没有任何关系,但这曾经让我感到困惑。

我还想说我做了一个实验,证实了 http 规范中的内容。

我用谷歌搜索 "free proxy ip and port",转到“https://www.hide-my-ip.com/proxylist.shtml”并配置 windows 使用转发代理(控制面板 -> Internet 选项 -> 连接 -> 局域网设置 -> "Use a proxy server...")。然后我向 www.bbc.com 发出请求并检查来自 chrome 控制台网络选项卡的原始 http 请求 Request-Line 中的地址是绝对的。然后我删除了代理并再次发出相同的请求。 Request-Line 的地址现在只是路径。

我不确定 Alexius Diakogiannos 提到的代理对 url 的整个重建。如果客户端不发送绝对 url,这是大多数转发代理都有的选项,这似乎非常合乎逻辑,但据我所知,至少 chrome 发送绝对 url当它意识到它在它后面时正确地发送给代理。当然,我自己从来没有 managed/ran 正向代理,所以我不知道。