`curl_easy_send` и` curl_easy_recv` через SSL: как обрабатывать `CURLE_AGAIN`? - PullRequest
0 голосов
/ 02 ноября 2018

curl_easy_send и curl_easy_recv возвращают 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, если мы хотим вызвать SSL_want.

Я пытался использовать CURLINFO_TLS_SSL_PTR, чтобы получить указатель сеанса OpenSSL; этот метод возвращает null всегда, однако, когда мы используем CURLOPT_CONNECT_ONLY.

Итак, как правильно обрабатывать CURLE_AGAIN с curl_easy_send и curl_easy_recv по SSL?

1 Ответ

0 голосов
/ 15 ноября 2018

Я наконец нашел решение. Я не понимаю, по какой причине команда libcurl реализовала CURLINFO_TLS_SSL_PTR таким образом, что она возвращает nullptr, даже если соединение установлено через SSL, а объект Curl все еще содержит указатель сеанса SSL, но не может вернуть его в правильном виде. путь. Я могу только надеяться, что они исправят эту проблему в будущих версиях, и пользователям libcurl не придется изобретать велосипед.

К счастью, мы можем получить сеанс SSL (хотя бы для OpenSSL) следующим образом:

  1. Используйте CURLOPT_SSL_CTX_FUNCTION, чтобы иметь возможность получить контекст SSL, когда Curl его создаст.
  2. Используйте SSL_CTX_set_info_callback с этим контекстом, чтобы иметь возможность перехватывать новое событие создания сеанса SSL.
  3. Используйте этот сеанс SSL с функцией SSL_want для правильной обработки CURLE_AGAIN.
...