【DELPHI】一個TIdHTTPServer元件可以同時處理http和https請求嗎?
2020-12-16 DELPHI
我使用的是tidhttpserver元件,到目前為止執行良好,但是當我使用以下程式碼新增ssl支援時
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請求,如果我傳送http請求,則引發此異常
Error accepting connection with SSL. error:1407609C:SSL routines:SSL23_GET_CLIENT_HELLO:http request問題是:我可以使用單個tidhttpserver元件來處理http和https請求?如果答案是肯定的,怎麼做?如果答案是否定的,我必須建立兩個tidhttpserver例項,一個用於http,另一個用於https?
解決辦法
是的,http和https都可以使用一個TIdHTTPServer。
如果您使用的是indy 9,那麼它有一個bug,當所有客戶端連線連線到伺服器時,預設情況下都會啟用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;
如果您使用的是indy 10,則該錯誤已修復,因此預設情況下,所有客戶端連線都將禁用ssl,因此您可以:
如果連線在埠443上,則使用
OnConnect事件開啟SSL,例如:procedure TForm1.IdHTTPServer1Connect(AContext: TIdContext);
begin
if AContext.Connection.Socket.Binding.Port = 443 then
TIdSSLIOHandlerSocketBase(AContext.Connection.Socket).PassThrough := False;
end;
(首選)使用new
TIdHTTPServer.OnQuerySSLPort事件告訴伺服器哪個埠應使用ssl,例如:procedure TForm1.IdHTTPServer1QuerySSLPort(APort: TIdPort; var VUseSSL: Boolean);
begin
VUseSSL := (APort = 443);
end;