How to catch curl error i.e time out in multicurl environment - libcurl

I know how to catch curl error(time out error) message in single curl request. It's something like as follows.
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT_MS, 100);
res = curl_easy_perform(curl_handle);
If res is not curl_ok then it is some error like CURLE_OPERATION_TIMEDOUT
etc. But i want to know ,how to do that when we use multicurl request
where we use curl_multi_add_handle to add every curl request.How to set
timeout time and how to catch error message.
bool cuev_emit(struct curlev *cuev, char *url, struct curl_slist *headers,
curlev_cb_t cb, void *cb_data)
{
struct curlex *ex = NULL;
CURL *easy = curl_easy_init();
CURLMcode code;
if (!easy) {
xsyslog(LOG_WARNING, "curl_easy_init() failed for url '%s' (errno: %d)",
url, errno);
return false;
}
curl_easy_setopt(easy, CURLOPT_URL, url);
curl_easy_setopt(easy, CURLOPT_VERBOSE, 0L);
curl_easy_setopt(easy, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(easy, CURLOPT_WRITEFUNCTION, _curl_write_cb);
if (cb) {
ex = calloc(1, sizeof(*ex));
if (!ex) {
xsyslog(LOG_WARNING, "cuev_emit() failed: calloc(%d) with errno: %d",
(int)sizeof(*ex), errno);
curl_easy_cleanup(easy);
return false;
}
curl_easy_setopt(easy, CURLOPT_WRITEDATA, ex);
curl_easy_setopt(easy, CURLOPT_PRIVATE, ex);
} else {
curl_easy_setopt(easy, CURLOPT_WRITEDATA, NULL);
curl_easy_setopt(easy, CURLOPT_PRIVATE, NULL);
}
if (headers) {
/* TODO: добавить хидеры */
}
if ((code = curl_multi_add_handle(cuev->multi, easy)) != CURLM_OK) {
xsyslog(LOG_WARNING, "curl_multi_add_handle() failed for url '%s', code: %d",
url, code);
curl_easy_cleanup(easy);
return false;
}
return true;
}
Main part of the code is above. I am using https://gist.github.com/bhardwaj75/7600b67726ae2cdbfcf8c9c74300ab69#file-libvev-curl-c code.

The key is the curl_multi_info_read() function that returns info about completed transfers when the multi interface is used. Call that after curl_multi_perform() and timed out transfers will have that error code set.
See also the Driving with the multi interface chapter in the curl book, or a multi-interface using example such as multi-app.c.

Related

how to resolve SSL Connect Error in curl cpp

I have been working on an application which uses curl for communication to a server. Sometimes I get an "SSL Connect" error.
curl/libcurl version
7.86
operating system
Windows
I tried to increase verbosity on a machine where this issue is occurring, and got an "ssl handshake" error.
static int trace(CURL* handle, curl_infotype type, char* data, size_t size, void* userp)
{
switch (type)
{
case CURLINFO_TEXT:
CLIENT_LOG_DEBUG("== Info: %s", data);
break;
default:
return 0;
case CURLINFO_HEADER_OUT:
CLIENT_LOG_DEBUG("=> Send header: %s", data);
break;
case CURLINFO_DATA_OUT:
CLIENT_LOG_DEBUG("=> Send data: %s", data);
break;
case CURLINFO_SSL_DATA_OUT:
CLIENT_LOG_DEBUG("=> Send SSL data: %s", data);
break;
case CURLINFO_HEADER_IN:
CLIENT_LOG_DEBUG("<= Recv header: %s", data);
break;
case CURLINFO_DATA_IN:
CLIENT_LOG_DEBUG("<= Recv data: %s", data);
break;
case CURLINFO_SSL_DATA_IN:
CLIENT_LOG_DEBUG("<= Recv SSL data: %s", data);
break;
}
return 0;
}
/// at caller method:
CLIENT_LOG_INFO("TRACE_LEVEL_HIGH");
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, trace);
curl_easy_setopt(curl, CURLOPT_DEBUGDATA, 1L);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
/// Other curl options set while making connection:
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, payload.size());
#ifndef PLATFORM_UNIX
curl_easy_setopt(curl, CURLOPT_CAINFO, "curl-ca-bundle.crt");
#endif
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteResponseCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 20L);
curl::SendRequest:314 TRACE_LEVEL_HIGH
trace:45 == Info: Connected to <URL> (<IP>) port 443 (#0)
trace:45 == Info: schannel: disabled automatic use of client certificate
trace:45 == Info: ALPN: offers http/1.1
trace:45 == Info: schannel: failed to receive handshake, SSL/TLS connection failed
trace:45 == Info: Closing connection 0
curl::SendRequest:387 Failed sending curl request with error:SSL connect error
I am only getting CURLINFO_TEXT logs, no header out, data out, etc.
I am stuck here. This doesn't seem to be a certificate-related issue.
This error indicates the TLS handshake key exchange does not finish successfully. Try to experiment with adding one of the lines below:
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3 | CURL_SSLVERSION_MAX_TLSv1_2);
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3 | CURL_SSLVERSION_MAX_TLSv1_1);
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3 | CURL_SSLVERSION_MAX_TLSv1_0);

