Receiving unhandled NULL exception when using curl_easy_cleanup(curl) - c++

I have a Unity application that uses a c++ plugin that I wrote for making http requests. This plugin uses curl libraries.
As per curl documentation, they recommend using curl_easy_cleanup(curl) as the last command, in order to free the handle and clean up all the resources.
Here's my code that makes a simple http POST request:
struct curl_slist *headers = NULL;
CURL *curl = NULL;
curl = curl_easy_init();
int httpCode(0);
if(curl)
{
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");
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
//Set remote URL
curl_easy_setopt(curl, CURLOPT_URL, endpoint.c_str());
std::string params;
for(std::unordered_map<std::string,std::string>::iterator it = parameters.begin(); it != parameters.end(); ++it)
{
params = it->first + ": " + it->second + " ";
headers = curl_slist_append(headers, (const char *)params.c_str());
}
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, jsonObject.c_str());
CURLcode res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ResponseRecievedCallback);
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//Uncommenting this line makes my application crash
//curl_easy_cleanup(curl);
}
However when I add this line, my unity app crashes with this following exception:
Receiving unhandled NULL exception
Obtained 13 stack frames.
#0 0x000001207a4438 in Curl_expire_clear
#1 0x00000120790e25 in Curl_close
I've spent the past couple of days online searching for some solution, read curl documentation but couldn't find any help. I'd appreciate if someone can explain why this might crash?
Thanks much!

Fixed the issue by making httpCode a long instead of an int (per documentation). I must've overlooked it before!

Related

Creating a shared link for a Dropbox file using curl & C++

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");

Poloniex API "Invalid command" c++ libcurl

I'm trying to solve it for many hours but nothing going better...
int main() {
CURL *curl_handle = curl_easy_init();
if(curl_handle) {
string post_data="";
struct curl_slist *headers=NULL;
string command = "command=returnBalances&nonce=" + to_string(time(0));
cout<<command<<endl;
string Secret = "mySecretCode";
string Sign = "Sign: "+ hmac::get_hmac(Secret, command, hmac::TypeHash::SHA512);
cout<<Sign<<endl;
post_data += command;
headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");
headers = curl_slist_append(headers, "Key: myKey");
headers = curl_slist_append(headers, Sign.c_str());
curl_easy_setopt(curl_handle, CURLOPT_URL, "https://poloniex.com/tradingApi");
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, post_data.length()+1);
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, post_data.c_str());
curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
}
curl_easy_perform(curl_handle);
curl_easy_cleanup(curl_handle);
return 0;
}
This returns to me
{"error":"Invalid command."}
I checked hmac function result threw website and they are equal.
Some people said that adding
"Content-Type: application/x-www-form-urlencoded"
can solve this, but not at this time.
Console output:
> POST /tradingApi HTTP/2
Host: poloniex.com
accept: */*
content-type: application/x-www-form-urlencoded
key: myKey
sign: resultOfHmacFunc
content-length: 40
Solution was to change from CURLOPT_POSTFIELDS to CURLOPT_COPYPOSTFIELDS

libcurl post - underscore replaced with space (ubuntu)

I'm trying to send email and password in a post request to my express nodejs server using curl c++. The post data has '_' changed to ' ' when I log it from server.
char emailtext[50];
char passwordtext[50];
int emailstrlen = wcstombs(emailtext, email->getText(), 50);
int passwordstrlen = wcstombs(passwordtext, password->getText(), 50);
long totalsize = emailstrlen + passwordstrlen;
strcat(emailtext, ":");
strcat(emailtext, passwordtext);
// "myemail#yahoo.com:mypassword\0"
curl_global_init(CURL_GLOBAL_ALL);
CURLcode res;
CURL* curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_URL, "https://localhost:3000/login");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
struct curl_slist *headers=NULL;
headers = curl_slist_append(headers, "Content-Type:text/plain; charset=utf-8");
cout << emailtext << endl;
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, emailtext);
/* pass our list of custom made headers */
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_perform(curl); /* post away! */
curl_slist_free_all(headers); /* free the header list */
curl_global_cleanup();
return true;
express nodejs server:
app.post('/login', bodyParser.text(), function (req, res) {
console.log("we got the post request for /login");
console.log("logging the body!");
console.log(req.body);
res.header('Content-type', 'text/plain');
return res.end('<h1>Hello, Secure World!</h1>');
});
say char* emailtext = "cool_stewj#yahoo.com:lololol"
output from log on server will then be "cool stewj#yahoo.com:lololol"
What's happening? I've tried url encoding the data which turned out to be silly and pointless. How do I get that underscore?
The terminal in ubuntu apparently doesn't show underscores, so any log output will have underscores replaced with spaces.
Btw that's a bad example of string code in beginning. Possible to just use one buffer. Just pointing it out.

CURLE_COULDNT_CONNECT - while Internet is ok and server is available

I get this error from Curl, yet, the site is available, and I see nothing going out on wireshark.
What might cause this error ?
I've try to run it against www.google.com and got the same error.
this very code was working a few hours ago. I have no idea what might cause this.
here is the code:
CURL *curl;
CURLcode res = CURLE_OK;
struct curl_slist *headers=NULL;
headers = curl_slist_append(headers, "Content-Type: text/xml");
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if(curl) {
struct rcvdstring s;
init_string(&s);
string FullAddress = URL+Method;
curl_easy_setopt(curl, CURLOPT_URL, FullAddress.c_str());
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
res = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, DATA.c_str());
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
char buf[1024];
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
res = curl_easy_perform(curl);
Respons.assign(s.ptr);
return res;
}
* Update - took the exe to another computer, it works there. This is local to my computer....
Ok, Moving the code to another computer - showed me the code is OK.
The problem was with Norton Internet Security that after a few days of developing decided to block my communication DLL.

error when creating folder on dropbox via libcurl

I am trying to make a c++ application that uses Dropbox. When I am trying to create a new folder I take the following error: {"error": "Not Found"} and "HTTP/1.1 404 Not Found".
I have followed the instruction of Dropbox's REST Api, so I have used the POST method. (I am not sure if I can use PUT, instead).
Here is my code:
void createDirectory(const char *new_Directory_Path)
{
string create_Directory_Url = "https://api.dropbox.com/1/fileops/create_folder/sandbox/test_folder";
CURL* curl = curl_easy_init();
if(!curl)
{
CURLcode res;
struct curl_slist *headers = NULL;
string my_header = "Authorization: OAuth oauth_version=\"1.0\", oauth_signature_method=\"PLAINTEXT\",
oauth_consumer_key=\""
+ m_consumer_key + "\", oauth_token=\"" + m_accessKey + "\", oauth_signature=\""
+ m_consumer_secret + "&" + m_accessSecret + "\"";
headers = curl_slist_append(headers, my_header.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
curl_easy_setopt(curl, CURLOPT_URL, create_Directory_Url.c_str());
res = curl_easy_perform(curl);
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
}
Please, does anyone have an idea about what am I doing wrong?
Looking at the documentation I belive you want to leave sandbox/test_folder off of the url and use root=sandbox & path=test_folder as form values.
Here is an example of submitting form parameters: http://curl.haxx.se/libcurl/c/postit2.html
EDIT:
I found another example, here: https://github.com/geersch/DropboxRESTApi/blob/master/src/part-3/README.md which seems to show the parameters being added to the url's query string rather than as form values. The doc page isn't clear. It just shows them as parameters but doesn't specify which kind.