https - 为什么这个 SSL_pending 调用总是返回零?

标签 https openssl winsock

此代码适用于使用阻塞套接字的 HTTPS 服务器:

  request := '';
  start := gettickcount;
  repeat
    if SSL_pending(ssl) > 0 then
      begin
      bytesin := SSL_read(ssl, buffer, sizeof(buffer)-1);
      if bytesin > 0 then
        begin
        buffer[bytesin] := #0;
        request := request + buffer;
        end
      else break; // read failed
      end; // pending
   until (gettickcount - start) > LARGETIMEOUT;
   // "request" is ready, though possibly empty

SSL_pending() 总是 返回零并且永远不会达到 SSL_read()。如果 SSL_pending() 调用被删除,则 SSL_read() 被执行。为什么 SSL_pending() 不指示有多少字节可用?

请注意,如果您调用 SSL_read() 并且返回的字节数小于您的缓冲区大小,那么您已经阅读了所有内容并完成了。

如果传入的数据大于您的缓冲区大小,则第一个 SSL_read() 调用会填充缓冲区,您可以重复调用 SSL_read() 直到无法填充缓冲区。

但是 如果传入的数据是缓冲区大小的精确倍数,则最后一 block 数据会填充缓冲区。如果您尝试另一个 SSL_read() 认为阻塞套接字上可能有更多数据,它会无限期挂起。因此希望首先检查 SSL_pending()。然而,这似乎不起作用。

如何避免卡在最终的 SSL_read() 上? (我无法想象答案是非阻塞的,因为这意味着您永远不能将 SSL_read 与阻塞一起使用。)

更新:以下作品。显然 SSL_pending() 在第一个 SSL_read() 之后才起作用:
  request := '';
  repeat
    bytesin := SSL_read(ssl, buffer, sizeof(buffer)-1);
    if bytesin > 0 then
      begin
      buffer[bytesin] := #0;
      request := request + buffer;
      end
    else break; // read failed
  until SSL_pending(ssl) <= 0;
  // "request" is ready, though possibly empty

最佳答案

您正在使用 SSL_pending()完全错误的方式。 OpenSSL 使用状态机,其中 SSL_pending()指示状态机是否有任何已缓冲并等待处理的未决字节。因为你从来没有调用 SSL_read() ,您永远不会缓冲任何数据或推进状态机。

关于https - 为什么这个 SSL_pending 调用总是返回零?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6616976/

相关文章:

ssl - 如何使用新的 HTTPS 本地主机证书

security - 通过 HTTP 强制使用 HTTPS

magento - 如何在 Mgt 开发环境中使用带有自签名证书的 HTTPS/SSL

c++ - 生成大小不是 16 的倍数的加密数据

c - ntdll.dll 中的 Winsock getaddrinfo 未处理的异常/崩溃

ssl - IIS 默认通配符 https 绑定(bind)与其他 SNI https 绑定(bind)

c - 如何读取/写入 RSA 结构中的公钥

iis - 即使添加到 curl-ca-bundle.crt,curl openssl 也无法验证 IIS 7 自签名证书

c++ - 连续性多个 WSASend() io 完成端口

c - 供客户端连接的多个套接字