`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_send
和 curl_easy_recv
return CURLE_AGAIN
由于网络连接速度慢而无法立即发送数据。
可以通过 libcurl
获取套接字并在该套接字上调用 poll
或 select
;如果我们调用 curl_easy_send
,我们将等到我们可以写入更多数据(即我们将使用 POLLOUT
和 poll
),而对于 curl_easy_recv
我们将等到传入数据可用(即我们将使用 POLLIN
和 poll
)。
这种方法不适用于SSL连接,因为即使我们读取SSL数据,OpenSSL也可能需要写入(例如,执行新的握手)。所以,即使我们使用 curl_easy_send
,我们也不知道我们是否必须使用 POLLIN
或 POLLOUT
。
OpenSSL 具有针对该问题的 SSL_want
功能。但是,如果我们想调用 SSL_want
.
,我们需要指向 SSL 会话的指针
我尝试使用 CURLINFO_TLS_SSL_PTR
来获取 OpenSSL 会话指针;但是当我们使用 CURLOPT_CONNECT_ONLY
.
时,此方法总是 returns null
那么,如何通过 SSL 使用 curl_easy_send
和 curl_easy_recv
以正确的方式处理 CURLE_AGAIN
?
我终于自己找到了解决办法。我不明白为什么 libcurl
团队实施 CURLINFO_TLS_SSL_PTR
的方式 return nullptr
即使连接是通过 SSL 建立的,Curl 对象仍然包含 SSL会话指针,但不能以正确的方式 return 它。我只希望他们能在未来的版本中解决这个问题,libcurl
用户将不必发明自行车。
幸运的是,我们可以通过以下方式获得 SSL 会话(至少 OpenSSL
):
- 使用
CURLOPT_SSL_CTX_FUNCTION
可以在 Curl 创建它时获取 SSL 上下文。
- 在此上下文中使用
SSL_CTX_set_info_callback
以能够拦截新的 SSL 会话创建事件。
- 使用带有
SSL_want
功能的 SSL 会话以正确的方式处理 CURLE_AGAIN
。
curl_easy_send
和 curl_easy_recv
return CURLE_AGAIN
由于网络连接速度慢而无法立即发送数据。
可以通过 libcurl
获取套接字并在该套接字上调用 poll
或 select
;如果我们调用 curl_easy_send
,我们将等到我们可以写入更多数据(即我们将使用 POLLOUT
和 poll
),而对于 curl_easy_recv
我们将等到传入数据可用(即我们将使用 POLLIN
和 poll
)。
这种方法不适用于SSL连接,因为即使我们读取SSL数据,OpenSSL也可能需要写入(例如,执行新的握手)。所以,即使我们使用 curl_easy_send
,我们也不知道我们是否必须使用 POLLIN
或 POLLOUT
。
OpenSSL 具有针对该问题的 SSL_want
功能。但是,如果我们想调用 SSL_want
.
我尝试使用 CURLINFO_TLS_SSL_PTR
来获取 OpenSSL 会话指针;但是当我们使用 CURLOPT_CONNECT_ONLY
.
null
那么,如何通过 SSL 使用 curl_easy_send
和 curl_easy_recv
以正确的方式处理 CURLE_AGAIN
?
我终于自己找到了解决办法。我不明白为什么 libcurl
团队实施 CURLINFO_TLS_SSL_PTR
的方式 return nullptr
即使连接是通过 SSL 建立的,Curl 对象仍然包含 SSL会话指针,但不能以正确的方式 return 它。我只希望他们能在未来的版本中解决这个问题,libcurl
用户将不必发明自行车。
幸运的是,我们可以通过以下方式获得 SSL 会话(至少 OpenSSL
):
- 使用
CURLOPT_SSL_CTX_FUNCTION
可以在 Curl 创建它时获取 SSL 上下文。 - 在此上下文中使用
SSL_CTX_set_info_callback
以能够拦截新的 SSL 会话创建事件。 - 使用带有
SSL_want
功能的 SSL 会话以正确的方式处理CURLE_AGAIN
。