You need to enable JavaScript to run this app. 如何在libcurl中正确配置SSL选项以连接Firebase实时数据库并解决Schannel报错
优惠活动
大模型
产品
解决方案
定价
更多

如何在libcurl中正确配置SSL选项以连接Firebase实时数据库并解决Schannel报错

libcurl连接Firebase实时数据库时TLS握手校验报错问题

现有代码实现

响应数据写入回调函数

static size_t my_write(void* buffer, size_t size, size_t nmemb, void* param) {
  std::string& text = *static_cast<std::string*>(param);
  size_t totalsize = size * nmemb;
  text.append(static_cast<char*>(buffer), totalsize);
  return totalsize;
}

主函数核心流程

int main() {
    std::string result;
    CURL* curl;
    CURLcode res;

    curl_global_init(CURL_GLOBAL_DEFAULT);

    curl = curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "https://example-project-62811-default-rtdb.firebaseio.com/.json");

        curl_easy_setopt(curl, CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_ALLOW_BEAST |
            CURLSSLOPT_NO_REVOKE);
        
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_write);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result);

        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

        res = curl_easy_perform(curl);

        curl_easy_cleanup(curl);

        if (CURLE_OK != res) {
            std::cerr << "CURL ERROR: " << res << "\n";
        }
    }
    curl_global_cleanup();

    std::cout << result << "\n\n";
}

故障现象

  • 上述代码访问普通公开第三方测试API时可正常运行
  • 访问Firebase实时数据库地址时,连接在TLS握手阶段失败,输出日志如下:
    Trying 35.201.97.85:443...
    Connected to example-project-62811-default-rtdb.firebaseio.com (35.201.97.85) port 443 (#0)
    schannel: next InitializeSecurityContext failed: Unknown error (0x80092013)
    Closing connection 0
    schannel: shutting down SSL/TLS connection with example-project-62811-default-rtdb.firebaseio.com port 443
    CURL ERROR: 35
    

已开展的排查操作

  1. 命令行直接执行curl访问同一地址,可完全复现相同报错
  2. 命令行添加--ssl-no-revoke参数后,curl可正常拉取Firebase返回的数据,对应执行命令为:
    curl https://example-project-62811-default-rtdb.firebaseio.com/.json --ssl-no-revoke
    
  3. 参照命令行参数的对应关系,在代码中设置了CURLOPT_PROXY_SSL_OPTIONS配置,携带CURLSSLOPT_NO_REVOKE标记,但配置未生效,依然报相同错误

问题根因

  • 代码中误用了libcurl配置项:CURLOPT_PROXY_SSL_OPTIONS的作用是配置libcurl与HTTPS代理服务器建立SSL连接时的行为,在未设置代理的场景下,这个配置完全不会影响libcurl和目标业务服务器(此处即Firebase)的直连TLS握手流程
  • Windows平台下,命令行--ssl-no-revoke参数对应的libcurl C API配置项是CURLOPT_SSL_OPTIONS,不是带PROXY前缀的版本
  • 报错码0x80092013对应Windows Schannel组件的证书吊销校验失败错误,本质是当前网络环境下无法正常连通证书吊销列表服务器,Schannel默认会拦截该类连接,设置CURLSSLOPT_NO_REVOKE标记即可跳过该校验逻辑

正确修改方案

将原有错误的代理SSL配置行,替换为作用于目标服务器直连的SSL配置项即可:

// 原错误写法:仅作用于代理连接的SSL配置,无代理时不生效
// curl_easy_setopt(curl, CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_ALLOW_BEAST | CURLSSLOPT_NO_REVOKE);

// 正确写法:作用于与目标服务器直连的SSL配置,和命令行参数效果对齐
curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_ALLOW_BEAST | CURLSSLOPT_NO_REVOKE);

补充说明:两个SSL配置项的作用域完全独立

  • CURLOPT_SSL_OPTIONS:控制libcurl和目标业务主机建立TLS连接时的行为
  • CURLOPT_PROXY_SSL_OPTIONS:仅控制libcurl和代理服务器建立TLS连接时的行为,无代理场景下不会参与目标主机的连接流程

内容的提问来源于stack exchange,提问作者batuhansenoglu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.11 02:54:04