ALPN 协商


ALPN 协商允许在同一个套接字上同时支持 HTTPS 和 HTTP/2。 reqres 对象可以是 HTTP/1 或 HTTP/2,并且应用程序必须将自己限制在 HTTP/1 的公共 API,并检测是否可以使用更多HTTP/2 的高级特性。

以下示例创建了支持两种协议的服务器:

const { createSecureServer } = require('node:http2');
const { readFileSync } = require('node:fs');

const cert = readFileSync('./cert.pem');
const key = readFileSync('./key.pem');

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

function onRequest(req, res) {
  // 检测是 HTTPS 请求还是 HTTP/2
  const { socket: { alpnProtocol } } = req.httpVersion === '2.0' ?
    req.stream.session : req;
  res.writeHead(200, { 'content-type': 'application/json' });
  res.end(JSON.stringify({
    alpnProtocol,
    httpVersion: req.httpVersion
  }));
}

'request' 事件在 HTTPS 和 HTTP/2 上的工作方式相同。

ALPN negotiation allows supporting both HTTPS and HTTP/2 over the same socket. The req and res objects can be either HTTP/1 or HTTP/2, and an application must restrict itself to the public API of HTTP/1, and detect if it is possible to use the more advanced features of HTTP/2.

The following example creates a server that supports both protocols:

const { createSecureServer } = require('node:http2');
const { readFileSync } = require('node:fs');

const cert = readFileSync('./cert.pem');
const key = readFileSync('./key.pem');

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

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;
  res.writeHead(200, { 'content-type': 'application/json' });
  res.end(JSON.stringify({
    alpnProtocol,
    httpVersion: req.httpVersion
  }));
}

The 'request' event works identically on both HTTPS and HTTP/2.