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
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);

Reply via email to