From 01da578bf48319413eef36e03452d14e7f7aebf8 Mon Sep 17 00:00:00 2001 From: Wilfried Goesgens Date: Tue, 3 May 2011 19:52:05 +0000 Subject: [PATCH] Work on integrating libcurl <-> libev --- citadel/modules/curl/serv_curl.c | 413 +++++++++++++++++++++ citadel/modules/curl/serv_curl.h | 47 +++ citadel/modules/extnotify/extnotify.h | 8 +- citadel/modules/extnotify/extnotify_main.c | 6 +- citadel/modules/extnotify/funambol65.c | 160 ++++---- 5 files changed, 545 insertions(+), 89 deletions(-) create mode 100644 citadel/modules/curl/serv_curl.c create mode 100644 citadel/modules/curl/serv_curl.h diff --git a/citadel/modules/curl/serv_curl.c b/citadel/modules/curl/serv_curl.c new file mode 100644 index 000000000..a8db1f2c2 --- /dev/null +++ b/citadel/modules/curl/serv_curl.c @@ -0,0 +1,413 @@ +/* + * Copyright (c) 1998-2009 by the citadel.org team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * thanks to some guy in #libev + */ + +#include "sysdep.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include + +#include +#include "citadel.h" +#include "server.h" +#include "citserver.h" +#include "support.h" + +#include "ctdl_module.h" +#include "serv_curl.h" + +evcurl_global_data global; + + +extern struct ev_loop *event_base; + +void SockStateCb(void *data, int sock, int read, int write); + +#define MOPT(s, v) \ + do { \ + sta = curl_multi_setopt(mhnd, (CURLMOPT_##s), (v)); \ + if (sta) { \ + CtdlLogPrintf(CTDL_ERR, "error setting option " #s " on curl multi handle: %s\n", curl_easy_strerror(sta)); \ + exit (1); \ + } \ +} while (0) + + +void ____InitC_ares_dns(AsyncIO *IO) +{ + int optmask = 0; + if (IO->DNSChannel == NULL) { + optmask |= ARES_OPT_SOCK_STATE_CB; + IO->DNSOptions.sock_state_cb = SockStateCb; + IO->DNSOptions.sock_state_cb_data = IO; + ares_init_options(&IO->DNSChannel, &IO->DNSOptions, optmask); + } +} + + + +/***************************************************************************** + * libevent / c-ares integration * + *****************************************************************************/ +static void ____DNS_send_callback(struct ev_loop *loop, ev_io *watcher, int revents) +{ + AsyncIO *IO = watcher->data; + + ares_process_fd(IO->DNSChannel, ARES_SOCKET_BAD, IO->dns_send_event.fd); +} +static void ____DNS_recv_callback(struct ev_loop *loop, ev_io *watcher, int revents) +{ + AsyncIO *IO = watcher->data; + + ares_process_fd(IO->DNSChannel, IO->dns_recv_event.fd, ARES_SOCKET_BAD); +} + +void ____SockStateCb(void *data, int sock, int read, int write) +{ +/* + struct timeval tvbuf, maxtv, *ret; + + int64_t time = 10; +*/ + AsyncIO *IO = data; +/* already inside of the event queue. */ + + if (read) { + if ((IO->dns_recv_event.fd != sock) && + (IO->dns_recv_event.fd != 0)) { + ev_io_stop(event_base, &IO->dns_recv_event); + } + IO->dns_recv_event.fd = sock; + ev_io_init(&IO->dns_recv_event, ____DNS_recv_callback, IO->dns_recv_event.fd, EV_READ); + IO->dns_recv_event.data = IO; + ev_io_start(event_base, &IO->dns_recv_event); + } + if (write) { + if ((IO->dns_send_event.fd != sock) && + (IO->dns_send_event.fd != 0)) { + ev_io_stop(event_base, &IO->dns_send_event); + } + IO->dns_send_event.fd = sock; + ev_io_init(&IO->dns_send_event, ____DNS_send_callback, IO->dns_send_event.fd, EV_WRITE); + IO->dns_send_event.data = IO; + ev_io_start(event_base, &IO->dns_send_event); + } +/* + + ev_io_start(event_base, &IO->dns_io_event); + + maxtv.tv_sec = time/1000; + maxtv.tv_usec = (time % 1000) * 1000; + + ret = ares_timeout(IO->DNSChannel, &maxtv, &tvbuf); + } +*/ + if ((read == 0) && (write == 0)) { + ev_io_stop(event_base, &IO->dns_recv_event); + ev_io_stop(event_base, &IO->dns_send_event); + } +} + + + + + + +static void +gotstatus(evcurl_global_data *global, int nnrun) +{ + CURLM *mhnd; + CURLMsg *msg; + int nmsg; +/* + if (EVCURL_GLOBAL_MAGIC != global.magic) + { + CtdlLogPrintf(CTDL_ERR, "internal error: gotstatus on wrong struct"); + return; + } +*/ + global->nrun = nnrun; + mhnd = global->mhnd; + + CtdlLogPrintf(CTDL_ERR, "about to call curl_multi_info_read\n"); + while ((msg = curl_multi_info_read(mhnd, &nmsg))) { + CtdlLogPrintf(CTDL_ERR, "got curl multi_info message msg=%d", msg->msg); + if (CURLMSG_DONE == msg->msg) { + CtdlLogPrintf(CTDL_ERR, "request complete\n"); + CURL *chnd = msg->easy_handle; + char *chandle; + CURLcode sta = curl_easy_getinfo(chnd, CURLINFO_PRIVATE, &chandle); + if (sta) + CtdlLogPrintf(CTDL_ERR, "error asking curl for private cookie of curl handle: %s\n", curl_easy_strerror(sta)); + evcurl_request_data *handle = (void *)chandle; + if (global != handle->global || chnd != handle->chnd) + CtdlLogPrintf(CTDL_ERR, "internal evcurl error: unknown curl handle completed\n"); + sta = msg->data.result; + if (sta) { + CtdlLogPrintf(CTDL_ERR, "error description: %s\n", handle->errdesc); + CtdlLogPrintf(CTDL_ERR, "error performing request: %s\n", curl_easy_strerror(sta)); + } + long httpcode; + sta = curl_easy_getinfo(chnd, CURLINFO_RESPONSE_CODE, &httpcode); + if (sta) + CtdlLogPrintf(CTDL_ERR, "error asking curl for response code from request: %s\n", curl_easy_strerror(sta)); + CtdlLogPrintf(CTDL_ERR, "http response code was %ld\n", (long)httpcode); + CURLMcode msta = curl_multi_remove_handle(mhnd, chnd); + if (msta) + CtdlLogPrintf(CTDL_ERR, "warning problem detaching completed handle from curl multi: %s\n", curl_multi_strerror(msta)); + handle->attached = 0; + } + } + if (0 == nnrun) { + ev_unloop(EV_DEFAULT, EVUNLOOP_ONE); /* remove in production */ + } +} + +static void +stepmulti(evcurl_global_data *global, curl_socket_t fd) { + int nnrun; + CURLMcode msta = curl_multi_socket_action(global->mhnd, fd, 0, &nnrun); + if (msta) + CtdlLogPrintf(CTDL_ERR, "error in curl processing events on multi handle, fd %d: %s\n", (int)fd, curl_multi_strerror(msta)); + if (global->nrun != nnrun) + gotstatus(global, nnrun); +} + +static void +gottime(struct ev_loop *loop, ev_timer *timeev, int events) { + CtdlLogPrintf(CTDL_ERR,"waking up curl for timeout\n"); + evcurl_global_data *global = (void *)timeev->data; + stepmulti(global, CURL_SOCKET_TIMEOUT); +} + +static void +gotio(struct ev_loop *loop, ev_io *ioev, int events) { + CtdlLogPrintf(CTDL_ERR,"waking up curl for io on fd %d\n", (int)ioev->fd); + sockwatcher_data *sockwatcher = (void *)ioev->data; + stepmulti(sockwatcher->global, ioev->fd); +} + +static size_t +gotdata(void *data, size_t size, size_t nmemb, void *cglobal) { + evcurl_request_data *D = (evcurl_request_data*) data; + return CurlFillStrBuf_callback(D->ReplyData, size, nmemb, cglobal); +} + +static int +gotwatchtime(CURLM *multi, long tblock_ms, void *cglobal) { + CtdlLogPrintf(CTDL_ERR,"gotwatchtime called %ld ms\n", tblock_ms); + evcurl_global_data *global = cglobal; + ev_timer_stop(EV_DEFAULT, &global->timeev); + if (tblock_ms < 0 || 14000 < tblock_ms) + tblock_ms = 14000; + ev_timer_set(&global->timeev, 0.5e-3 + 1.0e-3 * tblock_ms, 14.0); + ev_timer_start(EV_DEFAULT_UC, &global->timeev); + return 0; +} + +static int +gotwatchsock(CURL *easy, curl_socket_t fd, int action, void *cglobal, void *csockwatcher) { + evcurl_global_data *global = cglobal; + CURLM *mhnd = global->mhnd; + CtdlLogPrintf(CTDL_ERR,"gotwatchsock called fd=%d action=%d\n", (int)fd, action); + sockwatcher_data *sockwatcher = csockwatcher; + if (!sockwatcher) { + CtdlLogPrintf(CTDL_ERR,"called first time to register this sockwatcker\n"); + sockwatcher = malloc(sizeof(sockwatcher_data)); + sockwatcher->global = global; + ev_init(&sockwatcher->ioev, &gotio); + sockwatcher->ioev.data = (void *)sockwatcher; + curl_multi_assign(mhnd, fd, sockwatcher); + } + if (CURL_POLL_REMOVE == action) { + CtdlLogPrintf(CTDL_ERR,"called last time to unregister this sockwatcher\n"); + free(sockwatcher); + } else { + int events = (action & CURL_POLL_IN ? EV_READ : 0) | (action & CURL_POLL_OUT ? EV_WRITE : 0); + ev_io_stop(EV_DEFAULT, &sockwatcher->ioev); + if (events) { + ev_io_set(&sockwatcher->ioev, fd, events); + ev_io_start(EV_DEFAULT, &sockwatcher->ioev); + } + } + return 0; +} + +void curl_init_connectionpool(void) +{ + CURLM *mhnd ; +// global.magic = EVCURL_GLOBAL_MAGIC; + + ev_timer_init(&global.timeev, &gottime, 14.0, 14.0); + global.timeev.data = (void *)&global; + global.nrun = -1; + CURLcode sta = curl_global_init(CURL_GLOBAL_ALL); + /* note: probably replace with curl_global_init_mem if used with perl */ + if (sta) + { + CtdlLogPrintf(CTDL_ERR,"error initializing curl library: %s\n", curl_easy_strerror(sta)); + exit(1); + } +/* + if (!ev_default_loop(EVFLAG_AUTO)) + { + CtdlLogPrintf(CTDL_ERR,"error initializing libev\n"); + exit(2); + } +*/ + mhnd = global.mhnd = curl_multi_init(); + if (!mhnd) + { + CtdlLogPrintf(CTDL_ERR,"error initializing curl multi handle\n"); + exit(3); + } + + MOPT(SOCKETFUNCTION, &gotwatchsock); + MOPT(SOCKETDATA, (void *)&global); + MOPT(TIMERFUNCTION, &gotwatchtime); + MOPT(TIMERDATA, (void *)&global); + + /* well, just there to fire the sample request?*/ + ev_timer_start(EV_DEFAULT, &global.timeev); + return; +} + + + + +int evcurl_init(evcurl_request_data *handle, + void *CustomData, + const char* Desc, + int CallBack) +{ + CURLcode sta; + CURL *chnd; + + handle->global = &global; + handle->attached = 0; + chnd = handle->chnd = curl_easy_init(); + if (!chnd) + { + CtdlLogPrintf(CTDL_ERR, "error initializing curl handle\n"); + return 1; + } + + strcpy(handle->errdesc, Desc); + + OPT(VERBOSE, (long)1); + /* unset in production */ + OPT(NOPROGRESS, (long)1); + OPT(NOSIGNAL, (long)1); + OPT(FAILONERROR, (long)1); + OPT(ENCODING, ""); + OPT(FOLLOWLOCATION, (long)1); + OPT(MAXREDIRS, (long)7); + OPT(USERAGENT, CITADEL); + + OPT(TIMEOUT, (long)1800); + OPT(LOW_SPEED_LIMIT, (long)64); + OPT(LOW_SPEED_TIME, (long)600); + OPT(CONNECTTIMEOUT, (long)600); + OPT(PRIVATE, (void *)handle); + + + OPT(WRITEFUNCTION, &gotdata); + OPT(WRITEDATA, (void *)handle); + OPT(ERRORBUFFER, handle->errdesc); + + /* point to a structure that points back to the perl structure and stuff */ + OPT(URL, handle->URL->PlainUrl); + if (StrLength(handle->URL->CurlCreds)) + { + OPT(HTTPAUTH, (long)CURLAUTH_BASIC); + OPT(USERPWD, ChrPtr(handle->URL->CurlCreds)); + } +#ifdef CURLOPT_HTTP_CONTENT_DECODING + OPT(HTTP_CONTENT_DECODING, 1); + OPT(ENCODING, ""); +#endif + if (StrLength(handle->PostData) > 0) + { + OPT(POSTFIELDS, ChrPtr(handle->PostData)); + OPT(POSTFIELDSIZE, StrLength(handle->PostData)); + + } + else if ((handle->PlainPostDataLen != 0) && (handle->PlainPostData != NULL)) + { + OPT(POSTFIELDS, handle->PlainPostData); + OPT(POSTFIELDSIZE, handle->PlainPostDataLen); + } + + if (handle->headers != NULL) + OPT(HTTPHEADER, handle->headers); + + return 1; +} + +void +evcurl_handle_start(evcurl_request_data *handle) +{ + CURLMcode msta = curl_multi_add_handle(handle->global->mhnd, handle->chnd); + if (msta) + CtdlLogPrintf(CTDL_ERR, "error attaching to curl multi handle: %s\n", curl_multi_strerror(msta)); + handle->attached = 1; +} + + + +CTDL_MODULE_INIT(curl_client) +{ + if (!threading) + { + curl_init_connectionpool(); +/* + int r = ares_library_init(ARES_LIB_INIT_ALL); + if (0 != r) { + // TODO + // ThrowException(Exception::Error(String::New(ares_strerror(r)))); +//// assert(r == 0); + } +*/ } + return "curl"; +} diff --git a/citadel/modules/curl/serv_curl.h b/citadel/modules/curl/serv_curl.h new file mode 100644 index 000000000..295e32856 --- /dev/null +++ b/citadel/modules/curl/serv_curl.h @@ -0,0 +1,47 @@ +#include +#include + +typedef struct _evcurl_global_data { + int magic; + CURLM *mhnd; + ev_timer timeev; + int nrun; +} evcurl_global_data; + +typedef struct _evcurl_request_data +{ + evcurl_global_data *global; + CURL *chnd; + char errdesc[CURL_ERROR_SIZE]; + int attached; + char* PlainPostData; + long PlainPostDataLen; + StrBuf *PostData; + StrBuf *ReplyData; + ParsedURL *URL; + struct curl_slist * headers; +} evcurl_request_data; + +typedef struct _sockwatcher_data +{ + evcurl_global_data *global; + ev_io ioev; +} sockwatcher_data; + + + + +#define OPT(s, v) \ + do { \ + sta = curl_easy_setopt(chnd, (CURLOPT_##s), (v)); \ + if (sta) { \ + CtdlLogPrintf(CTDL_ERR, "error setting option " #s " on curl handle: %s", curl_easy_strerror(sta)); \ + } } while (0) + + +int evcurl_init(evcurl_request_data *handle, + void *CustomData, + const char* Desc, + int CallBack); + +void evcurl_handle_start(evcurl_request_data *handle); diff --git a/citadel/modules/extnotify/extnotify.h b/citadel/modules/extnotify/extnotify.h index c41291bce..645f458f4 100644 --- a/citadel/modules/extnotify/extnotify.h +++ b/citadel/modules/extnotify/extnotify.h @@ -18,9 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __cplusplus -extern "C" { -#endif +#include "../curl/serv_curl.h" #define FUNAMBOL_CONFIG_TEXT "funambol" #define PAGER_CONFIG_MESSAGE "__ Push email settings __" @@ -32,6 +30,7 @@ extern "C" { typedef struct _NotifyContext { StrBuf **NotifyHostList; HashList *NotifyErrors; + evcurl_request_data HTTPData; } NotifyContext; int notify_http_server(char *remoteurl, @@ -48,8 +47,5 @@ void extNotify_getPrefs(long configMsgNum, char *configMsg); long extNotify_getConfigMessage(char *username); void process_notify(long msgnum, void *usrdata); -#ifdef __cplusplus -} -#endif diff --git a/citadel/modules/extnotify/extnotify_main.c b/citadel/modules/extnotify/extnotify_main.c index 3e80ef4d7..31f2f0932 100644 --- a/citadel/modules/extnotify/extnotify_main.c +++ b/citadel/modules/extnotify/extnotify_main.c @@ -164,7 +164,7 @@ void do_extnotify_queue(void) NotifyContext Ctx; static int doing_queue = 0; - int i = 0; + //int i = 0; /* * This is a simple concurrency check to make sure only one queue run @@ -189,7 +189,7 @@ void do_extnotify_queue(void) } CtdlForEachMessage(MSGS_ALL, 0L, NULL, SPOOLMIME, NULL, process_notify, &Ctx); - +/* while ((Ctx.NotifyHostList != NULL) && (Ctx.NotifyHostList[i] != NULL)) FreeStrBuf(&Ctx.NotifyHostList[i]); @@ -212,7 +212,7 @@ void do_extnotify_queue(void) DeleteHashPos(&It); DeleteHash(&Ctx.NotifyErrors); } - +*/ CtdlLogPrintf(CTDL_DEBUG, "serv_extnotify: queue run completed\n"); doing_queue = 0; } diff --git a/citadel/modules/extnotify/funambol65.c b/citadel/modules/extnotify/funambol65.c index d3315b003..0e88c91ff 100644 --- a/citadel/modules/extnotify/funambol65.c +++ b/citadel/modules/extnotify/funambol65.c @@ -58,63 +58,14 @@ int notify_http_server(char *remoteurl, long MsgNum, NotifyContext *Ctx) { - char curl_errbuf[CURL_ERROR_SIZE]; - char *pchs, *pche; - char userpass[SIZ]; + CURLcode sta; char msgnumstr[128]; char *buf = NULL; - CURL *curl; - CURLcode res; - struct curl_slist * headers=NULL; - char errmsg[1024] = ""; char *SOAPMessage = NULL; char *contenttype = NULL; StrBuf *ReplyBuf; + CURL *chnd; - curl = curl_easy_init(); - if (!curl) { - CtdlLogPrintf(CTDL_ALERT, "Unable to initialize libcurl.\n"); - return 1; - } - - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); - ReplyBuf = NewStrBuf(); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, ReplyBuf); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlFillStrBuf_callback); - curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errmsg); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); - curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errbuf); - - pchs = strchr(remoteurl, ':'); - pche = strchr(remoteurl, '@'); - if ((pche != NULL) && - (pchs != NULL) && - (pchs < pche) && ((pche - pchs) < SIZ)) { - memcpy(userpass, pchs + 3, pche - pchs - 3); - - userpass[pche - pchs - 3] = '\0'; - curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_BASIC); - curl_easy_setopt(curl, CURLOPT_USERPWD, userpass); - - } -#ifdef CURLOPT_HTTP_CONTENT_DECODING - curl_easy_setopt(curl, CURLOPT_HTTP_CONTENT_DECODING, 1); - curl_easy_setopt(curl, CURLOPT_ENCODING, ""); -#endif - curl_easy_setopt(curl, CURLOPT_USERAGENT, CITADEL); - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 180); /* die after 180 seconds */ - if ( - (!IsEmptyStr(config.c_ip_addr)) - && (strcmp(config.c_ip_addr, "*")) - && (strcmp(config.c_ip_addr, "::")) - && (strcmp(config.c_ip_addr, "0.0.0.0")) - ) { - curl_easy_setopt(curl, CURLOPT_INTERFACE, config.c_ip_addr); - } - - headers = curl_slist_append(headers,"Accept: application/soap+xml, application/mime, multipart/related, text/*"); - headers = curl_slist_append(headers,"Pragma: no-cache"); if (tlen > 0) { /* Load the template message. Get mallocs done too */ @@ -131,7 +82,7 @@ int notify_http_server(char *remoteurl, CtdlLogPrintf(CTDL_ERR, buf); CtdlAideMessage(buf, "External notifier unable to find message template!"); - goto free; + goto abort; } mimetype = GuessMimeByFilename(template, tlen); @@ -156,7 +107,7 @@ int notify_http_server(char *remoteurl, CtdlLogPrintf(CTDL_ERR, buf); CtdlAideMessage(buf, "External notifier unable to load message template!"); - goto free; + goto abort; } // Do substitutions help_subst(SOAPMessage, "^notifyuser", user); @@ -164,62 +115,111 @@ int notify_http_server(char *remoteurl, help_subst(SOAPMessage, "^msgid", msgid); help_subst(SOAPMessage, "^msgnum", msgnumstr); - curl_easy_setopt(curl, CURLOPT_URL, remoteurl); - /* pass our list of custom made headers */ contenttype=(char*) malloc(40+strlen(mimetype)); sprintf(contenttype,"Content-Type: %s; charset=utf-8", mimetype); - headers = curl_slist_append(headers, "SOAPAction: \"\""); - headers = curl_slist_append(headers, contenttype); + Ctx->HTTPData.headers = curl_slist_append(Ctx->HTTPData.headers, "SOAPAction: \"\""); + Ctx->HTTPData.headers = curl_slist_append(Ctx->HTTPData.headers, contenttype); + Ctx->HTTPData.headers = curl_slist_append(Ctx->HTTPData.headers, "Accept: application/soap+xml, application/mime, multipart/related, text/*"); + Ctx->HTTPData.headers = curl_slist_append(Ctx->HTTPData.headers, "Pragma: no-cache"); /* Now specify the POST binary data */ - - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, SOAPMessage); - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(SOAPMessage)); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + Ctx->HTTPData.PlainPostData = SOAPMessage; + Ctx->HTTPData.PlainPostDataLen = strlen(SOAPMessage); } else { help_subst(remoteurl, "^notifyuser", user); help_subst(remoteurl, "^syncsource", config.c_funambol_source); help_subst(remoteurl, "^msgid", msgid); help_subst(remoteurl, "^msgnum", msgnumstr); - curl_easy_setopt(curl, CURLOPT_URL, remoteurl); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + Ctx->HTTPData.headers = curl_slist_append(Ctx->HTTPData.headers, "Accept: application/soap+xml, application/mime, multipart/related, text/*"); + Ctx->HTTPData.headers = curl_slist_append(Ctx->HTTPData.headers, "Pragma: no-cache"); } - res = curl_easy_perform(curl); + ParseURL(&Ctx->HTTPData.URL, NewStrBufPlain (remoteurl, -1), 80); + CurlPrepareURL(Ctx->HTTPData.URL); + int CallBack; + if (! evcurl_init(&Ctx->HTTPData, + Ctx, + "Citadel ExtNotify", + CallBack)) + { + CtdlLogPrintf(CTDL_ALERT, "Unable to initialize libcurl.\n"); + goto abort; + } + chnd = Ctx->HTTPData.chnd; + OPT(SSL_VERIFYPEER, 0); + OPT(SSL_VERIFYHOST, 0); +/* + ReplyBuf = NewStrBuf(); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, ReplyBuf); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlFillStrBuf_callback); +*/ + if ( + (!IsEmptyStr(config.c_ip_addr)) + && (strcmp(config.c_ip_addr, "*")) + && (strcmp(config.c_ip_addr, "::")) + && (strcmp(config.c_ip_addr, "0.0.0.0")) + ) { + OPT(INTERFACE, config.c_ip_addr); + } + + evcurl_handle_start(&Ctx->HTTPData); + + return 0; +abort: +/// curl_slist_free_all (headers); +/// curl_easy_cleanup(curl); + if (contenttype) free(contenttype); + if (SOAPMessage != NULL) free(SOAPMessage); + if (buf != NULL) free(buf); + FreeStrBuf (&ReplyBuf); + return 1; +} + + + +int EvaluateResult(NotifyContext *Ctx, int res, int b) +{ if (res) { StrBuf *ErrMsg; - CtdlLogPrintf(CTDL_ALERT, "libcurl error %d: %s\n", res, errmsg); + CtdlLogPrintf(CTDL_ALERT, "libcurl error %d: %s\n", + res, + Ctx->HTTPData.errdesc); ErrMsg = NewStrBufPlain(HKEY("Error sending your Notification\n")); - StrBufAppendPrintf(ErrMsg, "\nlibcurl error %d: %s\n", res, errmsg); - StrBufAppendBufPlain(ErrMsg, curl_errbuf, -1, 0); + StrBufAppendPrintf(ErrMsg, "\nlibcurl error %d: %s\n", + res, + Ctx->HTTPData.errdesc); +/// StrBufAppendBufPlain(ErrMsg, curl_errbuf, -1, 0); StrBufAppendBufPlain(ErrMsg, HKEY("\nWas Trying to send: \n"), 0); - StrBufAppendBufPlain(ErrMsg, remoteurl, -1, 0); - if (tlen > 0) { + StrBufAppendBufPlain(ErrMsg, Ctx->HTTPData.URL->PlainUrl, -1, 0); + if (Ctx->HTTPData.PlainPostDataLen > 0) { StrBufAppendBufPlain(ErrMsg, HKEY("\nThe Post document was: \n"), 0); - StrBufAppendBufPlain(ErrMsg, SOAPMessage, -1, 0); + StrBufAppendBufPlain(ErrMsg, + Ctx->HTTPData.PlainPostData, + Ctx->HTTPData.PlainPostDataLen, 0); StrBufAppendBufPlain(ErrMsg, HKEY("\n\n"), 0); } - if (StrLength(ReplyBuf) > 0) { + if (StrLength(Ctx->HTTPData.ReplyData) > 0) { StrBufAppendBufPlain(ErrMsg, HKEY("\n\nThe Serverreply was: \n\n"), 0); - StrBufAppendBuf(ErrMsg, ReplyBuf, 0); + StrBufAppendBuf(ErrMsg, Ctx->HTTPData.ReplyData, 0); } else StrBufAppendBufPlain(ErrMsg, HKEY("\n\nThere was no Serverreply.\n\n"), 0); - ExtNotify_PutErrorMessage(Ctx, ErrMsg); + ///ExtNotify_PutErrorMessage(Ctx, ErrMsg); + CtdlAideMessage(ChrPtr(ErrMsg), "External notifier unable to load message template!"); } CtdlLogPrintf(CTDL_DEBUG, "Funambol notified\n"); -free: - curl_slist_free_all (headers); - curl_easy_cleanup(curl); - if (contenttype) free(contenttype); - if (SOAPMessage != NULL) free(SOAPMessage); - if (buf != NULL) free(buf); - FreeStrBuf (&ReplyBuf); + +//// curl_slist_free_all (headers); +/// curl_easy_cleanup(curl); + ///if (contenttype) free(contenttype); + ///if (SOAPMessage != NULL) free(SOAPMessage); + ///if (buf != NULL) free(buf); + ///FreeStrBuf (&ReplyBuf); return 0; } -- 2.30.2