i want to index data using curl command in c++
the curl command i am running through linux is getting updated in solr but not via c++ code
curl command is
curl http://192.168.0.164:8983/solr/collection2/update?commit=true -H 'Content-type: application/json' -d '[{"id":"4456", "to":"Life is to.", "cc":"unknown ", "subject":"Life"}]'
and c++ code i m trying to execute is not updating the solr
CURL *curl = curl_easy_init();
CURLcode res;
static const char *postthis="'[{\"id\":\"4123\",\"from\":\"tarana\", \"to\":\"anuja\", \"cc\":\"unknown cc\",\"bcc\":\"unknown bcc\", \"src_ip\":\"192.168.0.156\",\"dst_ip\":\"192.168.0.40\",\"dst_port\":\"5454\",\"dst_port\":\"4545\",\"subject\":\"abc def ghi jhkl\",\"content\":\"this is testing\",\"interfaceid\":\"1\",\"locationid\":\"1\",\"date_time\":\"2014-12-31T01:59:59Z\"}]'";
static const char *postthis1= "http://192.168.0.164:8983/solr/collection2/update?commit=true ";
static const char *postthis2= "'Content-type: application/json'";
struct curl_slist *list = NULL;
logger.LogError("postthis %s",postthis);
logger.LogError("postthis1 %s",postthis1);
logger.LogError("postthis2 %s",postthis2);
//curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL,postthis1 );
list = curl_slist_append(list, "-H");
list = curl_slist_append(list, postthis2);
list = curl_slist_append(list, "-d");
//if we don't provide POSTFIELDSIZE, libcurl will strlen() by itself
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(postthis));
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postthis);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
// Perform the request, res will get the return code
res = curl_easy_perform(curl);
//Check for errors
if(res != CURLE_OK){
logger.LogError("curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}else if(res == CURLE_OK){
logger.LogError("res is CURLE_OK");
}
//always cleanup
curl_easy_cleanup(curl);
Related
I want to create a shared link for a dropbox file using curl & C++ on a windows 10 desktop.
I've already manage to upload the file to a dropbox folder using curl & C++.
When I try to create the link with command line it works with
curl -X POST https://api.dropboxapi.com/2/sharing/create_shared_link_with_settings --header "Authorization: Bearer <TOKEN>" --header "Content-Type: application/json" --data "{\"path\":\"path_of_the_file\"}"
but when I use this code to do the same in C++ it hangs at < HTTP/1.1 100 Continue
Here is my code :
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if (curl) {
string readBuffer;
printf("Running curl test get shared link.\n");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE); //no ssl
struct curl_slist *headers = NULL; // init to NULL is important
headers = curl_slist_append(headers, "Authorization: Bearer <TOKEN>");
headers = curl_slist_append(headers, "Content-Type: ");
headers = curl_slist_append(headers, "Dropbox-API-Arg: {\"path\":\"path_of_file\"}");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POST, true);
curl_easy_setopt(curl, CURLOPT_VERBOSE, true);
curl_easy_setopt(curl, CURLOPT_URL, "https://api.dropboxapi.com/2/sharing/create_shared_link_with_settings");
// 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);
cout << readBuffer << endl;
printf("\nFinished curl test.\n");
}
curl_global_cleanup();
printf("Done get shared link!\n");
I've tried with content-type : application/json and adding fields but I can't reproduce what I'm doing with the command line
There are errors in the code, causing undefined behaviour.
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_easy_setopt(curl, CURLOPT_POST, true);
curl_easy_setopt(curl, CURLOPT_VERBOSE, true);
cUrl has a C API, C does not have overloads. Thus curl_easy_setopt is a multi-arg function, and the third argument type depends on the second argument value. CURLOPT_SSL_VERIFYPEER and CURLOPT_VERBOSE require long values, you pass the values as int. The size of the third argument is important exactly like this is in *printf functions. The proper calls must be
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
The second. 100 Continue means you have not passed the data for the POST request. The server received request and waits for further data. See
libcurl example - http-post.c.
I can't reproduce what I'm doing with the command line
Add the --libcurl to the command line for getting a C code performing the same actions as in the command line.
Thank you S.M. Here is the code that works
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if (curl) {
string readBuffer;
printf("Running curl test get shared link.\n");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); //no ssl
struct curl_slist *headers = NULL; // init to NULL is important
headers = curl_slist_append(headers, "Authorization: Bearer <TOKEN>");
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "{\"path\":\"path_to_the_file"}");
curl_easy_setopt(curl, CURLOPT_URL, "https://api.dropboxapi.com/2/sharing/create_shared_link_with_settings");
// 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);
cout << readBuffer << endl;
printf("\nFinished curl test.\n");
}
curl_global_cleanup();
printf("Done get shared link!\n");
This question already has answers here:
Save cURL content result into a string in C++
(7 answers)
Closed 1 year ago.
Here is my code:
CURL *curl;
CURLcode res;
curl = curl_easy_init();
std::string json_message = "{\r\n \"email\":\"test#abv.bg\",\r\n \"password\":\"asdasdasd\"\r\n}";
if(curl) {
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_URL, "https://www.examle.com/myUrl");
curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "Authorization: Bearer secretkeyHere");
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
const char *data = json_message.c_str();
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
curl_easy_perform(curl);
}
curl_easy_cleanup(curl);
The problem is that when I execute that code the response of the http request is printed directly into my console application. I would like to store the response in a string without printing it into the console without intention.
Do you see why it is printed unintentionally and how can I store the response in a string?
By default, curl writes the received data to stdout. You can change that by using curl_easy_setopt() to specify a custom CURLOPT_WRITEFUNCTION callback, giving it a string* pointer via CURLOPT_WRITEDATA. For example:
static size_t writeToString(void *data, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
std::string *str = static_cast<std::string*>(userp);
str->append(static_cast<char*>(data), realsize);
return realsize;
}
...
CURL *curl = curl_easy_init();
if (curl) {
...
std::string respStr;
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &writeToString);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &respStr);
CURLcode res = curl_easy_perform(curl);
// use respStr as needed...
curl_easy_cleanup(curl);
}
I'm trying to make an http post with libcurl library to create an InfluxDB database, as indicated in their website:
curl -i -XPOST http://localhost:8086/query --data-urlencode "q=CREATE DATABASE mydb"
It looks like my code is not working. It doesnt give me any errors but db is not created. But instead if i try to add some points to an existing database, with the same function, it works. I think i miss the correct way of adding "q=CREATE DATABASE mydb" part. How should i change my code?
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);
}
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);
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);
}
After analyzing packets with http post request (which was returning Bad Request) i arrived to the point that i shouldn't add query parameters as data. But instead it should be part of url. So after changing code like that, it works!
int main(int argc, char *argv[]){
char *url = "http://localhost:8086/query?q=CREATE+DATABASE+mydb";
bool res = createInfluxDB(url);
/*control result*/
return(0);
}
bool createInfluxDB(char *url) {
CURL *curl;
curl = curl_easy_init();
if(curl) {
CURLcode res;
struct curl_slist* headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
res = curl_easy_perform(curl);
/*omitted controls*/
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
return(true);
}
EDITED ANSWER:
You still got a missnamed var in a if statment:
if (urlencode) free(...
That should be
if (urlencoded) free(...
Then in your headers you set the application type as json and I don't think that's what you want.
Something like "application/x-www-form-urlencoded" may be better.
struct curl_slist* headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");
ORIGNIAL ANSWER:
A workaround could be in your
char *data = curl_easy_escape(curl, json, int(strlen(json)));
That overload data with a json var that doesn't exist ?
Something like this may work better:
data = curl_easy_escape(curl, data, int(strlen(data)));
I am tried this but it is not working let me know what is wrong with the following code:
static const char *postthis="[{\"id\":\"4000\", \"to\":\"Life is to.\", \"cc\":\"unknown cc\", \"subject\":\"Life is subject\"}]";
static const char *postthis1= "http://192.168.0.164:8983/solr/collection1/update?wt=json&commit=true ";
static const char *postthis2= "'Content-type: application/json'";
struct curl_slist *list = NULL;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL,postthis1 );
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postthis);
list = curl_slist_append(list, "-H");
list = curl_slist_append(list, postthis2);
list = curl_slist_append(list, "-d");
/* if we don't provide POSTFIELDSIZE, libcurl will strlen() by
itself */
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(postthis));
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK){
logger.LogError("curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
/* always cleanup */
curl_easy_cleanup(curl);
}
with the above code I am getting response on terminal window as :
{"responseHeader":{"status":0,"QTime":9}}
which is response of above request.
and in solr log I am getting following things:
INFO - 2016-05-19 11:22:10.778; [ x:collection1] org.apache.solr.update.DirectUpdateHandler2; start commit{,optimize=false,openSearcher=true,waitSearcher=true,expungeDeletes=false,softCommit=false,prepareCommit=false}
INFO - 2016-05-19 11:22:10.779; [ x:collection1] org.apache.solr.update.DirectUpdateHandler2; No uncommitted changes. Skipping IW.commit.
INFO - 2016-05-19 11:22:10.781; [ x:collection1] org.apache.solr.core.SolrCore; SolrIndexSearcher has not changed - not re-opening: org.apache.solr.search.SolrIndexSearcher
INFO - 2016-05-19 11:22:10.783; [ x:collection1] org.apache.solr.update.DirectUpdateHandler2; end_commit_flush
INFO - 2016-05-19 11:22:10.784; [ x:collection1] org.apache.solr.update.processor.LogUpdateProcessor; [collection1] webapp=/solr path=/update params={commit=true&[{"id":"4001", "from":"Life is to", "to":"unknown cc", "subject":"Life is subject"}]=&wt=json} {commit=} 0 8
Actual curl command is :
curl http://192.168.0.164:8983/solr/collection1/update?commit=true -H "Content-Type: application/json" -d '[{"id":"450", "to":"Life is .", "cc":"unknown", "subject":"Life"}]'
it is working fine for indexing.
I am trying to run a simple example using libcurl, but just running this simple example gives me CURLE_WRITE_ERROR when I execute the curl_easy_perform(...) command. Does anyone have any idea what I am doing wrong? I have also tried other sites besides example.com.
CURL *curl = curl_easy_init();
if(curl)
{
CURLcode res;
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
res = curl_easy_perform(curl); // returns CURLE_WRITE_ERROR always!
curl_easy_cleanup(curl);
}
OK turns out Joachim is right. I did need a write callback
size_t CurlWriteCallback(char* buf, size_t size, size_t nmemb, void* up)
{
TRACE("CURL - Response received:\n%s", buf);
TRACE("CURL - Response handled %d bytes:\n%s", size*nmemb);
// tell curl how many bytes we handled
return size*nmemb;
}
// ...
CURL *curl = curl_easy_init();
if(curl)
{
CURLcode res;
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &CurlWriteCallback);
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}