cURL C++ send accented chars - c++

I'm trying to send this string "ààà" via curl POST HTTP.
CURL *curl;
CURLcode res;
char* content = "value=ààà!";
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if (curl) {
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Accept:application/x-www-form-urlencoded");
headers = curl_slist_append(headers, "Content-Type:application/x-www-form-urlencoded");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:3000");
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, content);
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();
I tried to send wchat_t* (using CURLOPT_POSTFIELDSIZE, wcslen(content))
instead of char*, I didn't solved.
I even tried to send using content-type:application/json but I get Unexpected end of JSON input .

Related

Libcurl post request not working on Windows 7

I am trying to make a simple POST request to my https REST API and receive the response on a Windows 7 operation system. The firewall is deactivated and the certificate is inside the .exe directory.
Here is the code that I am using:
std::string postRequest(std::string json, std::string endpoint,std::string code,std::string patchOrPOST,std::string source)
{
CURL* curl;
CURLcode res;
std::string response;
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
std::string authorization = "Authorization: Basic " + code, portApiHttp = "Referer: " + portAPI + "/index.html", origin = "Origin: " + portAPI;//X-Requested-With: XMLHttpRequest
struct curl_slist* headers = NULL;
if (curl) {
headers = curl_slist_append(headers, "Connection: keep-alive");
headers = curl_slist_append(headers, "Content-Length: "+(int)strlen(json.c_str()));
headers = curl_slist_append(headers, authorization.c_str());
headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "Content-Type: application/json");
if (source.size() != 0)
{
headers = curl_slist_append(headers, source.c_str());
}
headers = curl_slist_append(headers, R"(sec-ch-ua: "Chromium";v="91")");
headers = curl_slist_append(headers, "sec-ch-ua-mobile: ?0");
headers = curl_slist_append(headers, "X - Requested - With: XMLHttpRequest");
headers = curl_slist_append(headers, origin.c_str());
headers = curl_slist_append(headers, "Sec-Fetch-Site: same-origin");
headers = curl_slist_append(headers, "Sec-Fetch-Mode: cors");
headers = curl_slist_append(headers, "Sec-Fetch-Dest: empty");
headers = curl_slist_append(headers, portApiHttp.c_str());
headers = curl_slist_append(headers, "Accept-Encoding: gzip, deflate, br");
headers = curl_slist_append(headers, "Accept-Language: en-US,en;q=0.9");
curl_easy_setopt(curl, CURLOPT_URL,endpoint.c_str());
curl_easy_setopt(curl, CURLOPT_CAINFO, "ca-bundle.crt");
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
if (patchOrPOST == "PATCH")
{
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PATCH");
}
else if (patchOrPOST == "PUT")
{
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
}
else if (patchOrPOST == "GET")
{
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
}
else if(patchOrPOST=="DELETE")
{
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
}
//curl_easy_setopt(curl, CURLOPT_PROXY, "127.0.0.1:8888");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5L);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 50L);
curl_easy_setopt(curl, CURLOPT_HEADER, 1);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
if (patchOrPOST != "GET")
{
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, json.size());
curl_easy_setopt(curl, CURLOPT_POST, 1);
}
res= curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
if (res!= CURLE_OK) {
curl_easy_cleanup(curl);
return "ERROR";
}
res= curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
if (res!= CURLE_OK) {
curl_easy_cleanup(curl);
return "ERROR";
}
res = curl_easy_perform(curl);
long http_code;
/* 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);
}
curl_global_cleanup();
return response;
}
Why does this code work on Windows 10, but has SSL issues on Windows 7?
Why does this code work on Windows 10, but has SSL issues on Windows 7?
Most likely, the server is requesting stronger cryptographic suites than what Windows 7 can provide.
I have similar issue with Windows 7 and libcurl. I have found a solution. I was using libcurl with schannel (default for windows when using vcpkg). The problem was solved when I built libcurl with openssl instead.
If you are using vcpkg, you can install libcurl with openssl with this command:
vckpg.exe install curl[openssl]
You can download a precompiled binary from curl site too. I got the hint solve this from this default windows build for curl:
https://github.com/curl/curl-for-win

C++ send zip file using google email with curl

I'm using c++ and curl for sending an email with attachments, a zip archive in this example. I receive the email on gmail but when I download the .zip if I try to extract the content with WinRar I got the error:
The archive is either in unknown format or damaged
The zip is okay, I can extract it before sending.
This is the function for sending the file:
int sendFile()
{
CURL *curl;
CURLcode res = CURLE_OK;
curl = curl_easy_init();
if(curl) {
struct curl_slist *headers = NULL;
struct curl_slist *recipients = NULL;
struct curl_slist *slist = NULL;
curl_mime *mime;
curl_mime *alt;
curl_mimepart *part;
const char **cpp;
/* This is the URL for your mailserver */
curl_easy_setopt(curl, CURLOPT_URL, "smtps://smtp.gmail.com:465");
curl_easy_setopt(curl, CURLOPT_USERNAME, "email");
curl_easy_setopt(curl, CURLOPT_PASSWORD, "password");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM_ADDR);
recipients = curl_slist_append(recipients, TO_ADDR);
recipients = curl_slist_append(recipients, CC_ADDR);
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
for(cpp = headers_text; *cpp; cpp++)
headers = curl_slist_append(headers, *cpp);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
mime = curl_mime_init(curl);
alt = curl_mime_init(curl);
/* Text message. */
part = curl_mime_addpart(alt);
curl_mime_data(part, inline_text, CURL_ZERO_TERMINATED);
part = curl_mime_addpart(mime);
curl_mime_subparts(part, alt);
curl_mime_type(part, "multipart/alternative");
slist = curl_slist_append(NULL, "Content-Disposition: inline");
curl_mime_headers(part, slist, 1);
/* File */
std::string attachment = "D:/report.zip";
part = curl_mime_addpart(mime);
curl_mime_type(part, "application/zip");
curl_mime_filedata(part, attachment.c_str());
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
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(recipients);
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_mime_free(mime);
}
return (int)res;
}
Can you help me to understand what' s wrong? The zip is in the email but I can' t open it once downloaded because is damaged.
Thank you!
I had a similar problem sending jpeg files and was able to solve it by encoding the data with curl_mime_encoder.
curl_mime_filedata(part, attachment.c_str());
curl_mime_encoder(part, "base64");
Perhaps this might work for your case as well.

