Parse.com REST API with cURL and C++ - c++

I have a raspberry pi that is running a c++ program. It now needs to talk to the Parse.com cloud so it seems the REST API is the best choice. I've been programming for a year and have truly hit a wall here.
EDIT: I've been able to get the code below to run. It successfully posts "south" in a new row under the "direction" column. I had to link my compiler to -lcurl.
My remaining question is how can I in this syntax add conditions to the query? For me the limiting query is
WHERE hardwareType = 2.
I can also GET all the results of my parse table if I comment out the CURLOPT_POSTFIELDS line inside curl_easy_init. How can I limit this request with the same query quoted above?
#include <iostream>
#include <curl/curl.h>
#include <string>
#include <sstream>
#include <stdexcept>
using namespace std;
int main()
{
CURL *curl;
CURLcode res;
struct curl_slist *headerlist=NULL;
headerlist = curl_slist_append( headerlist, "X-Parse-Application-Id: aaaaaaaaaaa");
headerlist = curl_slist_append( headerlist, "X-Parse-REST-API-Key: bbbbbbbbbbbbbbbb");
headerlist = curl_slist_append( headerlist, "Content-Type: application/json");
//headerlist = curl_slist_append(headerlist, "-d '{"direction":"south"}'");
curl = curl_easy_init();
if(curl)
{
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
curl_easy_setopt(curl, CURLOPT_URL, "https://api.parse.com/1/classes/testing");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "{\"direction\" : \"south\"}");
res = curl_easy_perform(curl);
if(res != CURLE_OK){
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
}
}
}

Related

I cant get the bittrex v3 api in C++ working

