From 7d95a056d2bbadaf157062d5e7b152e80c079f31 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 14 Jan 2008 21:31:17 +0000 Subject: [PATCH] add mod_spidermonkey_curl (pressuerman must doc) git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7222 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- .../languages/mod_spidermonkey_curl/Makefile | 2 + .../mod_spidermonkey_curl.c | 237 ++++++++++++++++++ 2 files changed, 239 insertions(+) create mode 100644 src/mod/languages/mod_spidermonkey_curl/Makefile create mode 100644 src/mod/languages/mod_spidermonkey_curl/mod_spidermonkey_curl.c diff --git a/src/mod/languages/mod_spidermonkey_curl/Makefile b/src/mod/languages/mod_spidermonkey_curl/Makefile new file mode 100644 index 0000000000..c5513eb435 --- /dev/null +++ b/src/mod/languages/mod_spidermonkey_curl/Makefile @@ -0,0 +1,2 @@ +WANT_CURL=yes +include ../mod_spidermonkey/sm.mak diff --git a/src/mod/languages/mod_spidermonkey_curl/mod_spidermonkey_curl.c b/src/mod/languages/mod_spidermonkey_curl/mod_spidermonkey_curl.c new file mode 100644 index 0000000000..ff6452862d --- /dev/null +++ b/src/mod/languages/mod_spidermonkey_curl/mod_spidermonkey_curl.c @@ -0,0 +1,237 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005/2006, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * + * + * mod_spidermonkey_teletone.c -- TeleTone Javascript Module + * + */ +#include "mod_spidermonkey.h" +#include + +static const char modname[] = "CURL"; + +struct curl_obj { + CURL *curl_handle; + JSContext *cx; + JSObject *obj; + JSFunction *function; + jsrefcount saveDepth; + jsval ret; +}; + + +static size_t file_callback(void *ptr, size_t size, size_t nmemb, void *data) +{ + register unsigned int realsize = (unsigned int) (size * nmemb); + struct curl_obj *co = data; + uintN argc = 0; + jsval argv[4]; + + + if (!co) { + return 0; + } + if (co->function) { + char *ret; + argv[argc++] = STRING_TO_JSVAL(JS_NewStringCopyZ(co->cx, (char *)ptr)); + + JS_ResumeRequest(co->cx, co->saveDepth); + JS_CallFunction(co->cx, co->obj, co->function, argc, argv, &co->ret); + co->saveDepth = JS_SuspendRequest(co->cx); + + if ((ret = JS_GetStringBytes(JS_ValueToString(co->cx, co->ret)))) { + if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) { + return realsize; + } else { + return 0; + } + } + } + + return realsize; +} + + +/* Curl Object */ +/*********************************************************************************/ +static JSBool curl_construct(JSContext *cx, JSObject *obj, uintN argc, jsval * argv, jsval * rval) +{ + struct curl_obj *co = NULL; + + co = malloc(sizeof(*co)); + switch_assert(co); + + memset(co, 0, sizeof(*co)); + + co->cx = cx; + co->obj = obj; + + JS_SetPrivate(cx, obj, co); + + return JS_TRUE; +} + +static void curl_destroy(JSContext *cx, JSObject *obj) +{ + struct curl_obj *co = JS_GetPrivate(cx, obj); + switch_safe_free(co); + JS_SetPrivate(cx, obj, NULL); +} + +static JSBool curl_run(JSContext *cx, JSObject *obj, uintN argc, jsval * argv, jsval * rval) +{ + struct curl_obj *co = JS_GetPrivate(cx, obj); + char *method = NULL, *url, *cred = NULL; + char *url_p = NULL, *data = NULL, *durl = NULL; + long httpRes = 0; + struct curl_slist *headers = NULL; + + if (argc < 2 || !co) { + return JS_FALSE; + } + + + method = JS_GetStringBytes(JS_ValueToString(cx, argv[0])); + url = JS_GetStringBytes(JS_ValueToString(cx, argv[1])); + + co->curl_handle = curl_easy_init(); + if (!strncasecmp(url, "https", 5)) { + curl_easy_setopt(co->curl_handle, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(co->curl_handle, CURLOPT_SSL_VERIFYHOST, 0); + } + headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded"); + + if (argc > 2) { + data = JS_GetStringBytes(JS_ValueToString(cx, argv[2])); + } + + if (argc > 3) { + co->function = JS_ValueToFunction(cx, argv[3]); + } + + if (argc > 4) { + cred = JS_GetStringBytes(JS_ValueToString(cx, argv[4])); + if (!switch_strlen_zero(cred)) { + curl_easy_setopt(co->curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_easy_setopt(co->curl_handle, CURLOPT_USERPWD, cred); + } + } + + + curl_easy_setopt(co->curl_handle, CURLOPT_HTTPHEADER, headers); + + url_p = url; + + if (!strcasecmp(method, "post")) { + curl_easy_setopt(co->curl_handle, CURLOPT_POST, 1); + if (!data) { + data = ""; + } + curl_easy_setopt(co->curl_handle, CURLOPT_POSTFIELDS, data); + } else if (!switch_strlen_zero(data)) { + durl = switch_mprintf("%s?%s", url, data); + url_p = durl; + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Running: method: [%s] url: [%s] data: [%s] cred=[%s] cb: [%s]\n", + method, url_p, data, switch_str_nil(cred), co->function ? "yes" : "no"); + + curl_easy_setopt(co->curl_handle, CURLOPT_URL, url_p); + curl_easy_setopt(co->curl_handle, CURLOPT_WRITEFUNCTION, file_callback); + curl_easy_setopt(co->curl_handle, CURLOPT_WRITEDATA, (void *) co); + + curl_easy_setopt(co->curl_handle, CURLOPT_USERAGENT, "freeswitch-spidermonkey-curl/1.0"); + + co->saveDepth = JS_SuspendRequest(cx); + curl_easy_perform(co->curl_handle); + + curl_easy_getinfo(co->curl_handle, CURLINFO_RESPONSE_CODE, &httpRes); + curl_easy_cleanup(co->curl_handle); + curl_slist_free_all(headers); + co->curl_handle = NULL; + co->function = NULL; + JS_ResumeRequest(cx, co->saveDepth); + switch_safe_free(durl); + + + return JS_FALSE; +} + +static JSFunctionSpec curl_methods[] = { + {"run", curl_run, 2}, + {0} +}; + + +static JSPropertySpec curl_props[] = { + {0} +}; + +static JSBool curl_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval * vp) +{ + JSBool res = JS_TRUE; + return res; +} + +JSClass curl_class = { + modname, JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, curl_getProperty, DEFAULT_SET_PROPERTY, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, curl_destroy, NULL, NULL, NULL, + curl_construct +}; + + +switch_status_t curl_load(JSContext *cx, JSObject *obj) +{ + JS_InitClass(cx, obj, NULL, &curl_class, curl_construct, 3, curl_props, curl_methods, curl_props, curl_methods); + return SWITCH_STATUS_SUCCESS; +} + + +const sm_module_interface_t curl_module_interface = { + /*.name = */ modname, + /*.spidermonkey_load */ curl_load, + /*.next */ NULL +}; + +SWITCH_MOD_DECLARE(switch_status_t) spidermonkey_init(const sm_module_interface_t ** module_interface) +{ + curl_global_init(CURL_GLOBAL_ALL); + *module_interface = &curl_module_interface; + return SWITCH_STATUS_SUCCESS; +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab: + */