You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pro*C(C语言)中无需openssl/libcurl的HTTPS请求实现示例咨询

不依赖libcurl、openssl的HTTPS请求实现方案(Pro*C适配)

方案选型说明

  • ProC为Oracle提供的C语言内嵌SQL预编译环境,优先选择纯C实现、无外部动态依赖、可静态编译*的TLS协议栈,完全规避openssl、libcurl的编译和运行冲突
  • 目前适配性最优的轻量实现为mbed TLS(原PolarSSL),可直接将源码放入项目目录编译,无需依赖系统预装的加密、网络库
  • 若完全不想引入第三方源码,可直接调用系统自带的命令行工具发起HTTPS请求,零编译依赖

方案1:嵌入轻量TLS栈实现(稳定可控)

编译说明

将mbed TLS源码直接放入项目目录,和Pro*C生成的C代码一同编译即可,无需链接libcurl、libssl、libcrypto等系统动态库,可按需裁剪加密算法、TLS版本配置最小化编译体积。

代码示例(可直接嵌入.pc文件)

// 仅引入mbed TLS核心头文件,无openssl/curl依赖
#include "mbedtls/net_sockets.h"
#include "mbedtls/ssl.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/certs.h"
#include <stdio.h>
#include <string.h>

#define HTTPS_PORT "443"
#define REQUEST_HOST "example.com"
#define REQUEST_PATH "/"
#define REQUEST_BUF_SIZE 2048
#define RESPONSE_BUF_SIZE 4096

int https_request(void) {
    int ret;
    mbedtls_net_context server_fd;
    mbedtls_ssl_context ssl;
    mbedtls_ssl_config conf;
    mbedtls_entropy_context entropy;
    mbedtls_ctr_drbg_context ctr_drbg;
    const char *pers = "pro_c_https_client";
    unsigned char response_buf[RESPONSE_BUF_SIZE] = {0};

    // 初始化上下文资源
    mbedtls_net_init(&server_fd);
    mbedtls_ssl_init(&ssl);
    mbedtls_ssl_config_init(&conf);
    mbedtls_entropy_init(&entropy);
    mbedtls_ctr_drbg_init(&ctr_drbg);

    // 初始化随机数生成器
    if((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
                                   (const unsigned char *) pers, strlen(pers))) != 0) {
        goto clean_exit;
    }

    // 建立TCP连接
    if((ret = mbedtls_net_connect(&server_fd, REQUEST_HOST, HTTPS_PORT, MBEDTLS_NET_PROTO_TCP)) != 0) {
        goto clean_exit;
    }

    // 配置SSL参数
    if((ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT,
                                          MBEDTLS_SSL_TRANSPORT_STREAM,
                                          MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
        goto clean_exit;
    }

    // 证书校验配置,无需校验可设置为MBEDTLS_SSL_VERIFY_NONE
    mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
    mbedtls_ssl_conf_ca_chain(&conf, mbedtls_test_cas_pem, mbedtls_test_cas_pem_len);
    mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);

    if((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
        goto clean_exit;
    }

    mbedtls_ssl_set_hostname(&ssl, REQUEST_HOST);
    mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL);

    // 执行SSL握手
    while((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
        if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
            goto clean_exit;
        }
    }

    // 构造GET请求
    char request[REQUEST_BUF_SIZE] = {0};
    snprintf(request, REQUEST_BUF_SIZE,
             "GET %s HTTP/1.1\r\n"
             "Host: %s\r\n"
             "Connection: close\r\n"
             "\r\n", REQUEST_PATH, REQUEST_HOST);

    // 发送请求
    while((ret = mbedtls_ssl_write(&ssl, (const unsigned char *)request, strlen(request))) <= 0) {
        if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
            goto clean_exit;
        }
    }

    // 读取响应
    do {
        ret = mbedtls_ssl_read(&ssl, response_buf, RESPONSE_BUF_SIZE - 1);
        if(ret > 0) {
            // 此处可替换为业务逻辑处理响应内容
            printf("%.*s", ret, response_buf);
            memset(response_buf, 0, RESPONSE_BUF_SIZE);
        }
    } while(ret > 0 || ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE);

    ret = 0;
clean_exit:
    // 释放所有资源
    mbedtls_net_free(&server_fd);
    mbedtls_ssl_free(&ssl);
    mbedtls_ssl_config_free(&conf);
    mbedtls_ctr_drbg_free(&ctr_drbg);
    mbedtls_entropy_free(&entropy);
    return ret;
}

方案2:调用系统命令行实现(零编译依赖)

如果完全不想引入任何第三方源码,可直接调用系统预装的wget或curl命令行工具执行HTTPS请求,通过管道读取返回结果,无需修改项目编译配置:

#include <stdio.h>
#include <string.h>

int https_request_by_system_cmd(void) {
    FILE *cmd_fp;
    char buf[1024];
    // 发起HTTPS GET请求,无需校验证书可添加 -k 参数
    cmd_fp = popen("wget -qO- https://example.com", "r");
    if(cmd_fp == NULL) {
        return -1;
    }
    while(fgets(buf, sizeof(buf), cmd_fp) != NULL) {
        // 此处可替换为业务逻辑处理响应内容
        printf("%s", buf);
    }
    pclose(cmd_fp);
    return 0;
}

Pro*C适配注意事项

  • 上述两段纯C代码均可直接写入ProC的.pc源文件中,ProC预编译时会完整保留C逻辑,无需特殊适配
  • 方案1编译时,仅需将mbed TLS源码目录加入头文件搜索路径,关联对应.o文件即可,不会引入openssl、libcurl的相关依赖
  • 生产环境使用方案1时,建议替换内置的测试根证书为业务实际用到的根证书,降低安全风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 14:39:03