For the life of me I cannot get this to work. I have not been able to find example code for v3 of the Bittrex API so I have patched together what I've found for v1.1 and v3 in other programming languages.
I am using curl and openssl libraries.
I am getting a "URL using bad/illegal format or missing URL" error.
#include "../curl/curl.h"
#include <sha512.hh>
#include "hmac.h"
#include "sha.h"
string bittKey, bittSecret;
string timeStamp, hTTPMethod, uRI, requestBody, contentHash;
CURL *curl;
CURLcode res;
curl = curl_easy_init();
bittKey = "...";
bittSecret = "...";
timeStamp = std::to_string(time(nullptr));
uRI = "https://api.bittrex.com/v3/balances";
hTTPMethod = "GET";
requestBody = "";
contentHash = sw::sha512::calculate(requestBody);
string preSign = timeStamp + uRI + hTTPMethod + contentHash;
string apiSign = hmac_sha512(preSign, bittSecret);
struct curl_slist* headerList = NULL;
headerList = curl_slist_append(headerList, "Accept: application/json");
headerList = curl_slist_append(headerList, "Content-Type: application/json");
headerList = curl_slist_append(headerList, ("Api-Key: " + bittKey).c_str());
headerList = curl_slist_append(headerList, ("Api - Signature: " + apiSign).c_str());
headerList = curl_slist_append(headerList, ("Api-Timestamp: " + timeStamp).c_str());
headerList = curl_slist_append(headerList, ("Api-Content-Hash: " + contentHash).c_str());
curl_easy_setopt(curl, CURLOPT_URL, uRI);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerList);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
res = curl_easy_perform(curl);
if (res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
curl_slist_free_all(headerList);
curl_easy_cleanup(curl);
After quite a long time of searching and debugging through the curl libraries the solution was quite simple.
curl_easy_setopt(curl, CURLOPT_URL, uRI.c_str());
Oh and the timestamp doesn't work the way I have it above. It works as follows:
using namespace std::chrono;
milliseconds ms = duration_cast<milliseconds>(
system_clock::now().time_since_epoch()
);
timeStamp = std::to_string(ms.count());
The API is working now.

Downloading a file via curl in c++ from dropbox

I want to download a file from a dropbox shared link using curl in a c++ program
I found a dropbox api pdf that showed me how to do it
#include <stdio.h>
#include <curl/curl.h>
int main (int argc, char *argv[])
{
CURL *curl;
CURLcode res;
/* In windows, this will init the winsock stuff */
curl_global_init(CURL_GLOBAL_ALL);
/* get a curl handle */
curl = curl_easy_init();
if(curl) {
printf ("Running curl test.\n");
struct curl_slist *headers=NULL; /* init to NULL is important */
headers = curl_slist_append(headers, "Authorization: Bearer
<ACCESS_TOKEN>");
headers = curl_slist_append(headers, "Content-Type:");
headers = curl_slist_append(headers, "Dropbox-API-Arg:
{\"path\":\"/test.txt\"}");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL,
"https://content.dropboxapi.com/2/files/download");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
/* always cleanup */
curl_easy_cleanup(curl);
printf ("\nFinished curl test.\n");
}
curl_global_cleanup();
printf ("Done!\n");
return 0;
}
However, the comments supplied don't offer much explanation for me, and I can't get it to work.
I don't understand these three lines of code:
headers = curl_slist_append(headers, "Authorization: Bearer <ACCESS_TOKEN>");
headers = curl_slist_append(headers, "Content-Type:");
headers = curl_slist_append(headers, "Dropbox-API-Arg:{\"path\":\"/test.txt\"}");
I think I have to replace some stuff but I don't know what
"I think I have to replace some stuff but I don't know what" : Replace <ACCESS_TOKEN> with your actual access token.
You should also set the "Content-Type:" header to an appropriate value for the data you are fetching.
You must also change the value of the "Dropbox-API-Arg" header to match the file you are trying to get.
I finally found the solution to my problem.
Turns out I didn't have to use the Dropbox API
Here is the code
#include <iostream>
#include <curl/curl.h>
using namespace std;
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
size_t written;
written = fwrite(ptr, size, nmemb, stream);
return written;
}
int main(int argc, char** argv) {
CURL *curl;
FILE *fp;
const char* destination = "D:\\Desktop\\test.exe";
fp = fopen(destination, "wb");
curl = curl_easy_init();
/* A long parameter set to 1 tells the library to follow any Location: header
* that the server sends as part of an HTTP header in a 3xx response. The
*Location: header can specify a relative or an absolute URL to follow.
*/
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_URL, "https://www.dropbox.com/s/09nd26tdyto23yz/BankAccount.exe?dl=1"); // "dl=0"changed to "dl=1" to force download
// disabe the SSL peer certificate verification allowing the program to download the file from dropbox shared link
// in case it is not used it displays an error message stating "SSL peer certificate or SSH remote key was not OK"
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
CURLcode res;
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(fp);
if (res ==CURLE_OK)
cout << "OK";
else
cout << curl_easy_strerror(res);
return 0;
}
Thanks you guys for trying to help me. I appreciate

expected primary-expression before "__typeof__"

I am new to c++. I am trying a tiny piece of code to interact with a local instance of InfluxDB.
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <curl/curl.h>
#include <curl/curlver.h>
#include <curl/easy.h>
#include <curl/mprintf.h>
#include <curl/multi.h>
#include <curl/stdcheaders.h>
#include <curl/system.h>
#include <curl/typecheck-gcc.h>
using namespace std;
bool createInfluxDB(char *url, char *data) {
CURL *curl;
curl = curl_easy_init();
if(curl) {
CURLcode res;
/* What Content-type should i use?*/
struct curl_slist* headers = curl_slist_append(headers, "Content-Type: application/json");
/*--data-urlencode*/
char *urlencoded = curl_easy_escape(curl, data, int(strlen(data)));
curl_easy_setopt(curl, CURLOPT_URL, url); // Error here
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, urlencoded);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(urlencoded));
res = curl_easy_perform(curl);
/*omitted controls*/
curl_free(urlencoded);
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
return(true);
}
int main(int argc, char *argv[]){
char *url = "http://localhost:8086/query";
char *data = "q=CREATE DATABASE mydb";
/* should i change data string to json?
data = "{\"q\":\"CREATE DATABASE mydb\" }" */
bool res = createInfluxDB(url, data);
/*control result*/
return(0);
}
When trying to build it, i get the following errors:
expected primary-expression before '__typeof__'
extend list of errors
Any ideas where it might come from ?
I am working on codeblocks 16.01, using GCC compiler on Ubuntu.
That was due to curl library not being linked to the compiler. The correct way to fix this in Codeblocks editor:
Project>Build options..>"Linker settings" tab
Under Link libraries, click on add, type the library name on the popping window, click OK, click OK again. And reboot Codeblocks.

