TsgcWebSocketServer | TLS e HTTP simples na mesma porta

Um servidor TLS (TsgcWebSocketServer, TsgcWebSocketHTTPServer e TsgcHTTPServer com o IOHandler Indy, IOCP ou EPOLL padrão) também pode aceitar conexões HTTP e WebSocket simples na mesma porta que usa para TLS. Quando esta opção está habilitada, o servidor inspeciona o primeiro byte de cada nova conexão. Um byte $16 (registro de handshake TLS) significa que o cliente inicia um handshake TLS, qualquer outro byte significa que a conexão é atendida como texto simples. Se nenhum byte chegar dentro de PlainTextTimeout, a conexão é tratada como TLS, que é o comportamento anterior. Com os IOHandlers IOCP e EPOLL a decisão é tomada no primeiro dado recebido, sem bloqueio, e PlainTextTimeout não é usado.

O uso típico é migrar para HTTPS uma porta HTTP simples já publicada, sem alterar a porta configurada nos clientes. Habilite AllowPlainText enquanto os clientes são atualizados e desabilite-o novamente quando todos usarem TLS.

Propriedades

A enumeração TsgcSSLPlainTextPolicy é declarada na unit sgcWebSocket_Types.

Exemplo

Inicie um servidor na porta 443 que aceita conexões TLS e simples e atende ambas.


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;

Para saber se uma requisição usa TLS, chame o método do servidor IsTLS(AContext), por exemplo nos eventos OnCommandGet ou OnCommandOther. A propriedade TLS da conexão (TsgcWSConnectionServer) também está disponível.


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;

Limitações