[PATCH] curl

Paul P Komkoff Jr <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Organization Department of Fish & Wildlife
Message-ID <[email protected]>
attached
-- 
Paul P 'Stingray' Komkoff Jr // http://stingr.net/key <- my pgp key
 This message represents the official view of the voices in my head
curl (text/plain, 11.5 KB)
Index: gateway.A9/acinclude.m4
===================================================================
--- gateway.A9.orig/acinclude.m4	2004-11-06 17:36:47.473315824 +0300
+++ gateway.A9/acinclude.m4	2004-11-06 17:36:55.727061064 +0300
@@ -159,3 +159,42 @@
 fi
 ])
 
+dnl MY_CURL
+dnl -------
+dnl set my_cv_curl_vers to the version of libcurl or NONE
+dnl if libcurl is not found or is too old
+
+AC_DEFUN(MY_CURL,[
+ AC_CACHE_VAL(my_cv_curl_vers,[
+ my_cv_curl_vers=NONE
+ dnl check is the plain-text version of the required version
+ check="7.9.7"
+ dnl check_hex must be UPPERCASE if any hex letters are present
+ check_hex="070907"
+
+ AC_MSG_CHECKING([for curl >= $check])
+ if test x$CURL_PREFIX != x ; then
+   curl_config=$CURL_PREFIX/bin/curl-config
+ else
+   curl_config=curl-config
+ fi
+
+ if eval $curl_config --version 2>/dev/null >/dev/null; then
+   ver=`$curl_config --version | sed -e "s/libcurl //g"`
+   hex_ver=`$curl_config --vernum | tr 'a-f' 'A-F'`
+   ok=`echo "ibase=16; if($hex_ver>=$check_hex) $hex_ver else 0" | bc`
+
+   if test x$ok != x0; then
+     my_cv_curl_vers="$ver"
+     AC_MSG_RESULT([$my_cv_curl_vers])
+   else
+     AC_MSG_RESULT(FAILED)
+     AC_MSG_WARN([$ver is too old. Need version $check or higher.])
+   fi
+ else
+   AC_MSG_RESULT(FAILED)
+   AC_MSG_WARN([curl-config was not found])
+ fi
+ ])
+])
+
Index: gateway.A9/configure.in
===================================================================
--- gateway.A9.orig/configure.in	2004-11-06 17:36:47.493312784 +0300
+++ gateway.A9/configure.in	2004-11-06 17:36:55.728060912 +0300
@@ -182,6 +182,40 @@
     AC_MSG_ERROR([Couldnot find gethostbyname_r nor gethostbyname functions])])]
 )
 
