You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何防止KeepAlive=true时TIdHTTPServer发送多余HTML内容?

问题:KeepAlive=true时Indy HTTP服务器发送多余HTML内容

环境与场景

  • 使用C++Builder XE6 + Indy 10.6.0.5122搭建REST服务器,核心组件为TIdHTTPServer和TIdServerIOHandlerSSLOpenSSL
  • 客户端定时发起请求:每5000毫秒发送一次GET请求,每60000毫秒发送一次POST请求
  • 服务器响应规则:收到GET请求返回200 OK及JSON内容;收到POST请求返回204 No Content无内容响应

异常现象

  • 当KeepAlive = false时,HTTP和HTTPS通信均正常
  • 当KeepAlive = true时,客户端会每隔与POST请求间隔一致的时间(约60000毫秒)收到服务器发送的多余HTML内容:
Recv  15-06-2026 15:40:02.851: <HTML><BODY><B>204 No Content</B></BODY></HTML><EOL>
  • 若将POST请求间隔改为10000毫秒,客户端也会每隔约10000毫秒收到该HTML内容,内容为上次POST响应的残留
  • 该HTML内容偶尔会紧跟POST请求到达,导致客户端触发EIdHTTPProtocolException异常,日志如下:
Error 15-06-2026 16:11:52.643: PostEquipment(): EIdHTTPProtocolException: POST /equipment <HTML><BODY><B>204 No Content</B></BODY></HTML>

服务器OnCommandGet事件处理代码

void __fastcall TMainForm::HTTPCommandGet (TIdContext *AContext, TIdHTTPRequestInfo *ARequestInfo, TIdHTTPResponseInfo *AResponseInfo)
{
    TCommandHandler Handler;

    // Initialize.
    Handler.Context                 = AContext;
    Handler.RequestInfo             = ARequestInfo;
    Handler.ResponseInfo            = AResponseInfo;
    Handler.ListHistory             = ListHistory;
    Handler.EditVehiclesURI         = EditVehiclesURI;
    Handler.ListVehiclesResponse    = ListVehiclesResponse;
    Handler.ListVehiclesAction      = ListVehiclesAction;
    Handler.ListVehiclesCondition   = ListVehiclesCondition;
    Handler.BtnVehiclesLimitsAsText = BtnVehiclesLimitsAsText;
    Handler.ListVehicles            = ListVehicles;
    Handler.EditEquipmentURI        = EditEquipmentURI;
    Handler.ListEquipmentResponse   = ListEquipmentResponse;
    Handler.TreeEquipment           = TreeEquipment;
    Handler.ListEquipment           = ListEquipment;
    Handler.EditStatusURI           = EditStatusURI;
    Handler.ListStatusResponse      = ListStatusResponse;
    Handler.ListStatus              = ListStatus;
    Handler.EditResultsURI          = EditResultsURI;
    Handler.ListResultsResponse     = ListResultsResponse;
    Handler.ListResults             = ListResults;

    // Add request to 'History' list-view.
    TThread::Synchronize(NULL, &Handler.LogRequest);

    // Process request.
    TThread::Synchronize(NULL, &Handler.ProcessRequest);

    // Check if request should be ignored.
    if (AResponseInfo->ResponseNo <= 0)
    {
        // Prevent sending response.
        AResponseInfo->HeaderHasBeenWritten = true;
        return;
    }

    // Generate headers.
    if (!AResponseInfo->HeaderHasBeenWritten)
        AResponseInfo->WriteHeader();

    // If only headers requested, clear content.
    if (ARequestInfo->CommandType == hcHEAD)
        AResponseInfo->ContentText = _D("");

    // Send response.
    String S = AResponseInfo->ContentText;      // NOTE: WriteContent() clears ContentText and ContentStream properties.
    AResponseInfo->WriteContent();
    AResponseInfo->ContentText = S;

    // Add response to 'History' list-view.
    TThread::Synchronize(NULL, &Handler.LogResponse);

    // Clear content.
    AResponseInfo->ContentText = _D("");
}

更新内容

客户端异常日志代码

try
{
    HTTP->PostJSON(Config.BaseURL + Config.ResourceEquipment, Devices.ToJSON());
}
catch (Exception &E)
{
    AddLog(logError, _D("PostEquipment(): ") + E.ClassName() + _D(": ") + HTTP->Request->Method + _D(" ") + HTTP->Request->URL + _D("\r\n") + E.Message);
}

Wireshark捕获结果

No. Time            Source          Destination     Protocol    Length  Info
68  31.044634600    192.168.1.49    192.168.1.72    TCP         271     1274 → 80 [PSH, ACK] Seq=3057 Ack=1712 Win=65400 Len=217 [TCP PDU reassembled in 70]
69  31.086929000    192.168.1.72    192.168.1.49    TCP         54      80 → 1274 [ACK] Seq=1712 Ack=3274 Win=65318 Len=0
70  31.087180000    192.168.1.49    192.168.1.72    HTTP/JSON   292     POST /equipment HTTP/1.1 , JSON (application/json)
71  31.101679800    192.168.1.72    192.168.1.49    HTTP        161     HTTP/1.1 204 No Content 
72  31.294104800    192.168.1.49    192.168.1.72    TCP         60      1274 → 80 [ACK] Seq=3512 Ack=1819 Win=65293 Len=0
73  31.294141700    192.168.1.72    192.168.1.49    HTTP        103     Continuation
74  31.513229700    192.168.1.49    192.168.1.72    TCP         60      1274 → 80 [ACK] Seq=3512 Ack=1868 Win=65244 Len=0
  • 第73行的TCP Continuation包含客户端收到的多余HTML内容,Wireshark将其识别为独立的异常HTTP响应

提问

如何防止服务器在KeepAlive = true时发送这些多余的HTML内容?


内容的提问来源于stack exchange,提问作者Martin Nijhoff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 21:12:03