TLS 服务器(使用默认 Indy、IOCP 或 EPOLL IOHandler 的 TsgcWebSocketServer、TsgcWebSocketHTTPServer 和 TsgcHTTPServer)还可以在其用于 TLS 的同一端口上接受明文 HTTP 和 WebSocket 连接。启用此选项后,服务器会预读每个新连接的第一个字节。如果是 $16 字节(TLS 握手记录),表示客户端开始 TLS 握手;任何其他字节都表示该连接按明文方式处理。如果在 PlainTextTimeout 内没有收到任何字节,则该连接按 TLS 处理,这与之前的行为一致。使用 IOCP 和 EPOLL IOHandler 时,服务器会在收到第一批数据时做出判断,不会阻塞,也不使用 PlainTextTimeout。
典型用途是将已发布的明文 HTTP 端口迁移到 HTTPS,而无需更改客户端中配置的端口。在更新客户端期间启用 AllowPlainText,待所有客户端都使用 TLS 后再将其关闭。
Boolean,默认值为 False。为 True 时,TLS 监听器也会在同一端口上接受明文连接。ptpServe(默认):正常处理明文请求。ptpRedirect:服务器返回 308 Permanent Redirect,重定向到 https://<Host><path>,因此客户端会保留请求方法和请求体。如果请求没有 Host 头,服务器返回 400 Bad Request。ptpReject:服务器返回 400 Bad Request 并关闭连接。Integer,单位为毫秒,默认值为 5000。在将连接视为 TLS 之前,等待客户端发送第一个字节的时间。仅适用于默认的 Indy IOHandler。TsgcWSConnectionServer)的只读 Boolean 属性,连接使用 TLS 时为 True。服务器方法 IsTLS(AContext) 可从请求的 TIdContext 返回相同的值。枚举 TsgcSSLPlainTextPolicy 在单元 sgcWebSocket_Types 中声明。
在 443 端口启动一个同时接受 TLS 和明文连接的服务器,并对两种连接都提供服务。
oServer := TsgcWebSocketHTTPServer.Create(nil);
oServer.SSL := True;
oServer.Port := 443;
oServer.SSLOptions.Port := 443;
oServer.SSLOptions.CertFile := 'c:\certificates\mycert.pem';
oServer.SSLOptions.KeyFile := 'c:\certificates\mycert.pem';
oServer.SSLOptions.RootCertFile := 'c:\certificates\mycert.pem';
oServer.SSLOptions.AllowPlainText := True;
oServer.SSLOptions.PlainTextPolicy := ptpServe;
oServer.Active := True;
要了解请求是否使用 TLS,请调用服务器方法 IsTLS(AContext),例如在 OnCommandGet 或 OnCommandOther 事件中。连接的 TLS 属性(TsgcWSConnectionServer)同样可用。
procedure OnCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
if TsgcWebSocketHTTPServer1.IsTLS(AContext) then
AResponseInfo.ContentText := 'Secure connection'
else
AResponseInfo.ContentText := 'Plain connection, please use https://';
end;
TLS 值尚不可靠。从第一个请求开始,该值是正确的。SecurityOptions)仅在 TLS 连接上发送,明文连接上从不发送。