+dnl curl support
+
+CURL_PREFIX=""
+
+AC_ARG_WITH(curl,
+[  --with-curl=DIR           curl base installation path], [
+  if test "x$withval" != "x" ; then
+        CURL_PREFIX=$withval
+  fi
+])
+
+
+AC_MSG_CHECKING([whether to compile with CURL support])
+AC_ARG_ENABLE(curl,
+[  --enable-curl                enable curl for wapbox's http (TRY THIS!!!)],
+[
+  if test "$enableval" != yes; then
+    AC_MSG_RESULT(disabled)
+  else
+    AC_MSG_RESULT(searching)
+    MY_CURL
+    if test "$my_cv_curl_vers" != NONE; then
+      LIBS="$LIBS $($curl_config --libs)"
+      CFLAGS="$CFLAGS $($curl_config --cflags)"
+      CFLAGS="$CFLAGS -DCURL_SUPPORT=1"
+    else
+      AC_MSG_ERROR([Cannot find suitable libcurl])
+    fi
+  fi
+],[
+  AC_MSG_RESULT(disabled)
+]
+)
+
 dnl Extra feature checks
 
 dnl GW_HAVE_TYPE_FROM(HDRNAME, TYPE, HAVENAME, DESCRIPTION)
Index: gateway.A9/gw/wap-appl.c
===================================================================
--- gateway.A9.orig/gw/wap-appl.c	2004-08-29 11:15:03.000000000 +0400
+++ gateway.A9/gw/wap-appl.c	2004-11-06 17:41:37.645202992 +0300
@@ -98,6 +98,10 @@
 #include "wap-error.h"
 #include "wap-maps.h"
 
+#ifdef CURL_SUPPORT
+#include <curl/curl.h>
+#endif
+
 #define ENABLE_NOT_ACCEPTED 
 
 /*
@@ -158,6 +162,204 @@
     List *request_headers;
 };
 
+#ifdef CURL_SUPPORT
+static Mutex * curl_proxy_mutex = NULL; /* Mutex protecting change of proxy url */
+Octstr* curl_proxy_str = NULL;
+
+void curl_init() {
+    curl_global_init(CURL_GLOBAL_ALL);
+    curl_proxy_mutex = mutex_create();
+}
+
+void curl_cleanup() {
+    curl_global_cleanup();
+    mutex_destroy(curl_proxy_mutex);
+    curl_proxy_mutex = NULL;
+}
+
+void curl_use_proxy(Octstr *hostname, int port, List *exceptions,
+                    Octstr *username, Octstr *password)
+{
+    Octstr * new_proxy_str = NULL;
+
+    new_proxy_str = octstr_format("http://%S:%d", hostname, port);
+    mutex_lock(curl_proxy_mutex);
+    if (curl_proxy_str)
+        octstr_destroy(curl_proxy_str);
+    curl_proxy_str = new_proxy_str;
+    mutex_unlock(curl_proxy_mutex);
+}
+
+static CURLM* CurlMClient = NULL;
+static int pipeh[2] = { 0 };
+
+struct curl_http_request {
+    Octstr * body;
+    void * id;
+
+    Octstr* reply;
+    List* headers;
+
+    struct curl_slist * request_headers;
+    Octstr * url;
+    Octstr * proxy;
+};
+
+static size_t curl_writefunc(void *ptr, size_t size, size_t nmemb, void *stream) {
+    Octstr * s = stream;
+    int realsize = size * nmemb;
+
+    if (s == NULL) return realsize;
+    octstr_append_data(s, ptr, realsize);
+    return realsize;
+}
+
+static size_t curl_headfunc(void *ptr, size_t size, size_t nmemb, void *stream) {
+    List * l = stream;
+    int realsize = size * nmemb;
+    Octstr * s;
+
+    if (l == NULL) return realsize;
+    s = octstr_create_from_data(ptr, realsize);
+    octstr_strip_crlfs(s);
+    if ((octstr_len(s) == 0)  || (octstr_search_char(s, ':', 0) == -1)) {
+      octstr_destroy(s);
+    } else {
+      if (strncasecmp("Content-Encoding:", octstr_get_cstr(s), 17) == 0) {
+        /* CURLOPT_ENCODING. We are setting it to "" so curl will negotiate best method
+           and transparently decode it ... but it will leave Content-Encoding: header intact,
+           which will break some phones, namely Alcatel */
+        octstr_destroy(s);
+      } else {
+        list_append(l, s);
+      }
+    }
+    return realsize;
+}
+
+void curl_start_request(int method, Octstr *url,
+                        List *headers, Octstr *body, int follow, void *id) {
+    CURL* req = NULL;
+    struct curl_http_request * bfd = gw_malloc(sizeof(struct curl_http_request));
+
+    int i = 0;
+    int pragma = 0;
+
+    req = curl_easy_init();
+    bfd->url = octstr_duplicate(url);
+    bfd->request_headers = NULL;
+    bfd->body = NULL;
+    curl_easy_setopt(req, CURLOPT_URL, octstr_get_cstr(bfd->url));
+
+    if (method == HTTP_METHOD_POST) {
+      curl_easy_setopt(req, CURLOPT_POST, 1);
+      bfd->body = octstr_duplicate(body);
+      curl_easy_setopt(req, CURLOPT_POSTFIELDS, octstr_get_cstr(bfd->body));
+      curl_easy_setopt(req, CURLOPT_POSTFIELDSIZE, octstr_len(bfd->body));
+    }
+
+    if (method == HTTP_METHOD_HEAD)
+      curl_easy_setopt(req, CURLOPT_NOBODY, 1);
+
+    bfd->proxy = NULL;
+    mutex_lock(curl_proxy_mutex);
+    if (curl_proxy_str) {
+      bfd->proxy = octstr_duplicate(curl_proxy_str);
+      curl_easy_setopt(req, CURLOPT_PROXY, octstr_get_cstr(bfd->proxy));
+    }
+    mutex_unlock(curl_proxy_mutex);
+
+    curl_easy_setopt(req, CURLOPT_SSL_VERIFYPEER, 0);
+    curl_easy_setopt(req, CURLOPT_NOPROGRESS, 1);
+    curl_easy_setopt(req, CURLOPT_MUTE, 1);
+    curl_easy_setopt(req, CURLOPT_NOSIGNAL, 1);
+    curl_easy_setopt(req, CURLOPT_ENCODING, "");
+    curl_easy_setopt(req, CURLOPT_TIMEOUT, 60);
+
+    for (i = 0; i < list_len(headers); i++) {
+      bfd->request_headers = curl_slist_append(bfd->request_headers, octstr_get_cstr(list_get(headers, i)));
+      if (strncasecmp("Pragma:", octstr_get_cstr(list_get(headers, i)), 7) == 0)
+        pragma = 1;
+    }
+
+    if (!pragma)
+      bfd->request_headers = curl_slist_append(bfd->request_headers, "Pragma:");
+
+    curl_easy_setopt(req, CURLOPT_HTTPHEADER, bfd->request_headers);
+
+    bfd->id = id;
+    bfd->reply = octstr_create("");
+    bfd->headers = list_create();
+
+    curl_easy_setopt(req, CURLOPT_PRIVATE, bfd);
+
+    curl_easy_setopt(req, CURLOPT_WRITEFUNCTION, curl_writefunc);
+    curl_easy_setopt(req, CURLOPT_HEADERFUNCTION, curl_headfunc);
+    curl_easy_setopt(req, CURLOPT_WRITEDATA, bfd->reply);
+    curl_easy_setopt(req, CURLOPT_WRITEHEADER, bfd->headers);
+
+    curl_multi_add_handle(CurlMClient, req);
+    write(pipeh[1], "X", 1);
+}
+
+void *curl_receive_result(int *status, Octstr **final_url,
+                         List **headers, Octstr **body) {
+    fd_set f_read, f_write, f_exc;
+    int maxfd = 0;
+    int transfers = 0, msgs = 0;
+    char x;
+    struct curl_http_request * bfd;
+    void * p;
+    char* furl;
+    CURLMsg * msg;
+    CURL* hnd;
+    int result = 0;
+
+    while (1) {
+      while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(CurlMClient, &transfers));
+      while (msg = curl_multi_info_read(CurlMClient, &msgs)) {
+        hnd = msg->easy_handle;
+        result = msg->data.result;
+        curl_multi_remove_handle(CurlMClient, hnd);
+        if (CURLE_OK != curl_easy_getinfo(hnd, CURLINFO_PRIVATE, &bfd)) bfd = NULL;
+        if (bfd == NULL) continue;
+        if (CURLE_OK != curl_easy_getinfo(hnd, CURLINFO_HTTP_CODE, status)) (*status) = -1;
+        if (result != CURLE_OK) (*status) = -1;
+
+        (*headers) = bfd->headers;
+        (*body) = bfd->reply;
+        if (CURLE_OK == curl_easy_getinfo(hnd, CURLINFO_EFFECTIVE_URL, &furl))
+          (*final_url) = octstr_create(furl);
+        else (*final_url) = NULL;
+        p = bfd->id;
+        curl_easy_cleanup(hnd);
+        if (bfd->request_headers) curl_slist_free_all(bfd->request_headers);
+        if (bfd->proxy) octstr_destroy(bfd->proxy);
+        octstr_destroy(bfd->url);
+        octstr_destroy(bfd->body);
+        gw_free(bfd);
+        return p;
+      }
+
+      FD_ZERO(&f_read);
+      FD_ZERO(&f_write);
+      FD_ZERO(&f_exc);
+
+      curl_multi_fdset(CurlMClient, &f_read, &f_write, &f_exc, &maxfd);
+      if (maxfd < pipeh[0]) maxfd = pipeh[0];
+      FD_SET(pipeh[0], &f_read);
+      if (select(maxfd + 1, &f_read, &f_write, &f_exc, NULL) >= 0) {
+        if (FD_ISSET(pipeh[0], &f_read)) {
+          if (read(pipeh[0], &x, 1) == 1) {
+            continue;
+          } else {
+            return NULL;
+          }
+        }
+      } else return NULL;
+    }
+}
+#endif
 
 /*
  * WSP smart error messaging
@@ -244,6 +446,10 @@
 void wap_appl_init(Cfg *cfg) 
 {
     gw_assert(run_status == limbo);
+#ifdef CURL_SUPPORT
+    pipe(pipeh);
+    CurlMClient = curl_multi_init();
+#endif
     queue = list_create();
     fetches = counter_create();
     list_add_producer(queue);
@@ -267,6 +473,9 @@
     
     list_remove_producer(queue);
     gwthread_join_every(main_thread);
+#ifdef CURL_SUPPORT
+    close(pipeh[1]);
+#endif
     
     http_caller_signal_shutdown(caller);
     gwthread_join_every(return_replies_thread);
@@ -1060,8 +1269,11 @@
     List *headers;
 
     while (run_status == running) {
-
+#ifdef CURL_SUPPORT
+        p = curl_receive_result(&status, &final_url, &headers, &body);
+#else
         p = http_receive_result(caller, &status, &final_url, &headers, &body);
+#endif
         if (p == NULL)
             break;
 
@@ -1262,8 +1474,12 @@
         p->request_headers = actual_headers;
 
         /* issue the request to the HTTP server */
