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

如何用curlpp实现curl的-F文件上传POST请求?

问题描述

执行以下curl命令可正常向https://somewebsite.com/发送POST请求并上传test.txt文件:

curl -F "file=@test.txt" https://somewebsite.com/

但用curlpp实现相同功能时遇到问题,当前代码如下:

#include <cstdlib>
#include <cerrno>
#include <iostream>

#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
#include <curlpp/Exception.hpp>

int main(int argc, char *argv[])
{
  if (argc < 2)
  {
    std::cerr << "Wrong number of arguments!" << std::endl 
          << "Usage: test2 [url]" 
          << std::endl;
    return EXIT_FAILURE;
  }
  
  char *url = argv[1];
  
  try
  {
    curlpp::Easy request;
    
    request.setOpt(new curlpp::options::Url(url)); 
    //request.setOpt(new curlpp::options::Verbose(true)); 
    
    std::list<std::string> header; 
    header.push_back("User-Agent: \"testing post_request\""); 
    
    request.setOpt(new curlpp::options::HttpHeader(header));
    
    std::string POSTrequest = "file=@test.txt";
    
    request.setOpt(new curlpp::options::PostFields(POSTrequest));
    
    request.setOpt(new curlpp::options::PostFieldSize(POSTrequest.length()));
    request.setOpt(new curlpp::options::WriteStream(&std::cout));
    
    request.perform(); 
  }
  catch ( curlpp::LogicError & e )
  {
    std::cout << e.what() << std::endl;
  }
  catch ( curlpp::RuntimeError & e )
  {
    std::cout << e.what() << std::endl;
  }

  return EXIT_SUCCESS;
}

运行程序后服务器返回:

Segmentation fault

(Bad request. Check POST parameters. Hint: The curl command line requires an @ before local file names.)

尝试过去掉@、拆分字段、更换分隔符、使用绝对路径等方法均无效,系统为Fedora 41。

补充说明

执行curl -F "file=@test.txt" https://somewebsite.com/ --libcurl ./test.c生成了libcurl示例代码,可见curl是通过curl_mime系列函数实现文件上传,而非普通POST。现询问如何用curlpp实现相同功能?


解决方案

curlpp对应libcurl的curl_mime功能,需要使用curlpp::Mime和curlpp::Part类构建multipart/form-data请求,替换原来的PostFields方式。修改后的代码如下:

#include <cstdlib>
#include <iostream>
#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
#include <curlpp/Mime.hpp>
#include <curlpp/Exception.hpp>

int main(int argc, char *argv[])
{
    if (argc < 2)
    {
        std::cerr << "参数错误!" << std::endl 
                  << "用法: test2 [url]" 
                  << std::endl;
        return EXIT_FAILURE;
    }

    try
    {
        curlpp::Easy request;

        // 设置请求URL
        request.setOpt(new curlpp::options::Url(argv[1]));
        // 可选:开启调试模式查看请求详情
        // request.setOpt(new curlpp::options::Verbose(true));

        // 设置User-Agent
        std::list<std::string> headers;
        headers.push_back("User-Agent: \"testing post_request\"");
        request.setOpt(new curlpp::options::HttpHeader(headers));

        // 构建MIME表单
        curlpp::Mime mime(request);
        // 添加文件字段
        curlpp::Part filePart;
        filePart.setOpt(new curlpp::options::MimeFilename("test.txt"));
        filePart.setOpt(new curlpp::options::MimeName("file"));
        mime.addPart(filePart);

        // 将MIME表单绑定到请求
        request.setOpt(new curlpp::options::HttpPost(mime));

        // 设置响应输出流
        request.setOpt(new curlpp::options::WriteStream(&std::cout));

        // 执行请求
        request.perform();
    }
    catch (const curlpp::LogicError& e)
    {
        std::cerr << "逻辑错误: " << e.what() << std::endl;
        return EXIT_FAILURE;
    }
    catch (const curlpp::RuntimeError& e)
    {
        std::cerr << "运行时错误: " << e.what() << std::endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

关键修改点说明

  • 引入curlpp/Mime.hpp头文件,这是处理multipart/form-data请求的核心依赖
  • 移除PostFields和PostFieldSize设置,改用curlpp::Mime构建表单
  • 通过curlpp::Part创建文件字段:MimeFilename指定本地文件路径,MimeName对应表单字段名file
  • 用HttpPost选项将MIME表单绑定到请求,替代普通POST的参数设置

编译时需确保链接curlpp库,示例命令:

g++ -o test2 test2.cpp -lcurlpp -lcurl

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 02:22:06