【发布时间】:2019-03-29 17:24:23
【问题描述】:
我正在编写一个从 HTTP/2 到 HTTP/1 的代理,反之亦然。
当我收到一个定义 :scheme 的传入 HTTP/2 请求时,我应该为代理的 HTTP/1 请求映射到哪个标头?
我能找到的最接近的是https://www.rfc-editor.org/rfc/rfc7239#section-5.4
【问题讨论】:
标签: http2
我正在编写一个从 HTTP/2 到 HTTP/1 的代理,反之亦然。
当我收到一个定义 :scheme 的传入 HTTP/2 请求时,我应该为代理的 HTTP/1 请求映射到哪个标头?
我能找到的最接近的是https://www.rfc-editor.org/rfc/rfc7239#section-5.4
【问题讨论】:
标签: http2
将 HTTP/2 :scheme 伪标头映射到 HTTP/1.1 X-Forwarded-Proto 标头是正确的。
【讨论】:
X-Forwarded-Proto 作为HTTP/2 标头-:scheme 的意义何在?是标准化X-Forwarded-Proto吗?对我来说,:scheme 从语义上讲似乎是新事物。换句话说 - 是否有一个有效的用例,你可以同时拥有:scheme 和 X-Forwarded-Proto?
:scheme 和Forwarded: proto=... 都存在(X-Forwarded-Proto 现在已过时)并且它们可能具有不同的值: HTTP/2-to-HTTP/2 代理收到了一个https 请求,但将其转发为明文,所以:scheme 将是http。
你基本上不应该映射它。
首先,HTTP 没有直接等效于 :scheme 伪标头。请求是相对路径(例如/path/page/)而不是绝对路径(例如https://www.example.com/path/page/),并且主机标头仅包含服务器名称而不是方案。
所以连接知道它是 HTTP 还是 HTTPS,这会暴露给网络服务器等(例如,在 Apache 的 REQUEST_SCHEME 变量中),但在 HTTP 级别它不知道。
如果充当拦截代理并采用一个 HTTP/2 连接并将请求转发到另一个连接,那么您应该为第二个连接打开一个 HTTP 或 HTTPS 连接,这取决于下游系统支持的内容。
正如 sbordet 指出的那样,如果您想让下游系统了解原始方案是什么,那么您可以使用 X-Forwarded-Proto 标头(技术上已过时但仍在使用)或 Forwarded 标头,但这更多是为了提供信息而不是直接映射原始请求中的内容。该方案与当前请求有关。
【讨论】:
虽然 HTTP/1.x 使用消息起始行(参见 [RFC7230], 第 3.1 节)传达目标 URI、请求的方法和 响应的状态码,HTTP/2 使用特殊的伪标头 为此目的,以 ':' 字符 (ASCII 0x3a) 开头的字段。
还有:
“:scheme”伪标题字段包括 目标 URI([RFC3986],第 3.1 节)。
":scheme" 不限于“http”和“https”方案 URI。一种 代理或网关可以转换非 HTTP 方案的请求, 允许使用 HTTP 与非 HTTP 服务进行交互。
因此,如果您代理 HTTP,则应为“http”,如果您代理 HTTPS,则应为“https”。
再次阅读,我可以看到我可能对问题的理解有误(我在想 HTTP1 客户端,HTTP2 服务器)。但是以上两个引用仍然是相关的。您不要将 :scheme 放在 HTTP1 标头中 - 它构成了您放置在消息起始行中的 URI 的一部分。
【讨论】: