如何将 PUT curl 映射到 CPP Curlpp?

How to map PUT curl into CPP Curlpp?

我想 map/write 下面的 curl(此 curl 在 Linux 终端中正常工作)进入 cpp 代码:

curl -X PUT -u "abc" \
    "https://api123.pl" \
    -d 'symbol=EB&side=ri&quantity=3'

下面是使用 Curlpp 库的 CPP 代码:

    #include <iostream>
    #include <sstream>
    #include <curlpp/cURLpp.hpp>
    #include <curlpp/Easy.hpp>
    #include <curlpp/Options.hpp>
    using namespace curlpp::options;
    using namespace std;
    /*
    curl -X PUT -u "abc" \
        "https://api123.pl" \
        -d 'symbol=EB&side=ri&quantity=3'
    g++ name1.cpp -lcurl -lcurlpp -o name1 && ./name1
    */
    string test(const std::string &url) {
        try {
            curlpp::Cleanup cleanup;
            curlpp::Easy request;
            request.setOpt<curlpp::Options::Url>(url);
            request.setOpt(new curlpp::options::UserPwd("abc"));
            request.setOpt(new curlpp::options::CustomRequest{"PUT"});
//    /*
    //does not compile
            std::list<std::string> postContent;
            postContent.push_back("symbol:EB");
            postContent.push_back("side:ri");
            postContent.push_back("quantity:3");
            request.setOpt(new curlpp::options::PostFields(postContent));
//    */     
            std:stringstream content;
            content << request;        
            return content.str().c_str();
        }
        catch (const curlpp::RuntimeError &e) {
            std::cout << "CURLpp runtime error: " << e.what() << std::endl;
        }
        catch (const curlpp::LogicError &e) {
            std::cout << "CURLpp logic error: " << e.what() << std::endl;
        }
        throw std::string("Error");
    }
    int main(int, char **) {
        try {
            cout << test("https://api123.pl");
        }
        catch(curlpp::RuntimeError & e) {
            std::cout << e.what() << std::endl;
        }
        catch(curlpp::LogicError & e)   {
            std::cout << e.what() << std::endl;
        }
        return 0;
    }

我在编译过程中遇到错误:

1.2putWhosebug.cpp: In function ‘std::string getJSONAPIResultFromURL(const string&)’:
1.2putWhosebug.cpp:31:67: error: no matching function for call to ‘curlpp::OptionTrait<std::__cxx11::basic_string<char>, CURLOPT_POSTFIELDS>::OptionTrait(std::__cxx11::list<std::__cxx11::basic_string<char> >&)’
   31 |         request.setOpt(new curlpp::options::PostFields(postContent));
      |                                                                   ^
In file included from /usr/include/curlpp/Option.hpp:251,
                 from /usr/include/curlpp/Easy.hpp:31,
                 from 1.2putWhosebug.cpp:4:
/usr/include/curlpp/Option.inl:129:1: note: candidate: ‘curlpp::OptionTrait<OptionType, opt>::OptionTrait() [with OptionType = std::__cxx11::basic_string<char>; CURLoption opt = CURLOPT_POSTFIELDS]’
  129 | OptionTrait<OptionType, option>::OptionTrait()
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/curlpp/Option.inl:129:1: note:   candidate expects 0 arguments, 1 provided
/usr/include/curlpp/Option.inl:123:1: note: candidate: ‘curlpp::OptionTrait<OptionType, opt>::OptionTrait(typename curlpp::Option<OptionType>::ParamType) [with OptionType = std::__cxx11::basic_string<char>; CURLoption opt = CURLOPT_POSTFIELDS; typename curlpp::Option<OptionType>::ParamType = const std::__cxx11::basic_string<char>&]’
  123 | OptionTrait<OptionType, option>::OptionTrait(typename Option<OptionType>::ParamType value)
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/curlpp/Option.inl:123:85: note:   no known conversion for argument 1 from ‘std::__cxx11::list<std::__cxx11::basic_string<char> >’ to ‘curlpp::Option<std::__cxx11::basic_string<char> >::ParamType’ {aka ‘const std::__cxx11::basic_string<char>&’}
  123 | OptionTrait<OptionType, option>::OptionTrait(typename Option<OptionType>::ParamType value)
      |                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
