我正在使用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?
答案 0 :(得分:7)
是的,您可以对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;
如果您使用的是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;
(首选)使用新的TIdHTTPServer.OnQuerySSLPort
事件告诉服务器哪个端口应使用SSL,例如:
procedure TForm1.IdHTTPServer1QuerySSLPort(APort: TIdPort; var VUseSSL: Boolean);
begin
VUseSSL := (APort = 443);
end;