3 * @author Mathew McBride
5 * This module facilitates notifications to a Funambol server
8 * Based on bits of the previous serv_funambol
9 * Contact: <matt@mcbridematt.dhs.org> / <matt@comalies>
15 #include <sys/socket.h>
17 #include <libcitadel.h>
20 #include <curl/curl.h>
23 #include "citadel_dirs.h"
24 #include "clientsocket.h"
27 #include "sysdep_decls.h"
29 #include "ctdl_module.h"
31 #include "extnotify.h"
34 * \brief Sends a message to the Funambol server notifying
35 * of new mail for a user
36 * Returns 0 if unsuccessful
38 int notify_http_server(char *remoteurl,
39 const char* template, long tlen,
45 char curl_errbuf[CURL_ERROR_SIZE];
52 struct curl_slist * headers=NULL;
53 char errmsg[1024] = "";
54 char *SOAPMessage = NULL;
55 char *contenttype = NULL;
58 curl = curl_easy_init();
60 CtdlLogPrintf(CTDL_ALERT, "Unable to initialize libcurl.\n");
64 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
65 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
66 ReplyBuf = NewStrBuf();
67 curl_easy_setopt(curl, CURLOPT_WRITEDATA, ReplyBuf);
68 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlFillStrBuf_callback);
69 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errmsg);
70 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
71 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errbuf);
73 pchs = strchr(remoteurl, ':');
74 pche = strchr(remoteurl, '@');
77 (pchs < pche) && ((pche - pchs) < SIZ)) {
78 memcpy(userpass, pchs + 3, pche - pchs - 3);
80 userpass[pche - pchs - 3] = '\0';
81 curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_BASIC);
82 curl_easy_setopt(curl, CURLOPT_USERPWD, userpass);
85 #ifdef CURLOPT_HTTP_CONTENT_DECODING
86 curl_easy_setopt(curl, CURLOPT_HTTP_CONTENT_DECODING, 1);
87 curl_easy_setopt(curl, CURLOPT_ENCODING, "");
89 curl_easy_setopt(curl, CURLOPT_USERAGENT, CITADEL);
90 curl_easy_setopt(curl, CURLOPT_TIMEOUT, 180); /* die after 180 seconds */
91 if (!IsEmptyStr(config.c_ip_addr)) {
92 curl_easy_setopt(curl, CURLOPT_INTERFACE, config.c_ip_addr);
95 headers = curl_slist_append(headers,"Accept: application/soap+xml, application/mime, multipart/related, text/*");
96 headers = curl_slist_append(headers,"Pragma: no-cache");
99 /* Load the template message. Get mallocs done too */
100 FILE *Ftemplate = NULL;
101 const char *mimetype;
103 Ftemplate = fopen(template, "r");
104 if (Ftemplate == NULL) {
108 "Cannot load template file %s [%s]won't send notification\r\n",
109 file_funambol_msg, strerror(errno));
110 CtdlLogPrintf(CTDL_ERR, buf);
112 aide_message(buf, "External notifier unable to find message template!");
115 mimetype = GuessMimeByFilename(template, tlen);
117 snprintf(msgnumstr, 128, "%ld", MsgNum);
121 SOAPMessage = malloc(3072);
122 memset(SOAPMessage, 0, 3072);
124 while(fgets(buf, SIZ, Ftemplate) != NULL) {
125 strcat(SOAPMessage, buf);
129 if (strlen(SOAPMessage) < 0) {
133 "Cannot load template file %s; won't send notification\r\n",
135 CtdlLogPrintf(CTDL_ERR, buf);
137 aide_message(buf, "External notifier unable to load message template!");
141 help_subst(SOAPMessage, "^notifyuser", user);
142 help_subst(SOAPMessage, "^syncsource", config.c_funambol_source);
143 help_subst(SOAPMessage, "^msgid", msgid);
144 help_subst(SOAPMessage, "^msgnum", msgnumstr);
146 curl_easy_setopt(curl, CURLOPT_URL, remoteurl);
148 /* pass our list of custom made headers */
150 contenttype=(char*) malloc(40+strlen(mimetype));
151 sprintf(contenttype,"Content-Type: %s; charset=utf-8", mimetype);
153 headers = curl_slist_append(headers, "SOAPAction: \"\"");
154 headers = curl_slist_append(headers, contenttype);
156 /* Now specify the POST binary data */
158 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, SOAPMessage);
159 curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(SOAPMessage));
160 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
163 help_subst(remoteurl, "^notifyuser", user);
164 help_subst(remoteurl, "^syncsource", config.c_funambol_source);
165 help_subst(remoteurl, "^msgid", msgid);
166 help_subst(remoteurl, "^msgnum", msgnumstr);
167 curl_easy_setopt(curl, CURLOPT_URL, remoteurl);
168 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
171 res = curl_easy_perform(curl);
175 CtdlLogPrintf(CTDL_ALERT, "libcurl error %d: %s\n", res, errmsg);
176 ErrMsg = NewStrBufPlain(HKEY("Error sending your Notification\n"));
177 StrBufAppendPrintf(ErrMsg, "\nlibcurl error %d: %s\n", res, errmsg);
178 StrBufAppendBufPlain(ErrMsg, curl_errbuf, -1, 0);
179 StrBufAppendBufPlain(ErrMsg, HKEY("\nWas Trying to send: \n"), 0);
180 StrBufAppendBufPlain(ErrMsg, remoteurl, -1, 0);
182 StrBufAppendBufPlain(ErrMsg, HKEY("\nThe Post document was: \n"), 0);
183 StrBufAppendBufPlain(ErrMsg, SOAPMessage, -1, 0);
184 StrBufAppendBufPlain(ErrMsg, HKEY("\n\n"), 0);
186 if (StrLength(ReplyBuf) > 0) {
187 StrBufAppendBufPlain(ErrMsg, HKEY("\n\nThe Serverreply was: \n\n"), 0);
188 StrBufAppendBuf(ErrMsg, ReplyBuf, 0);
191 StrBufAppendBufPlain(ErrMsg, HKEY("\n\nThere was no Serverreply.\n\n"), 0);
192 ExtNotify_PutErrorMessage(Ctx, ErrMsg);
195 CtdlLogPrintf(CTDL_DEBUG, "Funambol notified\n");
197 curl_slist_free_all (headers);
198 curl_easy_cleanup(curl);
199 if (contenttype) free(contenttype);
200 if (SOAPMessage != NULL) free(SOAPMessage);
201 if (buf != NULL) free(buf);
202 FreeStrBuf (&ReplyBuf);