2013-07-22 84 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; 
    
相关问题