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

TIdHTTP.Get()因TLSv1.3会话票阻塞问题求助

解决方案

针对你遇到的TLS会话票导致TIdHTTP.Get()阻塞的问题,可以尝试以下几种修复方式:

1. 修改TIdSSLIOHandlerSocketOpenSSL.Readable()方法

问题核心是Readable()把TLS层的会话票数据误判为应用层可读数据,导致后续SSL_read()阻塞。可以修改该方法,只在存在应用层数据时返回True:

function TIdSSLIOHandlerSocketOpenSSL.Readable(AMSec: Integer): Boolean;
var
  LState: TSSLState;
  LBytes: Integer;
  LBuffer: array[0..0] of Byte;
begin
  Result := inherited Readable(AMSec);
  if Result then
  begin
    // 先检查SSL是否有已解密的应用层数据待读取
    if SSL_pending(FSSL) > 0 then Exit;
    // 非阻塞peek,判断底层数据是否为应用层数据
    LState := FSSL.State;
    FSSL.State := ssl_st_read;
    try
      LBytes := SSL_peek(FSSL, @LBuffer, SizeOf(LBuffer));
      if LBytes <= 0 then
      begin
        // 没有应用层数据,可能是TLS控制帧(如会话票)
        Result := False;
      end;
    finally
      FSSL.State := LState;
    end;
  end;
end;

这段代码在确认底层socket可读后,先检查SSL缓冲区是否有现成的应用层数据;如果没有,通过SSL_peek()尝试非阻塞读取,若无法获取应用层数据,则判定为不可读,避免后续触发不必要的SSL_read()。

2. 在HTTP响应处理完成后清理TLS控制帧

在TIdCustomHTTP.DoRequest方法中,当确认所有HTTP响应数据已接收完毕后,添加一段代码处理TLS层的控制数据(如会话票),避免后续Readable()检测到它们:

// 假设在读取完响应内容、处理完响应头之后添加
var
  LBytes: Integer;
  LBuffer: array[0..1023] of Byte;
begin
  // 非阻塞读取,消耗TLS控制帧(会话票等)
  while True do
  begin
    LBytes := SSL_read(FSSL.IOHandler.FSSL, @LBuffer, SizeOf(LBuffer));
    if LBytes <= 0 then
    begin
      LBytes := SSL_get_error(FSSL.IOHandler.FSSL, LBytes);
      if (LBytes = SSL_ERROR_WANT_READ) or (LBytes = SSL_ERROR_WANT_WRITE) then
        Break;
      // 其他错误忽略,或根据情况处理
      Break;
    end;
    // 读取到的是TLS控制数据,无需处理,直接丢弃
  end;
end;

这段代码通过非阻塞的SSL_read()消耗掉TLS层的控制数据,确保后续判断KeepAlive时,Readable()不会因为这些数据返回True。

3. 调整KeepAlive判断逻辑,仅依赖HTTP协议头

修改TIdCustomHTTP.DoRequest中判断是否保持连接的逻辑,不再调用Response.KeepAlive触发Readable()检测,而是直接根据HTTP响应的Connection头来决定:

// 替换原来的KeepAlive判断代码
LKeepAlive := (Response.Connection = 'keep-alive') and not FForceClose;

这种方式严格遵循HTTP协议规范,只要响应头指定keep-alive就保持连接,否则关闭,彻底避免因TLS层数据导致的误判。不过需要注意,这种方式可能忽略某些服务器的非常规行为,但符合标准HTTP流程。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 22:32:42