Poloniex API "Invalid command" c++ libcurl - c++

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

Related

Trying to create a c++ PUT request with cURL with an object

Recently I want to PUT an object with c++ curl.
Terminal command like this:
PUT /ObjectName HTTP/1.1
Content-Length:ContentLength
Content-Type: ContentType
Host: BucketName.oss-cn-hangzhou.aliyuncs.com
Date: GMT Date
Authorization: SignatureValue
My code:
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(curl, CURLOPT_URL, "https://tva******.oss*****.aliyuncs.com");
curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);
auto size = to_string(file_info.st_size);
curl_slist* headerList = NULL;
headerList = curl_slist_append(headerList, ("Authorization: " + Authorization).c_str());
headerList = curl_slist_append(headerList, ("Date: " + finalTime).c_str());
headerList = curl_slist_append(headerList, ("Content-Type: application/octet-stream"));
headerList = curl_slist_append(headerList, ("Content-Length: " + size).c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerList);
res = curl_easy_perform(curl);
But its effect is PUT HTTP/1.1 not PUT /ObjectName HTTP/1.1
I want to put an object ,but there is no object, so it puts a bucket.
How to make a request like PUT /ObjectName HTTP/1.1.

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

Receiving unhandled NULL exception when using curl_easy_cleanup(curl)

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!

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.

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