提问人:Fooad Taha 提问时间:3/29/2023 最后编辑:273KFooad Taha 更新时间:3/29/2023 访问量:709
SSL 错误 OpenSSL SSL_write:从 c++98 libcrul 使用 curl 时出现 SSL_ERROR_ZERO_RETURN、errno 32
SSL error OpenSSL SSL_write: SSL_ERROR_ZERO_RETURN, errno 32 when using curl from c++98 libcrul
问:
我在一家公司工作,我们正在使用 libcurl 将数据从设备发送到云 大多数时候它都可以工作,但有时它只是抛出我在标题中的SSL错误,当错误发生时,它总是发送的第一条消息(数据是GZIP文件,由json文件+二进制/文档文件组成)
在日志中,它通常: 1.log . log用于发送,例如:
CurlSender::Send:url:https://xxx-us-east-1.xxx.xxxxxx.com:443/v1/upload,数据:
Xڼ»㜖¥W+?ö
ö鯴sΔIх4sc÷n֮À6|ê륚sαAI÷<÷$c_ÁpIÙFYF÷÷ÿ ®
ý¹¿[ÿퟷ [ɯdõ���û²鋱ÿþ矛ЌsɡϿþ ý{.ޫ湯²þ»l#ÿùûÿ3/4蟟û®ÿ^Gяsÿ&㖖뿂M蟲ÿq��ÿA®>Y«÷"Iÿg^§üù_ÿ坣]>ù5Ӹ¿®þߐ婒ƾaHRü㰸Gп
URL 中的 x 只是为了隐藏我的公司信息
然后在那之后,我得到这个日志: CurlSender::Send:发送结束并出现错误:OpenSSL SSL_write:SSL_ERROR_ZERO_RETURN,错误 32
该代码在运行名为 Gaia 的自定义 Linux 的 Linux 设备计算机上运行
我们正在使用 C++ 98(我知道很旧)
这是 CurlSender 函数代码的一部分,因为我无法共享所有内容:
static bool Send ( IN void* curl,
IN const std::map<std::string,std::string> & headersMap,
IN HttpClient::InitParams & initParams,
IN std::string& write_buffer,
IN char* err_buf,
IN std::string& unix_socket,
IN std::string& url,
IN const std::string& api_path,
IN const std::string& payload,
IN int timeout_secs,
IN bool is_multipart,
IN const std::string& file_path,
IN const std::string& target_file_path,
IN HttpClient::REQUEST_TYPE request_type,
IN bool use_fresh_connection,
OUT NAC::IS::SmartPtr<HttpClient::HttpResponse>& httpResponse )
{
void* slist = NULL;
void *post=NULL;
void *last=NULL;
// clear write buffer leftovers (if any)
write_buffer.clear();
std::string cookie_string;
...
switch (request_type)
{
case HttpClient::POST_REQUEST:
{
DM_SLOG( TD::All, "creating POST request");
if (!file_path.empty())
{
if (!payload.empty())
{
DM_SLOG(TE_IS, TD::Surprise, "uploading data from buffer and file is supported only when using multipart");
return false;
}
TE_EXT_FUNC(curl_easy_setopt_long)(curl, te_CURLOPT_POST, 1);
upload_file = true;
}
else
{
TE_EXT_FUNC(curl_easy_setopt_str)(curl, te_CURLOPT_POSTFIELDS, payload.c_str());
TE_EXT_FUNC(curl_easy_setopt_long)(curl, te_CURLOPT_POSTFIELDSIZE, payload.size());
}
}
}
break;
TE_EXT_FUNC(curl_easy_setopt_write_callback)(curl, te_CURLOPT_WRITEFUNCTION, &HttpClient::WriteToMemoryFunc);
TE_EXT_FUNC(curl_easy_setopt_ptr)(curl, te_CURLOPT_WRITEDATA, &write_buffer);
//set data
TE_EXT_FUNC(curl_easy_setopt_ptr)(curl, te_CURLOPT_HTTPHEADER, slist);
TE_EXT_FUNC(curl_easy_setopt_PROXYAUTH_BASIC_DIGEST_NTLM)(curl);
TE_EXT_FUNC(curl_easy_setopt_str)(curl, te_CURLOPT_ENCODING, ""); //tells the server that it can send the response compressed
TE_EXT_FUNC(curl_easy_setopt_long)(curl, te_CURLOPT_NOSIGNAL, 1); //needed to run in a MT env otherwise process will crush :-( see: http://curl.haxx.se/libcurl/c/curl_easy_setopt.html
TE_EXT_FUNC(curl_easy_setopt_str)(curl, te_CURLOPT_ERRORBUFFER, err_buf);
TE_EXT_FUNC(curl_easy_setopt_write_callback)(curl, te_CURLOPT_HEADERFUNCTION,&HttpClient::HeaderFunc);
TE_EXT_FUNC(curl_easy_setopt_ptr)(curl, te_CURLOPT_WRITEHEADER, &cookie_string);
httpResponse->m_url = full_url;
//set connection timeout
if (timeout_secs != -1)
{
TE_EXT_FUNC(curl_easy_setopt_long)(curl, te_CURLOPT_TIMEOUT, timeout_secs);
}
//client certs (if needed)
if (!initParams.m_client_cert_params.m_client_cert_path.empty())
{
TE_EXT_FUNC(curl_easy_setopt_str)(curl, te_CURLOPT_SSLCERT, initParams.m_client_cert_params.m_client_cert_path.c_str());
TE_EXT_FUNC(curl_easy_setopt_str)(curl, te_CURLOPT_SSLCERTTYPE, initParams.m_client_cert_params.m_client_cert_type.c_str());
if (!initParams.m_client_cert_params.m_client_cert_private_key_path.empty())
{
TE_EXT_FUNC(curl_easy_setopt_str)(curl, te_CURLOPT_SSLKEY, initParams.m_client_cert_params.m_client_cert_private_key_path.c_str());
TE_EXT_FUNC(curl_easy_setopt_str)(curl, te_CURLOPT_SSLKEYTYPE, initParams.m_client_cert_params.m_client_cert_private_key_type.c_str());
}
if (!initParams.m_client_cert_params.m_client_cert_private_key_password.empty())
{
TE_EXT_FUNC(curl_easy_setopt_str)(curl, te_CURLOPT_KEYPASSWD, initParams.m_client_cert_params.m_client_cert_private_key_password.c_str());
}
}
if(initParams.m_verbose_logs && !TE_EXT_FUNC(curl_easy_setopt_debug_callback)(curl, &HttpClient::s_CurlDebugCb))
{
DM_SLOG(TE_IS, TD::Surprise, "failed to set verbose looging");
}
if (use_fresh_connection)
{
TE_EXT_FUNC(curl_easy_setopt_long)(curl, te_CURLOPT_FRESH_CONNECT, 1L);
}
if (payload.size() < PAYLOAD_DEBUG_OUTPUT_SIZE)
{
DM_SLOG(TE_IS, TD::All, "<request> url: " << full_url << ", data:\n" << payload);
}
else
{
std::string part_of_data = payload.substr(0, PAYLOAD_DEBUG_OUTPUT_SIZE);
DM_SLOG(TE_IS, TD::All, "<request> url: " << full_url << ", data:\n" << part_of_data);
}
httpResponse->m_is_send_success = true;
bool res = TE_EXT_FUNC(curl_easy_perform )(curl);
if (post != NULL)
{
TE_EXT_FUNC(curl_formfree)(post);
}
if (!res)
{
DM_SLOG(TE_IS, TD::Surprise, "send ended with error: " << err_buf);
httpResponse->m_send_error = err_buf;
httpResponse->m_is_send_success = false;
cleanup(curl, slist, fd_upload, fd_download);
return false;
}
“TE_EXT_FUNC”只是调用 curl 命令或任何其他 linux 命令的包装器
当函数调用:“bool res = TE_EXT_FUNC(curl_easy_perform )(curl);”,然后输入 if(!res) 条件时,会发生错误。
我尝试搜索此错误的解决方案或原因,但找不到任何具体内容,根据 OpenSSL 网站:
SSL_ERROR_ZERO_RETURN TLS/SSL 对等方已通过发送close_notify警报关闭了要写入的连接。无法读取更多数据。请注意,SSL_ERROR_ZERO_RETURN并不一定表示基础传输已关闭。
所以我的问题是:
- 如何解决/处理这个问题?
- 如何启用完整的 curl 日志记录并记录整个错误以及所有相关内容,以帮助找到此 + 未来错误的原因,而不是仅仅键入“SSL_ERROR_ZERO_RETURN,errno 32”,这没有帮助
我知道这太长了,但提前感谢任何回答的人
答:
另一端在发回响应之前已关闭连接。由于它只发生,因此有时对等方可能只是过载。如果您有权访问服务器,您可能会找出确切的原因,并可能增加服务器的资源。
在客户端上,您无法执行任何操作来防止这种情况发生。客户端上的唯一方法是重试请求,并希望下次成功。
评论