使用libcurl发送HTTPS请求遇CURLE_UNSUPPORTED_PROTOCOL错误求助
排查libcurl HTTPS请求返回CURLE_UNSUPPORTED_PROTOCOL错误
问题现象
运行以下libcurl示例代码时,HTTP请求可正常执行,但HTTPS请求调用curl_easy_perform()返回CURLE_UNSUPPORTED_PROTOCOL错误:
#include <stdio.h> #include <curl/curl.h> int main(void) { CURL* curl; CURLcode res; curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); if (curl) { curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); #ifdef SKIP_PEER_VERIFICATION curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); #endif #ifdef SKIP_HOSTNAME_VERIFICATION curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); #endif auto resultThree = curl_easy_setopt(curl, CURLOPT_CA_CACHE_TIMEOUT, 604800L); res = curl_easy_perform(curl); if (res != CURLE_OK) fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); curl_easy_cleanup(curl); } curl_global_cleanup(); return 0; }
已执行的排查操作
- 执行
curl -V确认系统中的curl支持HTTPS - 使用以下CMake配置编译libcurl:
if(WIN32) cmake_dependent_option(CURL_USE_SCHANNEL "Enable Windows native SSL/TLS" OFF CURL_ENABLE_SSL OFF) option(CURL_WINDOWS_SSPI "Enable SSPI on Windows" ${CURL_USE_SCHANNEL}) endif() - 手动下载
cacert.crt并设置CURLOPT_CAINFO指定证书路径,相关选项调用均返回CURLE_OK:curl = curl_easy_init(); auto cacert = "C:\\GauravK\\CPP_17\\CURL_CPP\\CURL_CPP\\cacert.crt"; if (curl) { auto resultOne = curl_easy_setopt(curl, CURLOPT_CAINFO, const_cast<char*> (cacert)); auto resultTwo = curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); auto resultThree = curl_easy_setopt(curl, CURLOPT_CA_CACHE_TIMEOUT, 604800L); res = curl_easy_perform(curl); } - 尝试定义
SKIP_PEER_VERIFICATION和SKIP_HOSTNAME_VERIFICATION,问题未解决
排查思路与解决方案
1. 修正CMake配置,确保libcurl启用SSL支持
当前CMake配置中CURL_USE_SCHANNEL的依赖是CURL_ENABLE_SSL OFF,这会直接禁用Windows原生SSL/TLS支持。修改配置如下,强制启用SSL并开启Schannel:
if(WIN32) set(CURL_ENABLE_SSL ON) cmake_dependent_option(CURL_USE_SCHANNEL "Enable Windows native SSL/TLS" ON CURL_ENABLE_SSL ON) option(CURL_WINDOWS_SSPI "Enable SSPI on Windows" ${CURL_USE_SCHANNEL}) endif()
修改后重新编译libcurl,查看编译日志确认输出中包含“Using Schannel for SSL/TLS”类的提示。
2. 验证链接的libcurl库是否支持HTTPS
在测试代码中添加版本信息输出,确认当前链接的库支持HTTPS协议:
#include <stdio.h> #include <curl/curl.h> int main(void) { curl_version_info_data* info = curl_version_info(CURLVERSION_NOW); printf("libcurl version: %s\n", info->version); printf("Supported protocols: "); for(int i = 0; info->protocols[i]; i++) { printf("%s ", info->protocols[i]); } printf("\n"); // 原测试代码... }
如果输出中没有https,说明你链接的是未启用SSL的libcurl库,需检查编译链接路径,确保使用重新编译后的带SSL支持的库。
3. 检查全局初始化选项
将curl_global_init(CURL_GLOBAL_DEFAULT)替换为curl_global_init(CURL_GLOBAL_ALL),确保SSL相关的全局资源被正确初始化。
4. 确认URL格式正确性
检查URL是否存在全角字符、空格或其他特殊格式问题,确保使用标准的https://example.com格式。
内容的提问来源于stack exchange,提问作者Gaurav K
相关产品推荐
相关产品推荐

