I would like to map/write below curl (this curl works correctly in Linux terminal) into cpp code:
curl -X PUT -u "abc" \
"https://api123.pl" \
-d 'symbol=EB&side=ri&quantity=3'
Below is the CPP code using Curlpp library:
#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;
}
I have got error during compilation:
1.2putStackoverflow.cpp: In function ‘std::string getJSONAPIResultFromURL(const string&)’:
1.2putStackoverflow.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.2putStackoverflow.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.2putStackoverflow.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>&&’
The problem is with:
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));
To compile program:
g++ name1.cpp -lcurl -lcurlpp -o name1 && ./name1
I do not know how to write code to map/write curl into cpp using curlpp. Thank you for help.
PostFields
is just a typedef
for cURLpp::OptionTrait<std::string, cURL::CURLOPT_POSTFIELDS>
, I'm simplifying things below.
If you read the error messages carefully, they tell you exactly what is wrong:
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> >&)'
What that is basically saying is that you can't pass a std::list<std::string>
to the constructor of PostFields
. There are 4 candidate constructors reported in the error details, none of which take a std::list
as input:
PostFields()
PostFields(const std::string&)
PostFields(const PostFields&)
PostFields(PostFields&&)
Indeed, if you read the 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
expects a single char*
as input (which cURLpp wraps using std::string
), so you have to pass your PUT
data as a single url-encoded string, just like you do on the command line, eg:
request.setOpt(new curlpp::Options::PostFields("symbol=EB&side=ri&quantity=3"));
Where did you ever get the idea that you can use a std::list
with PostFields
?
BTW, per the cURLpp documentation, you do not really need to use new
when adding options to the curlpp::Easy
object:
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"));