2013-07-22 92 views
5

我使用的是TIdHTTPServer組件,至今工作正常,但使用此代碼單個TIdHTTPServer組件可以同時處理http和https請求嗎?

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; 

服務器只處理HTTPS請求,當我加入SSL支持,如果我發送一個HTTP請求則拋出該異常

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

的問題是:我可以使用單一TIdHTTPServer組件來處理HTTP和HTTPS請求?如果答案是肯定的,可以這樣做?如果答案爲否,我必須創建兩個TIdHTTPServer實例,一個用於http,另一個用於https?

回答

6

是的,你可以使用HTTP和HTTPS單TIdHTTPServer

如果您使用的是Indy 9,那麼它有一個錯誤,即當所有客戶端連接到服務器時,其默認情況下都會啓用SSL 。若要解決,使用服務器的OnConnect事件手動打開關閉 SSL如果連接不上443端口,例如:

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

如果使用的是印10,則該錯誤是固定的,因此所有客戶端連接將SSL默認情況下禁用,所以你可以:

  1. 使用OnConnect事件打開 SSL如果連接端口443上,如:

    procedure TForm1.IdHTTPServer1Connect(AContext: TIdContext); 
    begin 
        if AContext.Connection.Socket.Binding.Port = 443 then 
        TIdSSLIOHandlerSocketBase(AContext.Connection.Socket).PassThrough := False; 
    end; 
    
  2. (優選的)使用新的TIdHTTPServer.OnQuerySSLPort事件告訴服務器哪個端口應該使用SSL或沒有,例如:

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