I'm working on a project that needs a licensing system. So I decided to use the licensing system of my sales platform Gumroad.
It seems pretty straightforward, the only thing is that I can't seem to add custom data to a cURL request in C .
This is the example posted in the documentation:
curl https://api.gumroad.com/v2/licenses/verify \
-d "product_permalink=QMGY" \
-d "license_key=YOUR_CUSTOMERS_LICENSE_KEY" \
-X POST
This works very well from the Ubuntu Terminal, but when I try to implement it in C , it doesn't work.
This is the C code:
std::stringstream get_response()
{
std::stringstream str;
curl::curl_ios<std::stringstream> writer(str);
curl::curl_easy easy(writer);
easy.add<CURLOPT_URL>("https://api.gumroad.com/v2/licenses/verify");
easy.add<CURLOPT_POSTFIELDS>("product_permalink=QMGY");
easy.add<CURLOPT_POSTFIELDS>("license_key=YOUR_CUSTOMERS_LICENSE_KEY");
try
{
easy.perform();
}
catch (curl::curl_easy_exception error)
{
auto errors = error.get_traceback();
error.print_traceback();
}
return str;
}
It is able to get a response from the server, but it doesn't recognize the license key.
I assume that this is because CURLOPT_POSTFIELDS is not the right field to replace -d.
Does anyone know the right field to use?
There are like 300 different ones, and I have no clue which one is the right one.
Can someone please point me in the right direction?
CodePudding user response:
Per the curl documentation for the -d option:
-d, --data
(HTTP MQTT) Sends the specified data in a POST request to the HTTP server, in the same way that a browser does when a user has filled in an HTML form and presses the submit button. This will cause curl to pass the data to the server using the content-type application/x-www-form-urlencoded. Compare to -F, --form.
--data-raw is almost the same but does not have a special interpretation of the @ character. To post data purely binary, you should instead use the --data-binary option. To URL-encode the value of a form field you may use --data-urlencode.
If any of these options is used more than once on the same command line, the data pieces specified will be merged with a separating &-symbol. Thus, using '-d name=daniel -d skill=lousy' would generate a post chunk that looks like 'name=daniel&skill=lousy'.
If you start the data with the letter @, the rest should be a file name to read the data from, or - if you want curl to read the data from stdin. Posting data from a file named 'foobar' would thus be done with -d, --data @foobar. When -d, --data is told to read from a file like that, carriage returns and newlines will be stripped out. If you do not want the @ character to have a special interpretation use --data-raw instead.
Examples:
curl -d "name=curl" https://example.com
curl -d "name=curl" -d "tool=cmdline" https://example.com
curl -d @filename https://example.comSee also --data-binary, --data-urlencode and --data-raw. This option overrides -F, --form and -I, --head and -T, --upload-file.
Note the part about specifying -d multiple times.
CURLOPT_POSTFIELDS is the correct field to use. You are simply using it the wrong way. You need to set CURLOPT_POSTFIELDS only once, providing it with all of the data to be posted, in the correct format the server is expecting. Since you are trying to post a application/x-www-form-urlencoded format, the data needs to be name=value pairs separated by &, eg:
std::stringstream get_response()
{
std::stringstream str;
curl::curl_ios<std::stringstream> writer(str);
curl::curl_easy easy(writer);
easy.add<CURLOPT_URL>("https://api.gumroad.com/v2/licenses/verify");
easy.add<CURLOPT_POSTFIELDS>("product_permalink=QMGY&license_key=YOUR_CUSTOMERS_LICENSE_KEY");
try
{
easy.perform();
}
catch (curl::curl_easy_exception error)
{
auto errors = error.get_traceback();
error.print_traceback();
}
return str;
}
If any of the name or value data may contain reserved or non-ASCII characters, you will have to url-encode that data, such as with curl_easy_escape().
CodePudding user response:
pretty sure you forgot easy.add<CURLOPT_POST>(1);
