`curl_easy_send` 和 `curl_easy_recv` 通过 SSL:如何处理 `CURLE_AGAIN`?

`curl_easy_send` and `curl_easy_recv` over SSL: how to handle `CURLE_AGAIN`?

curl_easy_sendcurl_easy_recv return CURLE_AGAIN 由于网络连接速度慢而无法立即发送数据。

可以通过 libcurl 获取套接字并在该套接字上调用 pollselect;如果我们调用 curl_easy_send,我们将等到我们可以写入更多数据(即我们将使用 POLLOUTpoll),而对于 curl_easy_recv 我们将等到传入数据可用(即我们将使用 POLLINpoll)。

这种方法不适用于SSL连接,因为即使我们读取SSL数据,OpenSSL也可能需要写入(例如,执行新的握手)。所以,即使我们使用 curl_easy_send,我们也不知道我们是否必须使用 POLLINPOLLOUT

OpenSSL 具有针对该问题的 SSL_want 功能。但是,如果我们想调用 SSL_want.

,我们需要指向 SSL 会话的指针

我尝试使用 CURLINFO_TLS_SSL_PTR 来获取 OpenSSL 会话指针;但是当我们使用 CURLOPT_CONNECT_ONLY.

时,此方法总是 returns null

那么,如何通过 SSL 使用 curl_easy_sendcurl_easy_recv 以正确的方式处理 CURLE_AGAIN

我终于自己找到了解决办法。我不明白为什么 libcurl 团队实施 CURLINFO_TLS_SSL_PTR 的方式 return nullptr 即使连接是通过 SSL 建立的,Curl 对象仍然包含 SSL会话指针,但不能以正确的方式 return 它。我只希望他们能在未来的版本中解决这个问题,libcurl 用户将不必发明自行车。

幸运的是,我们可以通过以下方式获得 SSL 会话(至少 OpenSSL):

  1. 使用 CURLOPT_SSL_CTX_FUNCTION 可以在 Curl 创建它时获取 SSL 上下文。
  2. 在此上下文中使用 SSL_CTX_set_info_callback 以能够拦截新的 SSL 会话创建事件。
  3. 使用带有 SSL_want 功能的 SSL 会话以正确的方式处理 CURLE_AGAIN