2013-07-22 17 views
5

sto usando un componente TIdHTTPServer, finora sta lavorando bene, ma quando ho aggiunto il supporto SSL utilizzando questo codiceUn singolo componente TIdHTTPServer può gestire la richiesta http e https nello stesso tempo?

SSLHandler:= TIdServerIOHandlerSSLOpenSSL.Create(nil); 
    SSLHandler.SSLOptions.CertFile := 'foo.pem'; 
    SSLHandler.SSLOptions.KeyFile := 'foo.pem'; 
    SSLHandler.SSLOptions.RootCertFile := 'foo.pem'; 
    SSLHandler.SSLOptions.Method := sslvSSLv23; 
    SSLHandler.SSLOptions.Mode := sslmServer; 

    SSLHandler.SSLOptions.VerifyDepth := 1; 
    SSLHandler.SSLOptions.VerifyMode := [sslvrfPeer,sslvrfFailIfNoPeerCert,sslvrfClientOnce]; 

    idHttpServer1.IOHandler := SSLHandler; 
    IdHTTPServer1.Bindings.Add.Port := 80; 
    IdHTTPServer1.Bindings.Add.Port := 443;  
    IdHTTPServer1.Active := True; 

server solo https processo richieste e se invio una richiesta HTTP Questa eccezione viene generata

Error accepting connection with SSL. error:1407609C:SSL routines:SSL23_GET_CLIENT_HELLO:http request

La domanda è: posso usare un singolo componente TIdHTTPServer per elaborare le richieste HTTP e HTTPS? se la risposta è Sì, come si può fare? Se la risposta è No, devo creare due istanze TIdHTTerver una per http e un'altra per https?

risposta

6

Sì, è possibile utilizzare un singolo TIdHTTPServer per HTTP e HTTPS.

Se si utilizza Indy 9, ha un bug in cui tutte le connessioni client avranno SSL abilitato per impostazione predefinita quando si collegano al server. Per ovviare a questo, utilizzare eventi del server OnConnect attivare manualmente off SSL se la connessione non è sulla porta 443, ad esempio:

procedure TForm1.IdHTTPServer1Connect(AThread: TIdPeerThread); 
begin 
    if AThread.Connection.Socket.Binding.Port <> 443 then 
    TIdSSLIOHandlerSocket(AThread.Connection.Socket).PassThrough := True; 
end; 

Se si utilizza Indy 10, allora questo bug è stato risolto, in modo che tutti connessioni client avranno SSL disabilitato di default, quindi è possibile:

  1. utilizzare l'evento OnConnect per accendere su SSL se il collegamento è sulla porta 443, ad esempio:

    procedure TForm1.IdHTTPServer1Connect(AContext: TIdContext); 
    begin 
        if AContext.Connection.Socket.Binding.Port = 443 then 
        TIdSSLIOHandlerSocketBase(AContext.Connection.Socket).PassThrough := False; 
    end; 
    
  2. (preferito) utilizzare il nuovo TIdHTTPServer.OnQuerySSLPort evento per dire al server quale porta deve utilizzare SSL o no, ad esempio:

    procedure TForm1.IdHTTPServer1QuerySSLPort(APort: TIdPort; var VUseSSL: Boolean); 
    begin 
        VUseSSL := (APort = 443); 
    end;