【发布时间】:2019-08-02 09:35:20
【问题描述】:
我正在尝试将 HTTPS 支持添加到使用 Indy 用 Delphi XE7 编写的现有 Web 服务器。我编写了一个简单的应用程序,它只在每个 HTTPS 请求上返回一个日期/时间戳。
我向OnCommandGet 和OnException 事件添加了处理程序:
procedure TForm13.HTTPServerCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
AResponseInfo.ContentText := DateTimeToStr(Now());
AResponseInfo.ContentEncoding := 'utf8';
Log('Request: %s', [ARequestInfo.URI]);
end;
procedure TForm13.HTTPServerException(AContext: TIdContext; AException: Exception);
begin
Log('Exception raised %s:%s', [AException.ClassName, AException.Message]);
end;
绑定代码:
with HTTPServer do
begin
with Bindings.Add() do
begin
IP := '0.0.0.0';
Port := 443;
end;
Active := true;
end;
当我执行来自浏览器的请求时,在大多数情况下我会得到:
12.03.2019 0:50:29 EIdConnClosedGracefully 引发异常:连接正常关闭。 12.03.2019 0:50:29 EIdConnClosedGracefully 引发异常:连接正常关闭。 12.03.2019 0:50:30 请求:/ 12.03.2019 0:50:30 EIdConnClosedGracefully 引发异常:连接正常关闭。 12.03.2019 0:50:30 请求:/favicon.ico 12.03.2019 0:51:00 引发异常 EIdSocketError:Socket Error #10060 连接超时。它处理请求并且浏览器显示时间戳。但是为什么优雅的连接关闭会引发异常呢?
更让我困扰的是,有时在最后一次请求后 30 秒后,我又得到另一个异常,如下所示:
12.03.2019 1:44:53 EIdConnClosedGracefully 引发异常:连接正常关闭。 12.03.2019 1:44:53 EIdConnClosedGracefully 引发异常:连接正常关闭。 12.03.2019 1:44:53 请求:/ 12.03.2019 1:44:54 EIdConnClosedGracefully 引发异常:连接正常关闭。 12.03.2019 1:44:54 请求:/favicon.ico 12.03.2019 1:45:24 引发异常 EIdOSSLAcceptError:接受与 SSL 的连接时出错。观察到违反协议的 EOF它随机发生,有时是超时,有时是这个。这对我来说看起来不对。任何想法为什么会发生这种情况?
PS:在 Delphi 10.3 中,它的发生方式与在 Delphi XE7 中相同,因此可能所有 Indy 版本都会受到影响。
【问题讨论】:
-
附带说明,
utf8不是AResponseInfo.ContentEncoding属性的有效值。如果您希望文本为 UTF-8 编码,则需要设置AResponseInfo.CharSet属性。 -
您没有显示设置服务器的
Bindings集合的代码。你是让服务器监听端口 80 还是 443?您是否分配了OnQuerySSLPort事件处理程序?您描述的症状是由客户端断开连接引起的。EIdConnClosedGracefully完全正常,请忽略它。这意味着客户端在请求之间断开连接。 EOF 错误意味着客户端在 SSL/TLS 握手过程中断开连接。 -
我已经在帖子中添加了绑定代码,但我确信其中没有什么特别之处。我还尝试添加 OnQuerySSLPort(始终返回 true),它不会改变任何东西。
-
您如何准确配置分配给服务器的
SSLIOHandler? -
我在 SSLOptions 中尝试了不同的变体:模式:sslmServer 或 sslmUnassigned,SSLVersions:不同的集合,CertFile、KeyFile 和 RootCertFile 都分配给具有自创建证书的同一个文件。