Because of variable my_description changes frequently I get this error:
{"code": 50109, "message": "The request body contains invalid JSON."}
It is possible to modify the code below to verify if libcurl gets an error when sending the message to webhook? I want to print when the message is sent and when exist an error in sending a message.
I tried this:
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
but it is not helpful.
Anybody can help me, please? Thanks!
#include <stdio.h>
#include <curl/curl.h>
#define nullptr ((void*)0)
int main() {
char message[65500];
int max_len = sizeof message;
CURL *curl;
CURLcode res;
char webhook[] = "DISCORD_WEBHOOK";
char my_description[] = "Description";
snprintf(message, max_len,"{\"username\": \"Test\",\"embeds\":[{\"description\": \"%s\"}]}", my_description);
curl = curl_easy_init();
if(curl) {
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_URL, webhook);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, message);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
return 0;
}
I tried this:
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
You might want to try this:
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
} else {
long response_code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
if(response_code != 200) {
// Error
}
}
An invalid JSON can be caused by quotes in my_description. Quotes must be replaced with escape sequences \".
Related
i use libcurl to search for mails in my mailbox.
But i cannot search mails with mails that inlcudes special chars (ä,ö,ü) in the subject.
int main(void)
{
CURL *curl;
CURLcode res = CURLE_OK;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_USERNAME, "myuser");
curl_easy_setopt(curl, CURLOPT_PASSWORD, "mypassword");
curl_easy_setopt(curl, CURLOPT_URL, "imaps://imap.gmail.com:993/INBOX");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "SEARCH SUBJECT Spülmaschine");
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);
}
return (int)res;
}
The mail cannot be found.
I searching a while but i cannot find some tipps.
Have someone any ideas ?
EDIT:// No one of the following trys will work:
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "SEARCH CHARSET UTF-8 SUBJECT \x53\x70\xc3\xbc\x6c\x6d\x61\x73\x63\x68\x69\x6e\x65");
//try it with UTF-7
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "SEARCH SUBJECT Sp+APw-lmaschine");
sprintf(strSearchString, "SEARCH CHARSET UTF-8 SUBJECT {%i}\r\n\x53\x70\xc3\xbc\x6c\x6d\x61\x73\x63\x68\x69\x6e\x65", strlen("\x53\x70\xc3\xbc\x6c\x6d\x61\x73\x63\x68\x69\x6e\x65"));
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, strSearchString);
After a long time i found a solution:
int main(void) {
CURL *curl;
CURLcode res = CURLE_OK;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_USERNAME, "myuser");
curl_easy_setopt(curl, CURLOPT_PASSWORD, "mypass");
curl_easy_setopt(curl, CURLOPT_URL, "imaps://imap.gmail.com:993");
// see RFC6855 IMAP Support for UTF-8
// imap.gmail.com states UTF8=ACCEPT in CAPABILITY response,
// so enable it to use UTF-8 in quoted strings.
// Must come after AUTHENTICATE and before SELECT.
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "ENABLE UTF8=ACCEPT");
res = curl_easy_perform(curl);
if (res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
// SELECT INBOX broken out from URL
if (res == CURLE_OK) {
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "SELECT INBOX");
res = curl_easy_perform(curl);
if (res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
if (res == CURLE_OK) {
// U+00FC LATIN SMALL LETTER U WITH DIAERESIS is \xC3\xBC in UTF-8
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "SEARCH
SUBJECT \"Sp\xC3\xBClmaschine\"");
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);
}
return (int) res;
}
While technically against protocol for including 8-bit characters, try SEARCH CHARSET UTF-8 SUBJECT "spülmaschine", and make sure you really are sending UTF-8 and not some other encoding. This will work on many servers. I do not know if you can make libcurl do it the proper way with an IMAP literal.
Note: some server software just doesn't support search that well. Remember, you can always use a tool like socat or python's imaplib, which give you pretty low level access to the protocol for experimenting.
Anyone can help me? i'm new in programming. How to make str and str2 compareable? (with code if can). or any code that can find a spesific word inside CURLcode
int main(void) {
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, "mabinogi.nexon.net");
/* example.com is redirected, so we tell libcurl to follow redirection*/
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
/* 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));
}
const char *str = curl_easy_strerror(res);
char *str2 = "nogi";
char *ff = strstr(str,str2); /*how to make this compareable?*/
if (ff) {
printf("word found!");
}
printf(*str);
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}
I am using this code to retrieve the data from the web browser using curl request in c language. I want to store the output in another file or buffer.
#include <stdio.h>
#include <curl/curl.h>
#include <curl/easy.h>
int main(void)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
/* example.com is redirected, so we tell libcurl to follow redirection */
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
/* 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);
}
return 0;
}
The output of this code is an html file. I want to store that html in another file or buffer. How to do that.
Thank you in advance.
Here's a modification to your code that writes the HTML response to a file:
#include <stdio.h>
#include <curl/curl.h>
#include <curl/easy.h>
int main(void)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
/* example.com is redirected, so we tell libcurl to follow redirection */
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
/* create an output file and prepare to write the response */
FILE *output_file = fopen("output_file.html", "w");
curl_easy_setopt(curl, CURLOPT_WRITEDATA, output_file);
/* 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: %sn",
curl_easy_strerror(res));
}
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}
Here are some related questions:
Saving a file using libcurl in C
Download file using libcurl in C/C++
I am a beginner in both C programming and libcurl and writing a program to fetch 1000 data values from a website. The website provides a job number and is redirected into another page for the results. Since, the code I have written is almost 500 lines, I am giving a general flow of the program and a short code which I think is the problematic area:
for(row=0;row<1000;row++)
{
------
url = "http://example.com";
curl_global_init(CURL_GLOBAL_ALL);
curlHandle = curl_easy_init();
if(curlHandle)
{
curl_easy_setopt(curlHandle, CURLOPT_TIMEOUT, 1800);
curl_easy_setopt(curlHandle, CURLOPT_ERRORBUFFER, curlErrStr);
curl_easy_setopt(curlHandle, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curlHandle, CURLOPT_URL, url);
curl_easy_setopt(curlHandle, CURLOPT_LOW_SPEED_LIMIT, dl_lowspeed_bytes);
curl_easy_setopt(curlHandle, CURLOPT_LOW_SPEED_TIME, dl_lowspeed_time);
curl_easy_setopt(curlHandle, CURLOPT_VERBOSE, 1L);
free(url);
curlErr = curl_easy_perform(curlHandle);
if(curlErr != CURLE_OK)
{
fprintf(stderr, "curl_easy_perform() failed: %s\n",curl_easy_strerror(curlErr));
}
else
{
curlErr = curl_easy_getinfo(curlHandle, CURLINFO_EFFECTIVE_URL, &url_new);
if((CURLE_OK == curlErr) && url_new)
{
sprintf(job,"%.*s\n", 18, url_new + 28);
if((ptr1 = strchr(job, '\n')) != NULL)
*ptr1 = '\0';
init_string(&s);
curl_easy_setopt(curlHandle, CURLOPT_TIMEOUT, 1800 );
curl_easy_setopt(curlHandle, CURLOPT_URL, url_new);
curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, writefunc);
curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, &s);
curlErr1 = curl_easy_perform(curlHandle);
printf("###### %lu\t%s\n",strlen(s.ptr),s.ptr);
free(s.ptr);
}
curl_easy_cleanup(curlHandle);
}
}
The functions are:
struct string
{
char *ptr;
size_t len;
};
void init_string(struct string *a)
{
a->len = 0;
a->ptr = malloc(a->len+1);
if (a->ptr == NULL)
{
fprintf(stderr, "malloc() failed\n");
exit(EXIT_FAILURE);
}
a->ptr[0] = '\0';
}
size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *a)
{
size_t new_len = a->len + size*nmemb;
a->ptr = realloc(a->ptr, new_len+1);
if (a->ptr == NULL)
{
fprintf(stderr, "realloc() failed\n");
exit(EXIT_FAILURE);
}
memcpy(a->ptr+a->len, ptr, size*nmemb);
a->ptr[new_len] = '\0';
a->len = new_len;
return size*nmemb;
}
The program shows no error of any kind. But out of the 1000 data, almost 50% couldn't be fetched due to curl_easy_perform() failed: Timeout was reached; and 20% of them have the output of the line strlen(s.ptr),s.ptr => 0. The rest are fetched correctly.
The verbose option for the zero output gave the following:
Connection #0 to host www.example.com left intact
getaddrinfo(3) failed for :80
Couldn't resolve host ''
Closing connection #1
Couldn't resolve host name
0
Please suggest the possible errors in the program.
Here is how I would fetch data using cURL
static CURL *curl = NULL;
CURL *initCURL(void)
{
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl)
{
// now set all the desired options
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
/* example.com is redirected, so we tell libcurl to follow redirection */
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
// etc
}
else
{ // else cURL object creation failed
// display appropriate error message
}
}
void endCurl(void)
{
// and then when all done with the cURL object,
// cleanup
curl_easy_cleanup(curl);
}
CURLcode execCurl( CURL *curl )
{
CURLcode res;
// Perform this request, for each fetch
res = curl_easy_perform(curl);
// Check for errors
if(res != CURLE_OK)
{
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
return( res );
}
Note:
I have had this same problem with the cURL timeout occurring.
The best recovery method I found is:
when a timeout occurs, retry the communication, requesting the same data
if I visit http://www.microsoft.com/
will redirect to http://www.microsoft.com/en-us/default.aspx
How can I get response/redirect url using CURL lib ?
I try
curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &reUrl);
this will get http://www.microsoft.com/
curl_easy_getinfo(curl, CURLINFO_REDIRECT_URL, &reUrl);
this will always get NULL
So thanks for help
Set CURLOPT_FOLLOWLOCATION to 1
#include <stdio.h>
#include <curl/curl.h>
int main(int argc, char** argv)
{
CURL *curl;
CURLcode curl_res;
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if (curl)
{
curl_easy_setopt(curl, CURLOPT_URL, "http://www.microsoft.com");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
/* Perform the request, curl_res will get the return code */
curl_res = curl_easy_perform(curl);
/* Check for errors */
if(curl_res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(curl_res));
if(CURLE_OK == curl_res)
{
char *url;
curl_res = curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url);
if((CURLE_OK == curl_res) && url)
printf("CURLINFO_EFFECTIVE_URL: %s\n", url);
}
/* always cleanup */
curl_easy_cleanup(curl);
/* we're done with libcurl, so clean it up */
curl_global_cleanup();
}
else
{
printf("cURL error.\n");
}
return 0;
}
You will see:
CURLINFO_EFFECTIVE_URL: http://www.microsoft.com/en-us/default.aspx