From c67fb1c41bfc35b3449e4c52cf903fdba3cdb776 Mon Sep 17 00:00:00 2001 From: Wilfried Goesgens Date: Mon, 30 May 2011 21:52:00 +0000 Subject: [PATCH] finish rewriting of http client code - we now have a context - we now handle replies - still some uncertain cleanup condition. --- citadel/event_client.h | 23 +++--- .../modules/eventclient/serv_eventclient.c | 48 +++++++++---- citadel/modules/extnotify/extnotify_main.c | 20 ++++-- citadel/modules/extnotify/funambol65.c | 70 ++++++++++--------- 4 files changed, 101 insertions(+), 60 deletions(-) diff --git a/citadel/event_client.h b/citadel/event_client.h index 8647fdde4..49d115978 100644 --- a/citadel/event_client.h +++ b/citadel/event_client.h @@ -36,15 +36,18 @@ typedef struct _DNSQueryParts { typedef struct _evcurl_request_data { - CURL *chnd; - char errdesc[CURL_ERROR_SIZE]; - int attached; - char* PlainPostData; - long PlainPostDataLen; - StrBuf *PostData; - StrBuf *ReplyData; -/// ParsedURL *URL; /// take from AsyncIO->ConnectMe - struct curl_slist * headers; + CURL *chnd; + struct curl_slist *headers; + char errdesc[CURL_ERROR_SIZE]; + + int attached; + + char *PlainPostData; + long PlainPostDataLen; + StrBuf *PostData; + + StrBuf *ReplyData; + long httpcode; } evcurl_request_data; struct AsyncIO { @@ -136,6 +139,6 @@ void InitC_ares_dns(AsyncIO *IO); int evcurl_init(AsyncIO *IO, void *CustomData, const char* Desc, - int CallBack); + IO_CallBack CallBack); void evcurl_handle_start(AsyncIO *IO); diff --git a/citadel/modules/eventclient/serv_eventclient.c b/citadel/modules/eventclient/serv_eventclient.c index 5de654fd4..873d16628 100644 --- a/citadel/modules/eventclient/serv_eventclient.c +++ b/citadel/modules/eventclient/serv_eventclient.c @@ -127,28 +127,35 @@ gotstatus(evcurl_global_data *global, int nnrun) while ((msg = curl_multi_info_read(mhnd, &nmsg))) { CtdlLogPrintf(CTDL_ERR, "EVCURL: got curl multi_info message msg=%d\n", msg->msg); if (CURLMSG_DONE == msg->msg) { + CURL *chnd; + char *chandle; + CURLcode sta; + CURLMcode msta; + AsyncIO *IO; + + chandle = NULL;; + chnd = msg->easy_handle; + sta = curl_easy_getinfo(chnd, CURLINFO_PRIVATE, &chandle); CtdlLogPrintf(CTDL_ERR, "EVCURL: request complete\n"); - CURL *chnd = msg->easy_handle; - char *chandle = NULL;; - CURLcode sta = curl_easy_getinfo(chnd, CURLINFO_PRIVATE, &chandle); if (sta) CtdlLogPrintf(CTDL_ERR, "EVCURL: error asking curl for private cookie of curl handle: %s\n", curl_easy_strerror(sta)); - evcurl_request_data *handle = (void *)chandle; + IO = (AsyncIO *)chandle; sta = msg->data.result; if (sta) { - CtdlLogPrintf(CTDL_ERR, "EVCURL: error description: %s\n", handle->errdesc); + CtdlLogPrintf(CTDL_ERR, "EVCURL: error description: %s\n", IO->HttpReq.errdesc); CtdlLogPrintf(CTDL_ERR, "EVCURL: error performing request: %s\n", curl_easy_strerror(sta)); } - long httpcode; - sta = curl_easy_getinfo(chnd, CURLINFO_RESPONSE_CODE, &httpcode); + sta = curl_easy_getinfo(chnd, CURLINFO_RESPONSE_CODE, &IO->HttpReq.httpcode); if (sta) CtdlLogPrintf(CTDL_ERR, "EVCURL: error asking curl for response code from request: %s\n", curl_easy_strerror(sta)); - CtdlLogPrintf(CTDL_ERR, "EVCURL: http response code was %ld\n", (long)httpcode); - CURLMcode msta = curl_multi_remove_handle(mhnd, chnd); + CtdlLogPrintf(CTDL_ERR, "EVCURL: http response code was %ld\n", (long)IO->HttpReq.httpcode); + msta = curl_multi_remove_handle(mhnd, chnd); if (msta) CtdlLogPrintf(CTDL_ERR, "EVCURL: warning problem detaching completed handle from curl multi: %s\n", curl_multi_strerror(msta)); - handle->attached = 0; + IO->HttpReq.attached = 0; + IO->SendDone(IO); + curl_multi_cleanup(msta); } } } @@ -156,7 +163,13 @@ gotstatus(evcurl_global_data *global, int nnrun) static void stepmulti(evcurl_global_data *global, curl_socket_t fd) { int nnrun; - CURLMcode msta = curl_multi_socket_action(global->mhnd, fd, 0, &nnrun); + CURLMcode msta; + + if (global == NULL) { + CtdlLogPrintf(CTDL_DEBUG, "EVCURL: stepmulti(NULL): wtf?\n"); + return; + } + msta = curl_multi_socket_action(global->mhnd, fd, 0, &nnrun); CtdlLogPrintf(CTDL_DEBUG, "EVCURL: stepmulti(): calling gotstatus()\n"); if (msta) CtdlLogPrintf(CTDL_ERR, "EVCURL: error in curl processing events on multi handle, fd %d: %s\n", (int)fd, curl_multi_strerror(msta)); @@ -180,9 +193,15 @@ gotio(struct ev_loop *loop, ev_io *ioev, int events) { static size_t gotdata(void *data, size_t size, size_t nmemb, void *cglobal) { - evcurl_request_data *D = (evcurl_request_data*) data; + AsyncIO *IO = (AsyncIO*) cglobal; + //evcurl_request_data *D = (evcurl_request_data*) data; CtdlLogPrintf(CTDL_DEBUG, "EVCURL: gotdata(): calling CurlFillStrBuf_callback()\n"); - return CurlFillStrBuf_callback(D->ReplyData, size, nmemb, cglobal); + + if (IO->HttpReq.ReplyData == NULL) + { + IO->HttpReq.ReplyData = NewStrBufPlain(NULL, SIZ); + } + return CurlFillStrBuf_callback(data, size, nmemb, IO->HttpReq.ReplyData); } static int @@ -273,13 +292,14 @@ void curl_init_connectionpool(void) int evcurl_init(AsyncIO *IO, void *CustomData, const char* Desc, - int CallBack) + IO_CallBack CallBack) { CURLcode sta; CURL *chnd; CtdlLogPrintf(CTDL_DEBUG,"EVCURL: evcurl_init called ms\n"); IO->HttpReq.attached = 0; + IO->SendDone = CallBack; chnd = IO->HttpReq.chnd = curl_easy_init(); if (!chnd) { diff --git a/citadel/modules/extnotify/extnotify_main.c b/citadel/modules/extnotify/extnotify_main.c index db1967eba..b26284af5 100644 --- a/citadel/modules/extnotify/extnotify_main.c +++ b/citadel/modules/extnotify/extnotify_main.c @@ -68,7 +68,7 @@ #include "ctdl_module.h" - +struct CitContext extnotify_queue_CC; void ExtNotify_PutErrorMessage(NotifyContext *Ctx, StrBuf *ErrMsg) { @@ -261,6 +261,7 @@ void process_notify(long NotifyMsgnum, void *usrdata) char remoteurl[SIZ]; char *FreeMe = NULL; char *PagerNo; + CitContext *SubC; Ctx = (NotifyContext*) usrdata; @@ -281,13 +282,17 @@ void process_notify(long NotifyMsgnum, void *usrdata) config.c_funambol_host, config.c_funambol_port, FUNAMBOL_WS); + + SubC = CloneContext (CC); + SubC->session_specific_data = NULL;// (char*) DupNotifyContext(Ctx); + notify_http_server(remoteurl, file_funambol_msg, strlen(file_funambol_msg),/*GNA*/ msg->cm_fields['W'], msg->cm_fields['I'], msgnum, - Ctx); + NULL); break; case eHttpMessages: { @@ -313,13 +318,15 @@ void process_notify(long NotifyMsgnum, void *usrdata) FlushStrBuf(FileBuf); memcpy(URLBuf, ChrPtr(URL), StrLength(URL) + 1); + SubC = CloneContext (CC); + SubC->session_specific_data = NULL;// (char*) DupNotifyContext(Ctx); notify_http_server(URLBuf, ChrPtr(FileBuf), StrLength(FileBuf), msg->cm_fields['W'], msg->cm_fields['I'], msgnum, - Ctx); + NULL); i++; } FreeStrBuf(&FileBuf); @@ -358,6 +365,7 @@ void process_notify(long NotifyMsgnum, void *usrdata) */ void do_extnotify_queue(void) { + CitContext *CCC = CC; NotifyContext Ctx; static int doing_queue = 0; @@ -380,11 +388,13 @@ void do_extnotify_queue(void) if (doing_queue) return; doing_queue = 1; + citthread_setspecific(MyConKey, (void *)&extnotify_queue_CC); + /* * Go ahead and run the queue */ CtdlLogPrintf(CTDL_DEBUG, "serv_extnotify: processing notify queue\n"); - + memset(&Ctx, 0, sizeof(NotifyContext)); Ctx.NotifyHostList = GetNotifyHosts(); if (CtdlGetRoom(&CC->room, FNBL_QUEUE_ROOM) != 0) { @@ -410,6 +420,8 @@ void create_extnotify_queue(void) { struct ctdlroom qrbuf; CtdlCreateRoom(FNBL_QUEUE_ROOM, 3, "", 0, 1, 0, VIEW_MAILBOX); + + CtdlFillSystemContext(&extnotify_queue_CC, "Extnotify"); /* * Make sure it's set to be a "system room" so it doesn't show up diff --git a/citadel/modules/extnotify/funambol65.c b/citadel/modules/extnotify/funambol65.c index 628eaf82a..6049b179d 100644 --- a/citadel/modules/extnotify/funambol65.c +++ b/citadel/modules/extnotify/funambol65.c @@ -47,6 +47,8 @@ #include "event_client.h" #include "extnotify.h" +eNextState EvaluateResult(AsyncIO *IO); + /* * \brief Sends a message to the Funambol server notifying * of new mail for a user @@ -66,6 +68,11 @@ int notify_http_server(char *remoteurl, char *contenttype = NULL; StrBuf *ReplyBuf; CURL *chnd; + AsyncIO *IO; + + IO = (AsyncIO*) malloc(sizeof(AsyncIO)); + memset(IO, 0, sizeof(AsyncIO)); + IO->CitContext = CC; snprintf(msgnumstr, 128, "%ld", MsgNum); @@ -120,36 +127,36 @@ int notify_http_server(char *remoteurl, contenttype=(char*) malloc(40+strlen(mimetype)); sprintf(contenttype,"Content-Type: %s; charset=utf-8", mimetype); - Ctx->IO.HttpReq.headers = curl_slist_append(Ctx->IO.HttpReq.headers, "SOAPAction: \"\""); - Ctx->IO.HttpReq.headers = curl_slist_append(Ctx->IO.HttpReq.headers, contenttype); - Ctx->IO.HttpReq.headers = curl_slist_append(Ctx->IO.HttpReq.headers, "Accept: application/soap+xml, application/mime, multipart/related, text/*"); - Ctx->IO.HttpReq.headers = curl_slist_append(Ctx->IO.HttpReq.headers, "Pragma: no-cache"); + IO->HttpReq.headers = curl_slist_append(IO->HttpReq.headers, "SOAPAction: \"\""); + IO->HttpReq.headers = curl_slist_append(IO->HttpReq.headers, contenttype); + IO->HttpReq.headers = curl_slist_append(IO->HttpReq.headers, "Accept: application/soap+xml, application/mime, multipart/related, text/*"); + IO->HttpReq.headers = curl_slist_append(IO->HttpReq.headers, "Pragma: no-cache"); /* Now specify the POST binary data */ - Ctx->IO.HttpReq.PlainPostData = SOAPMessage; - Ctx->IO.HttpReq.PlainPostDataLen = strlen(SOAPMessage); + IO->HttpReq.PlainPostData = SOAPMessage; + IO->HttpReq.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); - Ctx->IO.HttpReq.headers = curl_slist_append(Ctx->IO.HttpReq.headers, "Accept: application/soap+xml, application/mime, multipart/related, text/*"); - Ctx->IO.HttpReq.headers = curl_slist_append(Ctx->IO.HttpReq.headers, "Pragma: no-cache"); + IO->HttpReq.headers = curl_slist_append(IO->HttpReq.headers, "Accept: application/soap+xml, application/mime, multipart/related, text/*"); + IO->HttpReq.headers = curl_slist_append(IO->HttpReq.headers, "Pragma: no-cache"); } - ParseURL(&Ctx->IO.ConnectMe, NewStrBufPlain (remoteurl, -1), 80); - CurlPrepareURL(Ctx->IO.ConnectMe); - int CallBack; - if (! evcurl_init(&Ctx->IO, - Ctx, + ParseURL(&IO->ConnectMe, NewStrBufPlain (remoteurl, -1), 80); + CurlPrepareURL(IO->ConnectMe); + if (! evcurl_init(IO, +// Ctx, + NULL, "Citadel ExtNotify", - CallBack)) + EvaluateResult)) { CtdlLogPrintf(CTDL_ALERT, "Unable to initialize libcurl.\n"); goto abort; } - chnd = Ctx->IO.HttpReq.chnd; + chnd = IO->HttpReq.chnd; OPT(SSL_VERIFYPEER, 0); OPT(SSL_VERIFYHOST, 0); /* @@ -166,7 +173,7 @@ int notify_http_server(char *remoteurl, OPT(INTERFACE, config.c_ip_addr); } - evcurl_handle_start(&Ctx->IO); + evcurl_handle_start(IO); return 0; abort: @@ -180,32 +187,31 @@ abort: } - -int EvaluateResult(NotifyContext *Ctx, int res, int b) +eNextState EvaluateResult(AsyncIO *IO) { - if (res) { + + if (IO->HttpReq.httpcode != 200) { StrBuf *ErrMsg; - CtdlLogPrintf(CTDL_ALERT, "libcurl error %d: %s\n", - res, - Ctx->IO.HttpReq.errdesc); + CtdlLogPrintf(CTDL_ALERT, "libcurl error %ld: %s\n", + IO->HttpReq.httpcode, + IO->HttpReq.errdesc); ErrMsg = NewStrBufPlain(HKEY("Error sending your Notification\n")); - StrBufAppendPrintf(ErrMsg, "\nlibcurl error %d: %s\n", - res, - Ctx->IO.HttpReq.errdesc); -/// StrBufAppendBufPlain(ErrMsg, curl_errbuf, -1, 0); + StrBufAppendPrintf(ErrMsg, "\nlibcurl error %ld: \n\t\t%s\n", + IO->HttpReq.httpcode, + IO->HttpReq.errdesc); StrBufAppendBufPlain(ErrMsg, HKEY("\nWas Trying to send: \n"), 0); - StrBufAppendBufPlain(ErrMsg, Ctx->IO.ConnectMe->PlainUrl, -1, 0); - if (Ctx->IO.HttpReq.PlainPostDataLen > 0) { + StrBufAppendBufPlain(ErrMsg, IO->ConnectMe->PlainUrl, -1, 0); + if (IO->HttpReq.PlainPostDataLen > 0) { StrBufAppendBufPlain(ErrMsg, HKEY("\nThe Post document was: \n"), 0); StrBufAppendBufPlain(ErrMsg, - Ctx->IO.HttpReq.PlainPostData, - Ctx->IO.HttpReq.PlainPostDataLen, 0); + IO->HttpReq.PlainPostData, + IO->HttpReq.PlainPostDataLen, 0); StrBufAppendBufPlain(ErrMsg, HKEY("\n\n"), 0); } - if (StrLength(Ctx->IO.HttpReq.ReplyData) > 0) { + if (StrLength(IO->HttpReq.ReplyData) > 0) { StrBufAppendBufPlain(ErrMsg, HKEY("\n\nThe Serverreply was: \n\n"), 0); - StrBufAppendBuf(ErrMsg, Ctx->IO.HttpReq.ReplyData, 0); + StrBufAppendBuf(ErrMsg, IO->HttpReq.ReplyData, 0); } else StrBufAppendBufPlain(ErrMsg, HKEY("\n\nThere was no Serverreply.\n\n"), 0); -- 2.30.2