finish rewriting of http client code
authorWilfried Goesgens <dothebart@citadel.org>
Mon, 30 May 2011 21:52:00 +0000 (21:52 +0000)
committerWilfried Goesgens <dothebart@citadel.org>
Mon, 30 May 2011 21:52:00 +0000 (21:52 +0000)
 - we now have a context
 - we now handle replies
 - still some uncertain cleanup condition.

citadel/event_client.h
citadel/modules/eventclient/serv_eventclient.c
citadel/modules/extnotify/extnotify_main.c
citadel/modules/extnotify/funambol65.c

index 8647fdde43720722de033bd6356932eaac566dc8..49d1159783ba1a50380e9485a932d27adb012dea 100644 (file)
@@ -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);
index 5de654fd4656b0056a23b9c49749cb2951bab446..873d1662852a664401a557b1607d05c957493e2c 100644 (file)
@@ -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)
        {
index db1967eba78e5dd4651f3df46375c7a8ebed8ab5..b26284af51f8221b99722509004135c36f5b88c9 100644 (file)
@@ -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
index 628eaf82add590eaa13324e1023ae7efb39c8769..6049b179d2fbd8877286a476551a4a209eb094da 100644 (file)
@@ -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);