In file included from /usr/include/curlpp/Easy.hpp:31,
                 from 1.2putWhosebug.cpp:4:
/usr/include/curlpp/Option.hpp:145:8: note: candidate: ‘curlpp::OptionTrait<std::__cxx11::basic_string<char>, CURLOPT_POSTFIELDS>::OptionTrait(const curlpp::OptionTrait<std::__cxx11::basic_string<char>, CURLOPT_POSTFIELDS>&)’
  145 |  class OptionTrait : public Option<OptionType>
      |        ^~~~~~~~~~~
/usr/include/curlpp/Option.hpp:145:8: note:   no known conversion for argument 1 from ‘std::__cxx11::list<std::__cxx11::basic_string<char> >’ to ‘const curlpp::OptionTrait<std::__cxx11::basic_string<char>, CURLOPT_POSTFIELDS>&’
/usr/include/curlpp/Option.hpp:145:8: note: candidate: ‘curlpp::OptionTrait<std::__cxx11::basic_string<char>, CURLOPT_POSTFIELDS>::OptionTrait(curlpp::OptionTrait<std::__cxx11::basic_string<char>, CURLOPT_POSTFIELDS>&&)’
/usr/include/curlpp/Option.hpp:145:8: note:   no known conversion for argument 1 from ‘std::__cxx11::list<std::__cxx11::basic_string<char> >’ to ‘curlpp::OptionTrait<std::__cxx11::basic_string<char>, CURLOPT_POSTFIELDS>&&’

问题在于:

        std::list<std::string> postContent;
        postContent.push_back("symbol:EB");
        postContent.push_back("side:ri");
        postContent.push_back("quantity:3");
        request.setOpt(new curlpp::options::PostFields(postContent));

编译程序:

g++ name1.cpp -lcurl -lcurlpp -o name1 && ./name1

我不知道如何使用 curlpp 编写代码 map/write curl 到 cpp 中。谢谢你的帮助。

PostFields 只是 cURLpp::OptionTrait<std::string, cURL::CURLOPT_POSTFIELDS>typedef,我在下面进行简化。

如果您仔细阅读错误消息,它们会准确告诉您哪里出了问题:

error: no matching function for call to 'curlpp::OptionTrait<std::__cxx11::basic_string<char>, CURLOPT_POSTFIELDS>::OptionTrait(std::__cxx11::list<std::__cxx11::basic_string<char> >&)'

这基本上是说您不能将 std::list<std::string> 传递给 PostFields 的构造函数。错误详情中报了4个候选构造函数,其中none个取一个std::list作为输入:

PostFields()
PostFields(const std::string&)
PostFields(const PostFields&)
PostFields(PostFields&&)

的确,如果你阅读 cURLpp documentation, you can't create a PostFields from a std::list. Which makes sense, per the cURL documentation for CURLOPT_POSTFIELDS:

Pass a char * as parameter, pointing to the full data to send in an HTTP POST operation. You must make sure that the data is formatted the way you want the server to receive it. libcurl will not convert or encode it for you in any way. For example, the web server may assume that this data is url-encoded.

CURLOPT_POSTFIELDS 期望单个 char* 作为输入(cURLpp 使用 std::string 包装),因此您必须将 PUT 数据作为单个 url-编码的字符串,就像你在命令行上做的一样,例如:

request.setOpt(new curlpp::Options::PostFields("symbol=EB&side=ri&quantity=3"));

您从哪里想到可以将 std::listPostFields 一起使用?


顺便说一句,根据 cURLpp 文档,在向 curlpp::Easy 对象添加选项时,您实际上不需要使用 new

curlpp::Easy request;
request.setOpt(curlpp::Options::Url(url));
request.setOpt(curlpp::Options::UserPwd("abc"));
request.setOpt(curlpp::Options::CustomRequest("PUT"));
request.setOpt(curlpp::Options::PostFields("symbol=EB&side=ri&quantity=3"));