libcurl does not send json-Data

I try to pass some json-Code from c++ to a Python Flask Rest Api. But unfortunatelly this does not work and a don't see my mistake :(
This is my c-Code:
#include <stdio.h>
#include <curl/curl.h>
#include <string>
using namespace std;
int main(void)
{
CURL *curl;
CURLcode res;
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "localhost:5000/todo/api/v1.0/tasks/debug");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "{\"title\" : \"The Title\"}");
struct curl_slist *headers = NULL;
curl_slist_append(headers, "Accept: application/json");
curl_slist_append(headers, "Content-Type: application/json");
curl_slist_append(headers, "charsets: utf-8");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
res = curl_easy_perform(curl);
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}
This is the flask-function:
#POST DEBUG
#app.route("/todo/api/v1.0/tasks/debug", methods=['POST'])
def echo():
print(request.json)
return "ReturnString \n"
The output of the flask-Server looks like this:
None
127.0.0.1 - - [12/Jul/2017 12:49:15] "POST /todo/api/v1.0/tasks/debug HTTP/1.1" 200 -
So it seems to me that the json-Data is not passed to the flask-function.
I tried basically the same with text and it worked.
When I try the same thing with a curl-Call from the command-line, it works.
Curl-Command:
curl -i -H "Content-Type: application/json" -X POST -d '{"title":"Read a book"}' http://localhost:5000/todo/api/v1.0/tasks/debug
Output from Flask-Server:
{'title': 'Read a book'}
127.0.0.1 - - [12/Jul/2017 13:11:54] "POST /todo/api/v1.0/tasks/debug HTTP/1.1" 200 -
Any Help ?
After I ran your code and looked at the HTTP request with Wireshark, I found that the Content-Type header was not set to application/json. I then compared your code to the one produced by curl ... --libcurl example.c and found that request headers have to be added like so:
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, "charsets: utf-8");

How to use libcurl in c++ to send POST to elasticsearch

does anyone knows the exact syntax for using elasticsearch with libcurl?
#include <stdio.h>
#include <curl/curl.h>
int main(void)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:9200/bro-201409170900/http/ZinAvJ-ETT-mycy2jyRkdg/_update -d");
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "{\"script\" : \"ctx._source.longitude += 3\"}");
curl_easy_perform(curl);
curl_easy_cleanup(curl);
return 1;
}
This code does ont update the longitude parameter and I don't know why.
One should not specify the "-d' in the url. The command line tool is just build on top of libcurl.
If you want to see what the c code for the post request would look like you could use the libcurl option with command line .
example :
curl localhost:9200/bro-201409170900/http/ZinAvJ-ETT-mycy2jyRkdg/… -d '{ "script" : "ctx._source.longitude += 2"}' --libcurl output.c
A simple "C" implementation would look something on these lines
#include <stdio.h>
#include <curl/curl.h>
int main(void)
{
CURL *curl;
CURLcode res;
char *postFields = "{\"script\" : \"ctx._source.longitude += 3\"}";
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:9200/bro-201409170900/http/ZinAvJ-ETT-mycy2jyRkdg/_update");
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl,CURLOPT_POSTFIELDS,postFields);
curl_easy_setopt(curl,CURLOPT_POSTFIELDSIZE,strlen(postFields));
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
return res;
}