c++ How to continuously loop using Curl Multi Interface

im trying to loop continuously using curl multi interface. I have a timer function that needs to continuously loop through 4 urls at once, and go to the next 4, and so on etc.. I have successfully got the curl to poll my handles for its status, but when the handle hits 0, I try to reset the curl handle to loop again using new urls, but its not working. My timer function keeps working as it should, but curl multi stops, and gives me the same curl response using the same 4 urls, even though I try to reset the handles each time. Any help on this please, and thanks.. Below is a snippet of my code..
// Timer function that fires every 30 seconds with 4 different URL's each time
void timerFunction (QString url1,QString url2,QString url3,QString url4)
{
CURLMsg *msg = NULL;
std::string url1_ = url1.toStdString();
std::string url2_ = url2.toStdString();
std::string url3_ = url3.toStdString();
std::string url4_ = url4.toStdString();
CURLM *curlm;
int handle_count;
curlm = curl_multi_init();
CURL *curl1 = NULL;
curl1 = curl_easy_init();
CURL *curl2 = NULL;
curl2 = curl_easy_init();
CURL *curl3 = NULL;
curl3 = curl_easy_init();
CURL *curl4 = NULL;
curl4 = curl_easy_init();
if(curl1 && curl2 && curl3 && curl4)
{
curl_easy_setopt(curl1, CURLOPT_URL, url1_.c_str());
curl_easy_setopt(curl1, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl1);
curl_easy_setopt(curl2, CURLOPT_URL, url2_.c_str());
curl_easy_setopt(curl2, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl2);
curl_easy_setopt(curl3, CURLOPT_URL, url3_.c_str());
curl_easy_setopt(curl3, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl3);
curl_easy_setopt(curl4, CURLOPT_URL, url4_.c_str());
curl_easy_setopt(curl4, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl4);
CURLMcode code;
while(1)
{
code = curl_multi_perform(curlm, &handle_count);
if(handle_count == 0)
{
qDebug() << "Handle is 0, CURL Processing is done -- Repeat Process ";
break;
}
while ((msg = curl_multi_info_read(curlm, &handle_count)))
{
if (msg->msg == CURLMSG_DONE)
{
qDebug() << msg->msg;
curl_easy_reset(curl1);
curl_easy_reset(curl2);
curl_easy_reset(curl3);
curl_easy_reset(curl4);
handle_count = 4;
code = curl_multi_perform(curlm, &handle_count);
}
}
}
}
curl_easy_reset states clearly:
Re-initializes all options previously set on a specified CURL handle
to the default values. This puts back the handle to the same state as
it was in when it was just created with curl_easy_init.
It does not change the following information kept in the handle: live
connections, the Session ID cache, the DNS cache, the cookies and
shares.
What you need to do is use curl_multi_remove_handle and then curl_easy_cleanup for each handle in the loop once you are done with the response.
However you also need to use curl_multi_cleanup after the loop to remove all handles.
Your code would look like this:
// Timer function that fires every 30 seconds with 4 different URL's each time
void timerFunction (QString url1,QString url2,QString url3,QString url4)
{
CURLMsg *msg = NULL;
std::string url1_ = url1.toStdString();
std::string url2_ = url2.toStdString();
std::string url3_ = url3.toStdString();
std::string url4_ = url4.toStdString();
CURLM *curlm;
CURL* eh = NULL;
int still_running = 0, i = 0, msgs_left = 0;
curlm = curl_multi_init();
CURL *curl1 = NULL;
curl1 = curl_easy_init();
CURL *curl2 = NULL;
curl2 = curl_easy_init();
CURL *curl3 = NULL;
curl3 = curl_easy_init();
CURL *curl4 = NULL;
curl4 = curl_easy_init();
if(curl1 && curl2 && curl3 && curl4)
{
curl_easy_setopt(curl1, CURLOPT_URL, url1_.c_str());
curl_easy_setopt(curl1, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl1);
curl_easy_setopt(curl2, CURLOPT_URL, url2_.c_str());
curl_easy_setopt(curl2, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl2);
curl_easy_setopt(curl3, CURLOPT_URL, url3_.c_str());
curl_easy_setopt(curl3, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl3);
curl_easy_setopt(curl4, CURLOPT_URL, url4_.c_str());
curl_easy_setopt(curl4, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl4);
while(1)
{
curl_multi_perform(curlm, &still_running);
do {
int numfds = 0;
CURLMcode res = curl_multi_wait(curlm, NULL, 0, MAX_WAIT_MSECS, &numfds);
if (res != CURLM_OK) {
// handle error your way
}
curl_multi_perform(curlm, &still_running);
} while (still_running);
while ((msg = curl_multi_info_read(curlm, &msgs_left)))
{
if (msg->msg == CURLMSG_DONE)
{
eh = msg->easy_handle;
qDebug() << msg->msg;
curl_multi_remove_handle(curlm, eh);
curl_easy_cleanup(eh);
}
}
curl_multi_cleanup(cm);
}
}
Have not tested your code, but I modified it so you get an idea of how you should do it.

How do I kill the popup?

If you edit the following code to have valid certificate paths and a url that requires client certificates and then compile it with clang++ -lcurl curl.cpp on OS X (I'm using El Cap, but I think Mavericks or later behave the same way), and run the executable, you get a popup (shown below) from OS X asking if you want to allow the executable to use a private key in your keychain. This is annoying to users that know what's going on (internally curl on OS X uses the OS X security framework to load the client cert) but it's frightening for users who don't know what's happening because they think that the program is trying to access a private key in their keychain (as an aside this is an example of terrible UX from Apple as the popup message is a complete red herring).
The curl command line tool doesn't produce a popup, so either there is a lower level API I could use or it's because the executable is signed. The real program I'm trying to add this feature to is often distributed as source code so signing the executable isn't an ideal approach, as I can't distribute the signing keys or they'll be revoked. Does anyone know how I can prevent the popup programmatically?
#include <curl/curl.h>
#include <string>
using namespace std;
static size_t receiveResponseBytes(void *buffer, size_t size, size_t nmemb, void *userData) {
string *responseData = (string *) userData;
responseData->append((const char *) buffer, size * nmemb);
return size * nmemb;
}
void prepareCurlPOST(CURL *curl, string &bodyJsonString, string *responseData, struct curl_slist **chunk) {
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_URL, "https://example.dev/v1/check.json");
curl_easy_setopt(curl, CURLOPT_HTTPGET, 0);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, bodyJsonString.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, bodyJsonString.length());
*chunk = curl_slist_append(NULL, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, *chunk);
curl_easy_setopt(curl, CURLOPT_SSLCERT, "/path/to/client_cert.p12");
curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "P12");
curl_easy_setopt(curl, CURLOPT_SSLCERTPASSWD, "1234");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receiveResponseBytes);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, responseData);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 180);
curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/ca.crt");
}
int main(){
CURL* curl = curl_easy_init();
struct curl_slist *chunk = NULL;
string responseData;
long responseCode;
string bodyJsonString = "{\"version\": 1}";
prepareCurlPOST(curl, bodyJsonString, &responseData, &chunk);
fprintf(stderr,"%s\n",curl_easy_strerror(curl_easy_perform(curl)));
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
if (responseCode != 200) {
fprintf(stderr, "HTTP %d %s\n", (int) responseCode, responseData.c_str());
}
curl_slist_free_all(chunk);
curl_easy_cleanup(curl);
}
This is how I solved this problem (thanks to the Phusion folks for letting me tinker on this):
#include <curl/curl.h>
#include <string>
#include <CoreFoundation/CoreFoundation.h>
#include <Security/Security.h>
using namespace std;
const char* cert_label = "Name of the certificate as it appears in keychain access";
const char* domain = "https://example.dev/v1/check.json";
const char* ca_path = "/path/to/ca.crt";
const char* cert_path = "/path/to/client_cert.p12";
const char* cert_pw = "1234";
static OSStatus LookupKeychainItem(const char *label,
SecIdentityRef *out_cert_and_key)
{
OSStatus status = errSecItemNotFound;
if(kSecClassIdentity != NULL) {
CFTypeRef keys[4];
CFTypeRef values[4];
CFDictionaryRef query_dict;
CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
kCFStringEncodingUTF8);
/* Set up our search criteria and expected results: */
values[0] = kSecClassIdentity; /* we want a certificate and a key */
keys[0] = kSecClass;
values[1] = kCFBooleanTrue; /* we need a reference */
keys[1] = kSecReturnRef;
values[2] = kSecMatchLimitOne; /* one is enough, thanks */
keys[2] = kSecMatchLimit;
/* identity searches need a SecPolicyRef in order to work */
values[3] = SecPolicyCreateSSL(false, label_cf);
keys[3] = kSecMatchPolicy;
query_dict = CFDictionaryCreate(NULL, (const void **)keys,
(const void **)values, 4L,
&kCFCopyStringDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFRelease(values[3]);
CFRelease(label_cf);
/* Do we have a match? */
status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key);
CFRelease(query_dict);
}
return status;
}
SecAccessRef createAccess()
{
SecAccessRef access=NULL;
if (SecAccessCreate(CFStringCreateWithCString(NULL, cert_label, kCFStringEncodingUTF8), NULL, &access)){
printf("SecAccessCreate failed\n");
return NULL;
}
return access;
}
static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
const char *cPassword,
SecIdentityRef *out_cert_and_key)
{
OSStatus status = errSecItemNotFound;
CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL,
(const UInt8 *)cPath, strlen(cPath), false);
CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
cPassword, kCFStringEncodingUTF8) : NULL;
CFDataRef pkcs_data = NULL;
if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
NULL, NULL, &status)) {
SecAccessRef access = createAccess();
const void *cKeys[] = {kSecImportExportPassphrase,kSecImportExportAccess};
//kSecTrustSettingsKeyUseAny
const void *cValues[] = {password,access};
CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
2L, NULL, NULL);
CFArrayRef items = NULL;
/* Here we go: */
status = SecPKCS12Import(pkcs_data, options, &items);
if(items)
CFRelease(items);
CFRelease(options);
CFRelease(pkcs_data);
}
if(password)
CFRelease(password);
CFRelease(pkcs_url);
return status;
}
static size_t receiveResponseBytes(void *buffer, size_t size, size_t nmemb, void *userData) {
string *responseData = (string *) userData;
responseData->append((const char *) buffer, size * nmemb);
return size * nmemb;
}
void prepareCurlPOST(CURL *curl, string &bodyJsonString, string *responseData, struct curl_slist **chunk) {
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_URL, domain);
curl_easy_setopt(curl, CURLOPT_HTTPGET, 0);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, bodyJsonString.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, bodyJsonString.length());
*chunk = curl_slist_append(NULL, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, *chunk);
curl_easy_setopt(curl, CURLOPT_SSLCERT, cert_label);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receiveResponseBytes);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, responseData);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 180);
curl_easy_setopt(curl, CURLOPT_CAINFO, ca_path);
}
void killKey(){
SecIdentityRef id = NULL;
if (LookupKeychainItem(cert_label,&id) != errSecItemNotFound){
CFArrayRef itemList = CFArrayCreate(NULL, (const void **)&id, 1, NULL);
const void *keys2[] = { kSecClass, kSecMatchItemList, kSecMatchLimit };
const void *values2[] = { kSecClassIdentity, itemList, kSecMatchLimitAll };
CFDictionaryRef dict = CFDictionaryCreate(NULL, keys2, values2, 3, NULL, NULL);
OSStatus oserr = SecItemDelete(dict);
if (oserr) {
CFStringRef str = SecCopyErrorMessageString(oserr, NULL);
printf("Removing Passenger Cert from keychain failed: %s Please remove the private key from the certificate labeled %s in your keychain.", CFStringGetCStringPtr(str,kCFStringEncodingUTF8), cert_label);
CFRelease(str);
}
CFRelease(dict);
CFRelease(itemList);
}
}
void preAuthKey(){
SecIdentityRef id = NULL;
if(LookupKeychainItem(cert_label,&id) == errSecItemNotFound){
OSStatus status = SecKeychainSetUserInteractionAllowed(false);
if(status != errSecSuccess){
printf("%s\n",CFStringGetCStringPtr(SecCopyErrorMessageString(status,NULL),kCFStringEncodingUTF8));
}
CopyIdentityFromPKCS12File("/path/to/client_cert.p12","1234",&id);
status = SecKeychainSetUserInteractionAllowed(true);
if(status != errSecSuccess){
printf("%s\n",CFStringGetCStringPtr(SecCopyErrorMessageString(status,NULL),kCFStringEncodingUTF8));
}
}
}
int main(){
preAuthKey();
CURL* curl = curl_easy_init();
struct curl_slist *chunk = NULL;
string responseData;
long responseCode;
string bodyJsonString = "{\"version\": 1}";
prepareCurlPOST(curl, bodyJsonString, &responseData, &chunk);
fprintf(stderr,"%s\n",curl_easy_strerror(curl_easy_perform(curl)));
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
if (responseCode != 200) {
fprintf(stderr, "HTTP %d %s\n", (int) responseCode, responseData.c_str());
}
curl_slist_free_all(chunk);
curl_easy_cleanup(curl);
killKey();
}

