2013-07-22 20 views
5

, şimdiye kadar iyi çalışıyor, ama SSL desteği eklendiğinde bu koduTek bir TIdHTTPServer bileşeni, aynı anda http ve https isteği işleyebilir mi? Bir TIdHTTPServer bileşenini kullanıyorum

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; 

Sunucu yalnızca işlem https istekleri kullanarak ve bir http isteği göndermek eğer bu istisna

atılır

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

soru şudur: Ben http ve https isteklerini işlemek için tek bir TIdHTTPServer bileşeni kullanabilirsiniz? Cevabınız evet ise bu nasıl yapılabilir? Cevap Hayır ise, http için bir tane diğeri https için iki adet TIdHTTPServer örneği oluşturmalıyım?

cevap

6

Evet, hem HTTP ve HTTPS için tek TIdHTTPServer kullanabilirsiniz.

Indy 9 kullanıyorsanız, sunucuya bağlandıklarında varsayılan olarak tüm istemci bağlantılarının SSL etkin etkin olduğu bir hata vardır. bu nedenle tüm, sen Indy 10 kullanıyorsanız

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

, o hata düzeltildi: Bağlantı, 443 numaralı bağlantı noktasında örneğin değilse manuel SSL kapalı çevirmek sunucunun OnConnect olayı Kullanıcılara bu geçici bir çözüm için

  1. bağlantı portu 443, örneğin açıksa SSL açmak için OnConnect olayı kullanın:: istemci bağlantıları ya SSL varsayılan olarak özürlü var, bu yüzden olacak

    procedure TForm1.IdHTTPServer1Connect(AContext: TIdContext); 
    begin 
        if AContext.Connection.Socket.Binding.Port = 443 then 
        TIdSSLIOHandlerSocketBase(AContext.Connection.Socket).PassThrough := False; 
    end; 
    
  2. (tercih edilir) örn SSL veya olmasın, kullanması gereken hangi portu sunucu anlatmak için yeni TIdHTTPServer.OnQuerySSLPort olay kullanın:

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