HTTP/2 兼容 API,如何处理

Posted

技术标签:

【中文标题】HTTP/2 兼容 API,如何处理【英文标题】:HTTP/2 compatibility API, how to handle it 【发布时间】:2022-01-16 14:21:09 【问题描述】:

虽然我最初决定创建一个仅 HTTP/2 的服务器,但我发现兼容性 API 是一个不错的选择,可以支持不支持或不支持 HTTP/2 的客户端(fetch in react-native?) .

但是,我很难理解如何处理 HTTP/1x 处理程序上的传入请求,报告 req.httpVersion === "2.0"。以下代码摘自nodejs 文档中的ALPN negotiation section

function onRequest(req, res) 
  // Detects if it is a HTTPS request or HTTP/2
  const  socket:  alpnProtocol   = req.httpVersion === '2.0' ?
    req.stream.session : req;

  // HERE: OK, say we have  req.httpVersion === '2.0'
  // Now, what?

  res.writeHead(200,  'content-type': 'application/json' );
  res.end(JSON.stringify(
    alpnProtocol,
    httpVersion: req.httpVersion
  ));

首先,我不明白上面的代码应该做什么。就像,我知道它的作用,但它没有什么特别之处——似乎只是通用的 HTTP/1x 请求处理程序,它会发送一些 JSON,仅此而已。我错过了什么吗?

除此之外:

一旦 HTTP/1x 处理程序报告 req.httpVersion = "2.0",我该怎么办? 它是否也会由 HTTP/2 处理程序 (server.on("stream", ()=> ... )) 处理,所以我应该在 HTTP/1x 处理程序中忽略它? 如果 HTTP/2 处理程序不能自动处理它,我可以而且应该手动将请求转发给 HTTP/2 处理程序吗?
function http2handler(stream, headers) ... 

function http1xhandler(req, res) 
  if (req.httpVersion === "2.0") 
    // handle as HTTP/2
    return http2handler(req.stream, req.headers);
  

  // handle as HTTP/1x ...


const server = createSecureServer(
   cert, key, allowHTTP1: true ,
  http1xhandler
).listen(4443);

server.on("stream", http2handler);
如果以上都不是,示例中的响应 JSON 是否在向客户端指示它应该切换到 HTTP/2 方面发挥作用?如果是这样,客户具体应该怎么做?

对不起,如果这可能是一个愚蠢的问题,nodejs 文档很糟糕......似乎他们的每一点文档都必须以悬念结束......

【问题讨论】:

【参考方案1】:

在摆弄了一些代码并阅读了更多的文章和答案之后,我想我终于明白了发生了什么。但是,如果我在这里说的任何内容有误,我将不胜感激。

HTTP/2 兼容性 API 为 HTTP/1x 和 HTTP/2 请求提供通用请求处理程序。如ALPN negotiation documentation 所示,开发人员应限制对公共 HTTP/1x API 的响应 - 直到识别出 HTTP/2 请求。您可以检查req.httpVersion 来识别这些,并根据需要分支您的代码。

如果您同时指定兼容性请求处理程序(createSecureServer 上的回调函数)和on("stream", ...) 事件处理程序(仅限 HTTP/2),则服务器行为是:

对于 HTTP/1x 请求,只会调用兼容性请求处理程序 对于 HTTP/2 请求,both 兼容性和 on("stream", ...) 请求处理程序将被调用 - 但只有一个处理程序应该响应请求。如果您尝试响应来自两个处理程序的请求,您将获得:Error [ERR_HTTP2_HEADERS_SENT]: Response has already been initiated.

我选择处理这些问题的方法是创建独立的HTTP/1xHTTP/2 处理程序,每个处理程序都处理自己的蛋糕。兼容性处理程序应忽略 HTTP/2 请求。在代码中:

function http1xhandler(req, res) 
  if (req.httpVersion === "2.0") 
    // Ignore HTTP/2 requests, will be handled by the on("stream", ...) event handler
    // Or, you can answer the HTTP/2 request here, using HTTP/2 features as well
    return;
  

  // Handle HTTP/1x request
  res.writeHead(200,  'content-type': 'text/plain' );
  res.end("Hello HTTP/1x!");


const server = createSecureServer(
   cert, key, allowHTTP1: true ,
  http1xhandler
).listen(4443);

// Do not use the following if you are handling
// HTTP/2 in the HTTP/1x compatibility callback

function http2handler(stream, headers)
  stream.respond(
      'content-type': 'text/plain; charset=utf-8',
      ':status': 200
    );
  stream.end("Hello HTTP/2!");


server.on("stream", http2handler);

希望这对研究这些 API 的其他人有用。

【讨论】:

以上是关于HTTP/2 兼容 API,如何处理的主要内容,如果未能解决你的问题,请参考以下文章

libc库 与 MYSQL 不兼容 如何处理?

如何处理html5新标签的浏览器兼容问题

WooCommerce REST API v2:如何处理付款?

如何处理耗时的ajax请求

html5有哪些新特性移除了那些元素?如何处理HTML5新标签的浏览器兼容问题?如何区分 HTML 和 HTML5?

如何处理所有的贬低