Reading emails from gmail POP3 account using libCurl

I'm currently working in a C++ project which has to be able to read emails from an gmail POP3 account just like the title says. Also is important to say that I need to download the attachments (is encode base64?) of the mail and its body.
The fact is that everyone recommend to use libCurl for this task, but the code sample on their web is not working.
I saw this example on Libcurl website:
#include <stdio.h>
#include <curl/curl.h>
int main(void)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl)
{
/* Set username and password */
curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password");
/* This will only fetch the message with ID "1" of the given mailbox */
curl_easy_setopt(curl, CURLOPT_URL, "pop3s://user#pop.example.com/1");
/* 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;
}
As you see, the code looks pretty easy for fetching email by email inside the inbox, but when i try to perform the operation with CURLcode curl_easy_perform(CURL *) the function doesn't return anything and the process 'dies' so i can't skip this line.
My code is the following one:
void MailServer::Open(char *username,char *password)
{
m_username = username; //username = example#gmail.com
m_password = password; //password = blabla123
curl = curl_easy_init();
curl_easy_setopt(curl,CURLOPT_USERNAME,username);
curl_easy_setopt(curl,CURLOPT_PASSWORD,password);
m_popsAccount = "pop3s://" + m_username +"/1";
curl_easy_setopt(curl, CURLOPT_URL, m_popsAccount.c_str());
res = curl_easy_perform(curl); //here does not return anything
}
I tried to find some 'clear' example on the web, but i really couldn't...
Someone could give me a hand with it? :)
I made it guys! Here's a good sample about how you can access a gmail acount and see what's inside. I'm currently working on parsing the information inside, because actually it only retrieves the amount of mails on inbox and its size.
If you change the url as "pops://pop.gmail.com:995/1" it will return the content of the messege and also including a base64 encoding for the attachments. Thanks Anyway... here is the code! :)
#pragma region Types
struct MemoryStruct {
char *memory;
size_t size;
};
#pragma endregion
void MailServer::Open(char *username,char *password)
{
m_username = username;
m_password = password;
struct MemoryStruct chunk;
chunk.memory = (char*) malloc(1); //crecerá según sea necesario con el realloc
chunk.size = 0; //no hay datos en este punto
//inicializacion
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
//login
curl_easy_setopt(curl,CURLOPT_USERNAME,username);
curl_easy_setopt(curl,CURLOPT_PASSWORD,password);
m_popsAccount = "pop3s://pop.gmail.com:995/";
curl_easy_setopt(curl, CURLOPT_URL, m_popsAccount.c_str());
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
//some servers needs this validation
curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
res = curl_easy_perform(curl);
if(res != CURLE_OK)
{
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
else
{
/*
here is where you can work with the data inside the chunk...
*/
printf("%s\n",chunk.memory); //here is the information
printf("%lu bytes retrieved\n", (long)chunk.size);
}
//se libera la memoria si hay datos
if(chunk.memory)
free(chunk.memory);
/* always cleanup */
curl_global_cleanup();
}
size_t MailServer::WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1);
if(mem->memory == NULL) {
/* out of memory! */
printf("not enough memory (realloc returned NULL)\n");
return 0;
}
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
return realsize;
}

libcurl crashing program after execution?

I am using libcurl to make request google server. The curl library is giving output , when i use curl variables as global every thing works fine but when i am using the curl variables as local inside a function or a class private members the program crashes. I am not able to catch where segmentation fault occurring.
Code is
void func1();
{
Internet_connection_through_curl internet_connection;
internet_connection.simple_program(query_url);
}
Internet_connection_through_curl::simple_program(string url)
{
CURL *curle;
CURLcode rese;
curle = curl_easy_init();
if(curle)
{
curl_easy_setopt(curle, CURLOPT_URL, url.c_str());
curl_easy_setopt(curle, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curle, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curle, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curle, CURLOPT_WRITEDATA , (void *)(&UF));
curl_easy_setopt(curle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curle, CURLOPT_HEADERFUNCTION, HeaderMemoryCallback);
rese = curl_easy_perform(curle);
fprintf(stderr , "Curl easy perform error----> %s\n" , curl_easy_strerror(rese));
if(rese != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",curl_easy_strerror(rese));
curl_easy_cleanup(curle);
}
}