C++: How can I Send binary data(protobuf data) using HTTP post request through a curl call

I am trying trying to make a POST request on a url with protobuf data. I don't know how/ where to add binary data. Below is my C++ program.
"
void sendContent()
{
using namespace std;
int Error = 0;
//CString str;
CURL* curl;
CURLcode res;
struct curl_slist *headerlist = NULL;
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
headerlist = curl_slist_append(headerlist, "Content-Type: application/x-protobuf");
//Set URL to recevie POST
curl_easy_setopt(curl, CURLOPT_VERBOSE, true);
curl_easy_setopt(curl, CURLOPT_POST, true);
curl_easy_setopt(curl, CURLOPT_HEADER, true);
curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:9090/info");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_global_cleanup();
}"
You should set the data pointer by curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);. In the meantime, you should set the data size by curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, length_of_data);.
You can find the libcurl post example in there.
And I copy the program below.
#include <stdio.h>
#include <curl/curl.h>
int main(void)
{
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) {
/* First set the URL that is about to receive our POST. This URL can
just as well be a https:// URL if that is what should receive the
data. */
curl_easy_setopt(curl, CURLOPT_URL, "http://postit.example.com/moo.cgi");
/* Now specify the POST data */
/* size of the POST data */
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, length_of_data);
/* binary data */
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
/* 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);
}
curl_global_cleanup();
return 0;
}
Fixing your original suggestion would probably make it something like this (based on the simplepost example from the libcurl web site):
#include <curl/curl.h>
int binarypost(char *binaryptr, long binarysize)
{
CURL *curl;
CURLcode res = CURLE_OK;
struct curl_slist *headerlist = NULL;
headerlist = curl_slist_append(headerlist, "Content-Type: application/x-protobuf");
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:9090/info");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, binaryptr);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, binarysize);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
}
return (int)res;
}

cUrl Problems with uploading files

Using cUrl ( windows ) and was trying to get an upload function to work. However, it just doesnt seem to work. Getting error ERROR_FILE_NOT_PROVIDED from anonfiles
Here is the API = https://anonfiles.com/docs/api
Here is my code:
std::string UploadPicture()
{
CURL *curl;
CURLcode res;
std::string readBuffer;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_URL, "https://api.anonfiles.com/upload");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "cache-control: no-cache");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "file=test.ini");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
return readBuffer;
}
return "Failed";
}
Any help is welcome. I have tried many other ways as well, but didnt manage to get it right.

Uploading a picture to a Password Protected Directory using libcurl and C++

I'm trying to upload pictures using c++ application with libcurl to my server, the file in my server is a protected directory, I tried everything I know but it didn't work.
struct curl_slist *headerlist = NULL;
const char * Picture = "C:\xxxx";
FILE *fd = fopen(Picture, "rb");
struct stat file_info;
fstat(fileno(fd), &file_info);
headerlist = curl_slist_append(headerlist, "user : xxxx");
headerlist = curl_slist_append(headerlist, "password : xxxxx");
headerlist = curl_slist_append(headerlist, "Content-Type: image/jpeg");
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, "http://xxxx.000webhostapp.com/Pictures");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_READDATA, fd);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (curl_off_t)file_info.st_size);
res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
MessageBox::Show("Picture Failed");
}
curl_easy_cleanup(curl);
curl_global_cleanup();
user and password are not HTTP headers, so you should not be passing them via CURLOPT_HTTPHEADER. Use CURLOPT_USERNAME and CURLOPT_PASSWORD instead. Also look at CURLOPT_HTTPAUTH.
Try this:
curl_global_init(CURL_GLOBAL_ALL);
...
const char *Picture = "C:\\xxxx";
FILE *fd = fopen(Picture, "rb");
if (!fd)
{
MessageBox::Show("Cannot Open Picture File");
}
else
{
struct stat file_info;
fstat(fileno(fd), &file_info);
curl = curl_easy_init();
if (!curl)
{
MessageBox::Show("Cannot Initialize CURL Session");
}
else
{
struct curl_slist *headerlist = curl_slist_append(NULL, "Content-Type: image/jpeg");
curl_easy_setopt(curl, CURLOPT_URL, "http://xxxx.000webhostapp.com/Pictures");
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_easy_setopt(curl, CURLOPT_USERNAME, "xxxx");
curl_easy_setopt(curl, CURLOPT_PASSWORD, "xxxxx");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_READDATA, fd);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (curl_off_t)file_info.st_size);
res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
MessageBox::Show("Picture Failed");
}
curl_easy_cleanup(curl);
}
fclose(fd);
}
...
curl_global_cleanup();