Indy 支持 ALPN(应用层协议协商)

· 功能

ALPN(应用层协议名称)是一种 TLS 扩展,在 hello 消息交换过程中包含协议协商。ALPN 能够以更高效且避免额外往返的方式协商安全连接上使用的协议。日益普及的 HTTP/2 协议正是利用 ALPN 进一步缩短网站加载时间并加快连接加密速度。

根据 RFC 7301 规范,使用 ALPN 时,客户端会在 TLS ClientHello 消息中将支持的应用协议列表发送给服务器,服务器从中选择一个协议并在 ServerHello 消息中返回所选协议。这样,应用协议协商便可在 TLS 握手的单次往返中完成。此方法还允许服务器为每种应用协议关联不同的证书。

sgcWebSockets 4.3.2 起,若使用我们的自定义 Indy 库编译 sgcWebSockets,即可使用 ALPN 协议。Indy 默认不实现此协议。

客户端

创建一个要求 ALPN 使用"h2"协议的 WebSocket 客户端,连接后检查服务器接受了哪种协议。

oClient := TsgcWebSocketClient.Create(nil);
oClient.Host := '127.0.0.1';
oClient.Port := 443;
oClient.TLS := True;
oClient.TLSOptions.ALPNProtocols.Add('h2');
oClient.Active := True;
procedure OnClientConnect(Connection: TsgcWSConnection);
var
  vProtocol: string;
begin
  vProtocol := TsgcWSConnectionClient(Connection).ALPNProtocol;
end; 

服务器

创建一个 WebSocket 服务器,检查客户端是否支持"h2" ALPN 连接。

oServer := TsgcWebSocketServer.Create(nil);
oServer.Port := 443;
oServer.SSL := True;
oServer.Active := True;
procedure OnServerSSLALPNSelect(Sender: TObject; aProtocols: TStringList; var aProtocol: string);
begin
  if aProtocols.IndexOf('h2') > -1 then
    aProtocol := 'h2';
end;