TsgcWebSocketServer | TLS and plain HTTP on the same port

A TLS server (TsgcWebSocketServer, TsgcWebSocketHTTPServer and TsgcHTTPServer with the default Indy, IOCP or EPOLL IOHandler) can also accept plain HTTP and WebSocket connections on the same port it uses for TLS. When this option is enabled, the server peeks at the first byte of every new connection. A $16 byte (TLS handshake record) means the client starts a TLS handshake, any other byte means the connection is served as plain text. If no byte arrives within PlainTextTimeout, the connection is treated as TLS, which is the previous behaviour. With the IOCP and EPOLL IOHandlers the decision is made on the first data received, without blocking, and PlainTextTimeout is not used.

The typical use is migrating an existing published plain HTTP port to HTTPS without changing the port configured on the clients. Enable AllowPlainText while the clients are updated, and switch it off again once all of them use TLS.

Properties

The enumeration TsgcSSLPlainTextPolicy is declared in the unit sgcWebSocket_Types.

Example

Start a server on port 443 that accepts TLS and plain connections and serves both.


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;

To know whether a request uses TLS, call the server method IsTLS(AContext), for example in the OnCommandGet or OnCommandOther events. The TLS property of the connection (TsgcWSConnectionServer) is also available.


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;

Limitations