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

使用curl mime API将数组加密数据转为multipart/form-data 解决本地数据读取失败问题

libcurl mime接口构造multipart/form-data报错解决方法

报错根因

你触发错误的核心原因是接口使用错误:
curl_mime_filedata接口的入参要求是本地文件的路径,调用后libcurl会自动读取路径指向的文件内容作为表单字段值。你当前传入的是内存中的加密二进制数据,libcurl会把你传入的数据内容当作文件路径去读取,自然找不到对应文件,抛出「Failed to open/read local data from file/application」错误。

你查阅到的curl_formadd是旧版libcurl的表单操作接口,你当前使用的curl_mime系列是官方推荐的新版替代接口,不需要切换到旧接口,新版接口有对应的内存数据传入方法。

需要修改的代码点

  • 上传内存二进制数据作为文件字段:使用curl_mime_data传入内存数据指针和长度,搭配curl_mime_filename指定上传的文件名(根据后端接口要求调整)
  • 普通文本字段直接使用curl_mime_data传入内容即可,不要调用curl_mime_filedata
  • 你当前的回调函数返回值为0,会导致返回的响应头被截断,如果需要正常接收返回结果需要同步修正回调逻辑
  • 额外注意:你当前取cmdData前10个字节作为认证头的逻辑没有判断cmdData长度,当传入的数组长度小于10时会发生内存越界,建议补充长度校验

修正后完整代码

#include <string>
#include <vector>
#include <iostream>
#include <cstring>
#include <curl/curl.h>
#include <curl/easy.h>

#define SYSLOG_INFO std::clog

struct Post {
    std::string url, chunk;
    static constexpr auto HeaderSize = 10;
    // 修正回调函数,正常写入返回头
    size_t static callBackFunk(char* buffer, size_t size, size_t nmemb,
                               void* userdata)
    {
        size_t real_size = size * nmemb;
        std::string* resp_header = static_cast<std::string*>(userdata);
        resp_header->append(buffer, real_size);
        SYSLOG_INFO << __PRETTY_FUNCTION__ << " received " << real_size << " bytes header\n";
        return real_size;
    }

    std::string libcurl(const std::vector<uint8_t>& cmdData)
    {
        // 补充长度校验,避免越界
        if (cmdData.size() < HeaderSize) {
            SYSLOG_INFO << "cmdData length is less than required HeaderSize " << HeaderSize << "\n";
            return "";
        }

        CURL*              curl{nullptr};
        CURLcode           res;
        curl_mime*         form    = NULL;
        curl_mimepart*     field   = NULL;
        struct curl_slist* headers = NULL;
        static const char  buf[]   = "Expect:";

        curl = curl_easy_init();
        if (!curl) {
            SYSLOG_INFO << "curl_easy_init failed\n";
            return "";
        }
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

        form  = curl_mime_init(curl);
        // 第一个字段upfile:传入内存二进制数据作为文件内容
        field = curl_mime_addpart(form);
        curl_mime_name(field, "upfile");
        // 第三个参数用CURL_BINARY指明是二进制数据,避免libcurl自动处理转义
        curl_mime_data(field, reinterpret_cast<const char*>(cmdData.data()), cmdData.size(), CURL_BINARY);
        // 如果后端要求指定上传文件名,可保留这一行,文件名自行修改
        curl_mime_filename(field, "upload.bin");

        // 第二个字段filename:如果是传文件名文本就直接传文本内容,可按需求调整值
        field = curl_mime_addpart(form);
        curl_mime_name(field, "filename");
        curl_mime_data(field, "upload.bin", CURL_ZERO_TERMINATED);

        std::string header =
            std::string(cmdData.begin(), cmdData.begin() + HeaderSize);
        SYSLOG_INFO << "header = " << header << std::endl;
        std::string headerAuth = "SCPv2: " + header;

        headers = curl_slist_append(headers, headerAuth.c_str());
        headers = curl_slist_append(headers, buf);

        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_MIMEPOST, form);
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

        curl_easy_setopt(curl, CURLOPT_HEADERDATA, &chunk);
        curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, callBackFunk);
        // 如果需要接收响应体,可以额外加CURLOPT_WRITEDATA和CURLOPT_WRITEFUNCTION配置

        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);

        res = curl_easy_perform(curl);
        if (res != CURLE_OK) {
            std::cerr << " curl_easy_perform() failed "
                      << curl_easy_strerror(res) << std::endl;
        }

        curl_easy_cleanup(curl);
        curl_mime_free(form);
        curl_slist_free_all(headers);

        return chunk;
    }
};

int main() {
    // 测试用的cmdData长度要大于等于10,这里补全到10字节避免校验失败
    Post post {"http://www.example.com", "hello world"};
    post.libcurl({1,2,3,4,5,6,7,8,9,10});
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 15:54:05