+#ifdef CURL_SUPPORT
+        curl_start_request(http_name2method(method), url, actual_headers, request_body, 0, p);
+#else
         http_start_request(caller, http_name2method(method), url, actual_headers, 
                            request_body, 0, p, NULL);
+#endif
 
         octstr_destroy(request_body);
     } 
Index: gateway.A9/gw/wapbox.c
===================================================================
--- gateway.A9.orig/gw/wapbox.c	2004-08-29 11:15:03.000000000 +0400
+++ gateway.A9/gw/wapbox.c	2004-11-06 17:36:55.730060608 +0300
@@ -85,6 +85,14 @@
 #endif
 #include "radius/radius_acct.h"
 
+#ifdef CURL_SUPPORT
+void curl_init();
+void curl_cleanup();
+void curl_use_proxy(Octstr *hostname, int port, List *exceptions,
+                    Octstr *username, Octstr *password);
+#define http_use_proxy curl_use_proxy
+#endif
+
 static void config_reload(int reload);
 static long logfilelevel=-1;
 
@@ -669,6 +677,10 @@
     cf_index = get_and_set_debugs(argc, argv, NULL);
     
     setup_signal_handlers();
+
+#ifdef CURL_SUPPORT
+    curl_init();
+#endif
     
     if (argv[cf_index] == NULL)
         config_filename = octstr_create("kannel.conf");
@@ -822,6 +834,10 @@
 
     gwlib_shutdown();
 
+#ifdef CURL_SUPPORT
+    curl_cleanup();
+#endif
+
     /* now really restart */
     if (restart)
         execvp(argv[0], argv);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.