2009-07-01 20:03:48 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
2014-02-05 15:02:28 -06:00
* Copyright ( C ) 2005 - 2014 , Anthony Minessale II < anthm @ freeswitch . org >
2009-07-01 20:03:48 +00:00
*
* 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 < anthm @ freeswitch . org >
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
*
* Rupa Schomaker < rupa @ rupa . com >
2013-02-28 14:32:50 -05:00
* Yossi Neiman < mishehu @ freeswitch . org >
2013-07-30 16:35:46 +08:00
* Seven Du < dujinfang @ gmail . com >
2009-07-01 20:03:48 +00:00
*
* mod_curl . c - - API for performing http queries
*
*/
2010-02-06 03:38:24 +00:00
2009-07-01 20:03:48 +00:00
# include <switch.h>
2011-11-29 11:13:11 -06:00
# include <switch_curl.h>
2013-02-28 14:30:56 -06:00
# ifdef _MSC_VER
# include <WinSock2.h>
# else
2013-02-28 14:32:50 -05:00
# include <sys/socket.h>
2013-02-28 14:30:56 -06:00
# endif
2009-07-01 20:03:48 +00:00
/* Prototypes */
SWITCH_MODULE_SHUTDOWN_FUNCTION ( mod_curl_shutdown ) ;
SWITCH_MODULE_RUNTIME_FUNCTION ( mod_curl_runtime ) ;
SWITCH_MODULE_LOAD_FUNCTION ( mod_curl_load ) ;
/* SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime)
* Defines a switch_loadable_module_function_table_t and a static const char [ ] modname
*/
SWITCH_MODULE_DEFINITION ( mod_curl , mod_curl_load , mod_curl_shutdown , NULL ) ;
2014-11-16 19:16:39 +00:00
static char * SYNTAX = " curl url [headers|json|content-type <mime-type>|connect-timeout <seconds>|timeout <seconds>] [get|head|post|delete|put [data]] " ;
2009-07-01 20:03:48 +00:00
2013-02-28 14:32:50 -05:00
# define HTTP_SENDFILE_ACK_EVENT "curl_sendfile::ack"
# define HTTP_SENDFILE_RESPONSE_SIZE 32768
2009-07-01 20:03:48 +00:00
static struct {
switch_memory_pool_t * pool ;
} globals ;
2013-02-28 14:32:50 -05:00
typedef enum {
CSO_NONE = ( 1 < < 0 ) ,
CSO_EVENT = ( 1 < < 1 ) ,
CSO_STREAM = ( 1 < < 2 )
} curlsendfile_output_t ;
2009-07-01 20:03:48 +00:00
struct http_data_obj {
switch_stream_handle_t stream ;
switch_size_t bytes ;
switch_size_t max_bytes ;
switch_memory_pool_t * pool ;
int err ;
long http_response_code ;
char * http_response ;
2011-11-29 15:35:36 -06:00
switch_curl_slist_t * headers ;
2009-07-01 20:03:48 +00:00
} ;
typedef struct http_data_obj http_data_t ;
2013-02-28 14:32:50 -05:00
struct http_sendfile_data_obj {
switch_memory_pool_t * pool ;
switch_file_t * file_handle ;
long http_response_code ;
char * http_response ;
switch_curl_slist_t * headers ;
char * mydata ;
char * url ;
char * identifier_str ;
char * filename_element ;
char * filename_element_name ;
char * extrapost_elements ;
switch_CURL * curl_handle ;
struct curl_httppost * formpost ;
struct curl_httppost * lastptr ;
uint8_t flags ; /* This is for where to send output of the curl_sendfile commands */
switch_stream_handle_t * stream ;
char * sendfile_response ;
switch_size_t sendfile_response_count ;
} ;
typedef struct http_sendfile_data_obj http_sendfile_data_t ;
2014-07-04 01:48:13 +00:00
struct data_stream {
const char * data ;
size_t length ;
} ;
2009-07-01 20:03:48 +00:00
struct callback_obj {
switch_memory_pool_t * pool ;
char * name ;
} ;
typedef struct callback_obj callback_t ;
2013-07-30 16:35:46 +08:00
struct curl_options_obj {
long connect_timeout ;
long timeout ;
} ;
typedef struct curl_options_obj curl_options_t ;
2009-07-01 20:03:48 +00:00
static size_t file_callback ( void * ptr , size_t size , size_t nmemb , void * data )
{
register unsigned int realsize = ( unsigned int ) ( size * nmemb ) ;
http_data_t * http_data = data ;
http_data - > bytes + = realsize ;
if ( http_data - > bytes > http_data - > max_bytes ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Oversized file detected [%d bytes] \n " , ( int ) http_data - > bytes ) ;
2009-07-01 20:03:48 +00:00
http_data - > err = 1 ;
return 0 ;
}
2010-02-06 03:38:24 +00:00
http_data - > stream . write_function ( & http_data - > stream , " %.*s " , realsize , ptr ) ;
2009-07-01 20:03:48 +00:00
return realsize ;
}
static size_t header_callback ( void * ptr , size_t size , size_t nmemb , void * data )
{
register unsigned int realsize = ( unsigned int ) ( size * nmemb ) ;
http_data_t * http_data = data ;
char * header = NULL ;
2010-02-06 03:38:24 +00:00
header = switch_core_alloc ( http_data - > pool , realsize + 1 ) ;
2009-07-01 20:03:48 +00:00
switch_copy_string ( header , ptr , realsize ) ;
header [ realsize ] = ' \0 ' ;
2011-11-29 15:35:36 -06:00
http_data - > headers = switch_curl_slist_append ( http_data - > headers , header ) ;
2010-02-06 03:38:24 +00:00
2009-07-01 20:03:48 +00:00
return realsize ;
}
2014-07-04 01:48:13 +00:00
static size_t read_callback ( void * ptr , size_t size , size_t nmemb , void * stream )
{
struct data_stream * dstream = ( struct data_stream * ) stream ;
2014-07-04 07:47:04 +00:00
size_t nmax = size * nmemb ;
size_t ncur = ( dstream - > length > nmax ) ? nmax : dstream - > length ;
2014-07-04 01:48:13 +00:00
memmove ( ptr , dstream - > data , ncur ) ;
2014-07-04 07:43:59 +00:00
dstream - > data + = ncur ;
2014-07-04 07:47:04 +00:00
dstream - > length - = ncur ;
2014-07-04 01:48:13 +00:00
return ncur ;
}
2013-07-30 16:35:46 +08:00
static http_data_t * do_lookup_url ( switch_memory_pool_t * pool , const char * url , const char * method , const char * data , const char * content_type , curl_options_t * options )
2010-02-06 03:38:24 +00:00
{
2011-11-29 15:35:36 -06:00
switch_CURL * curl_handle = NULL ;
2009-07-01 20:03:48 +00:00
long httpRes = 0 ;
http_data_t * http_data = NULL ;
2013-02-13 15:08:19 -05:00
switch_curl_slist_t * headers = NULL ;
2014-07-04 01:48:13 +00:00
struct data_stream dstream = { NULL } ;
2009-07-01 20:03:48 +00:00
http_data = switch_core_alloc ( pool , sizeof ( http_data_t ) ) ;
memset ( http_data , 0 , sizeof ( http_data_t ) ) ;
http_data - > pool = pool ;
2010-02-06 03:38:24 +00:00
2009-07-01 20:03:48 +00:00
http_data - > max_bytes = 64000 ;
SWITCH_STANDARD_STREAM ( http_data - > stream ) ;
2009-07-24 17:06:22 +00:00
if ( ! method ) {
method = " get " ;
}
2010-02-06 03:38:24 +00:00
2013-07-30 22:12:58 +08:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " method: %s, url: %s, content-type: %s \n " , method , url , content_type ) ;
2013-02-13 15:08:19 -05:00
curl_handle = switch_curl_easy_init ( ) ;
2010-02-06 03:38:24 +00:00
2013-07-30 16:35:46 +08:00
if ( options ) {
if ( options - > connect_timeout ) {
switch_curl_easy_setopt ( curl_handle , CURLOPT_CONNECTTIMEOUT , options - > connect_timeout ) ;
}
if ( options - > timeout ) {
switch_curl_easy_setopt ( curl_handle , CURLOPT_TIMEOUT , options - > timeout ) ;
}
}
2009-07-01 20:03:48 +00:00
if ( ! strncasecmp ( url , " https " , 5 ) ) {
2014-08-21 22:17:35 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Not verifying TLS cert for %s; connection is not secure \n " , url ) ;
2013-02-13 15:08:19 -05:00
switch_curl_easy_setopt ( curl_handle , CURLOPT_SSL_VERIFYPEER , 0 ) ;
switch_curl_easy_setopt ( curl_handle , CURLOPT_SSL_VERIFYHOST , 0 ) ;
2009-07-01 20:03:48 +00:00
}
2009-07-24 17:06:22 +00:00
if ( ! strcasecmp ( method , " head " ) ) {
2013-02-13 15:08:19 -05:00
switch_curl_easy_setopt ( curl_handle , CURLOPT_NOBODY , 1 ) ;
2009-12-11 01:20:26 +00:00
} else if ( ! strcasecmp ( method , " post " ) ) {
2013-02-13 15:08:19 -05:00
switch_curl_easy_setopt ( curl_handle , CURLOPT_POSTFIELDSIZE , strlen ( data ) ) ;
switch_curl_easy_setopt ( curl_handle , CURLOPT_POSTFIELDS , ( void * ) data ) ;
if ( content_type ) {
char * ct = switch_mprintf ( " Content-Type: %s " , content_type ) ;
headers = switch_curl_slist_append ( headers , ct ) ;
switch_curl_easy_setopt ( curl_handle , CURLOPT_HTTPHEADER , headers ) ;
switch_safe_free ( ct ) ;
}
2013-02-25 17:45:10 -08:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Post data: %s \n " , data ) ;
2014-07-31 02:29:02 +00:00
} else if ( ! strcasecmp ( method , " delete " ) ) {
switch_curl_easy_setopt ( curl_handle , CURLOPT_CUSTOMREQUEST , " DELETE " ) ;
switch_curl_easy_setopt ( curl_handle , CURLOPT_POSTFIELDSIZE , strlen ( data ) ) ;
switch_curl_easy_setopt ( curl_handle , CURLOPT_POSTFIELDS , ( void * ) data ) ;
if ( content_type ) {
char * ct = switch_mprintf ( " Content-Type: %s " , content_type ) ;
headers = switch_curl_slist_append ( headers , ct ) ;
switch_curl_easy_setopt ( curl_handle , CURLOPT_HTTPHEADER , headers ) ;
switch_safe_free ( ct ) ;
}
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " DELETE data: %s \n " , data ) ;
2014-07-04 01:48:13 +00:00
} else if ( ! strcasecmp ( method , " put " ) ) {
dstream . data = data ;
dstream . length = strlen ( data ) ;
switch_curl_easy_setopt ( curl_handle , CURLOPT_UPLOAD , 1 ) ;
switch_curl_easy_setopt ( curl_handle , CURLOPT_READFUNCTION , read_callback ) ;
switch_curl_easy_setopt ( curl_handle , CURLOPT_INFILESIZE_LARGE , ( curl_off_t ) dstream . length ) ;
switch_curl_easy_setopt ( curl_handle , CURLOPT_READDATA , ( void * ) & dstream ) ;
if ( content_type ) {
char * ct = switch_mprintf ( " Content-Type: %s " , content_type ) ;
headers = switch_curl_slist_append ( headers , ct ) ;
headers = switch_curl_slist_append ( headers , " Expect: " ) ;
switch_curl_easy_setopt ( curl_handle , CURLOPT_HTTPHEADER , headers ) ;
switch_safe_free ( ct ) ;
}
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " PUT data: %s \n " , data ) ;
2009-07-24 17:06:22 +00:00
} else {
2013-02-13 15:08:19 -05:00
switch_curl_easy_setopt ( curl_handle , CURLOPT_HTTPGET , 1 ) ;
2009-07-24 17:06:22 +00:00
}
2013-02-13 15:08:19 -05:00
switch_curl_easy_setopt ( curl_handle , CURLOPT_FOLLOWLOCATION , 1 ) ;
switch_curl_easy_setopt ( curl_handle , CURLOPT_MAXREDIRS , 15 ) ;
2014-11-17 11:01:35 -05:00
switch_curl_easy_setopt ( curl_handle , CURLOPT_HTTPAUTH , CURLAUTH_ANY ) ;
2013-02-13 15:08:19 -05:00
switch_curl_easy_setopt ( curl_handle , CURLOPT_URL , url ) ;
switch_curl_easy_setopt ( curl_handle , CURLOPT_NOSIGNAL , 1 ) ;
switch_curl_easy_setopt ( curl_handle , CURLOPT_WRITEFUNCTION , file_callback ) ;
switch_curl_easy_setopt ( curl_handle , CURLOPT_WRITEDATA , ( void * ) http_data ) ;
switch_curl_easy_setopt ( curl_handle , CURLOPT_HEADERFUNCTION , header_callback ) ;
switch_curl_easy_setopt ( curl_handle , CURLOPT_HEADERDATA , ( void * ) http_data ) ;
switch_curl_easy_setopt ( curl_handle , CURLOPT_USERAGENT , " freeswitch-curl/1.0 " ) ;
switch_curl_easy_perform ( curl_handle ) ;
switch_curl_easy_getinfo ( curl_handle , CURLINFO_RESPONSE_CODE , & httpRes ) ;
switch_curl_easy_cleanup ( curl_handle ) ;
switch_curl_slist_free_all ( headers ) ;
2010-02-06 03:38:24 +00:00
if ( http_data - > stream . data & & ! zstr ( ( char * ) http_data - > stream . data ) & & strcmp ( " " , http_data - > stream . data ) ) {
2009-07-01 20:03:48 +00:00
http_data - > http_response = switch_core_strdup ( pool , http_data - > stream . data ) ;
}
2010-02-06 03:38:24 +00:00
2009-07-01 20:03:48 +00:00
http_data - > http_response_code = httpRes ;
2010-02-06 03:38:24 +00:00
2009-07-01 20:03:48 +00:00
switch_safe_free ( http_data - > stream . data ) ;
return http_data ;
}
2010-02-06 03:38:24 +00:00
static char * print_json ( switch_memory_pool_t * pool , http_data_t * http_data )
{
2015-03-03 22:50:21 -06:00
cJSON * top = cJSON_CreateObject ( ) ,
2015-06-30 12:45:01 -05:00
* headers = cJSON_CreateArray ( ) ;
2009-07-01 22:26:59 +00:00
char * data = NULL ;
2015-03-03 22:50:21 -06:00
char tmp [ 32 ] , * f = NULL ;
2011-11-29 15:35:36 -06:00
switch_curl_slist_t * header = http_data - > headers ;
2015-03-03 22:50:21 -06:00
if ( ! top | | ! headers ) {
cJSON_Delete ( headers ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Unable to alloc memory for cJSON structures. \n " ) ;
goto curl_json_output_end ;
}
switch_snprintf ( tmp , sizeof ( tmp ) , " %ld " , http_data - > http_response_code ) ;
cJSON_AddItemToObject ( top , " status_code " , cJSON_CreateString ( tmp ) ) ;
2009-07-01 22:26:59 +00:00
if ( http_data - > http_response ) {
2015-03-03 22:50:21 -06:00
cJSON_AddItemToObject ( top , " body " , cJSON_CreateString ( http_data - > http_response ) ) ;
2009-07-01 22:26:59 +00:00
}
2010-02-06 03:38:24 +00:00
2009-07-01 22:26:59 +00:00
/* parse header data */
2010-02-06 03:38:24 +00:00
while ( header ) {
2015-03-03 22:50:21 -06:00
cJSON * obj = NULL ;
2009-07-01 22:26:59 +00:00
/* remove trailing \r */
2010-03-03 21:28:51 +00:00
if ( ( data = strrchr ( header - > data , ' \r ' ) ) ) {
2009-07-01 22:26:59 +00:00
* data = ' \0 ' ;
}
2010-02-06 03:38:24 +00:00
2009-11-06 15:58:08 +00:00
if ( zstr ( header - > data ) ) {
2009-07-01 22:26:59 +00:00
header = header - > next ;
continue ;
}
2010-02-06 03:38:24 +00:00
2010-03-03 21:28:51 +00:00
if ( ( data = strchr ( header - > data , ' : ' ) ) ) {
2009-07-01 22:26:59 +00:00
* data = ' \0 ' ;
data + + ;
2010-02-06 03:38:24 +00:00
while ( * data = = ' ' & & * data ! = ' \0 ' ) {
2009-07-01 22:26:59 +00:00
data + + ;
}
2015-03-03 22:50:21 -06:00
obj = cJSON_CreateObject ( ) ;
cJSON_AddItemToObject ( obj , " key " , cJSON_CreateString ( header - > data ) ) ;
cJSON_AddItemToObject ( obj , " value " , cJSON_CreateString ( data ) ) ;
cJSON_AddItemToArray ( headers , obj ) ;
2009-07-01 22:26:59 +00:00
} else {
if ( ! strncmp ( " HTTP " , header - > data , 4 ) ) {
char * argv [ 3 ] = { 0 } ;
int argc ;
if ( ( argc = switch_separate_string ( header - > data , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) ) {
if ( argc > 2 ) {
2015-03-03 22:50:21 -06:00
cJSON_AddItemToObject ( top , " version " , cJSON_CreateString ( argv [ 0 ] ) ) ;
cJSON_AddItemToObject ( top , " phrase " , cJSON_CreateString ( argv [ 2 ] ) ) ;
2009-07-01 22:26:59 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Unparsable header: argc: %d \n " , argc ) ;
}
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Starts with HTTP but not parsable: %s \n " , header - > data ) ;
}
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Unparsable header: %s \n " , header - > data ) ;
}
}
header = header - > next ;
}
2015-03-03 22:50:21 -06:00
cJSON_AddItemToObject ( top , " headers " , headers ) ;
f = cJSON_PrintUnformatted ( top ) ;
data = switch_core_strdup ( pool , f ) ;
switch_safe_free ( f ) ;
curl_json_output_end :
cJSON_Delete ( top ) ; /* should free up all children */
2009-07-01 22:26:59 +00:00
return data ;
}
2013-02-28 14:32:50 -05:00
static size_t http_sendfile_response_callback ( void * ptr , size_t size , size_t nmemb , void * data )
{
register unsigned int realsize = ( unsigned int ) ( size * nmemb ) ;
http_sendfile_data_t * http_data = data ;
if ( http_data - > sendfile_response_count + realsize < HTTP_SENDFILE_RESPONSE_SIZE )
{
// I'm not sure why we need the (realsize+1) here, but it truncates the data by 1 char if I don't do this
switch_copy_string ( & http_data - > sendfile_response [ http_data - > sendfile_response_count ] , ptr , ( realsize + 1 ) ) ;
http_data - > sendfile_response_count + = realsize ;
}
else
{
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Response page is more than %d bytes long, truncating. \n " , HTTP_SENDFILE_RESPONSE_SIZE ) ;
realsize = 0 ;
}
return realsize ;
}
// This function and do_lookup_url functions could possibly be merged together. Or at least have do_lookup_url call this up as part of the initialization routine as it is a subset of the operations.
static void http_sendfile_initialize_curl ( http_sendfile_data_t * http_data )
{
2013-02-28 14:30:56 -06:00
uint8_t count ;
2013-02-28 14:32:50 -05:00
http_data - > curl_handle = curl_easy_init ( ) ;
if ( ! strncasecmp ( http_data - > url , " https " , 5 ) )
{
2014-08-21 22:17:35 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Not verifying TLS cert for %s; connection is not secure \n " , http_data - > url ) ;
2013-02-28 14:32:50 -05:00
curl_easy_setopt ( http_data - > curl_handle , CURLOPT_SSL_VERIFYPEER , 0 ) ;
curl_easy_setopt ( http_data - > curl_handle , CURLOPT_SSL_VERIFYHOST , 0 ) ;
}
/* From the docs:
* Optionally , you can provide data to POST using the CURLOPT_READFUNCTION and CURLOPT_READDATA
* options but then you must make sure to not set CURLOPT_POSTFIELDS to anything but NULL
* curl_easy_setopt ( curl_handle , CURLOPT_POSTFIELDSIZE , strlen ( data ) ) ;
* curl_easy_setopt ( curl_handle , CURLOPT_POSTFIELDS , ( void * ) data ) ;
*/
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Post data: %s\n", data);
curl_easy_setopt ( http_data - > curl_handle , CURLOPT_FOLLOWLOCATION , 1 ) ;
curl_easy_setopt ( http_data - > curl_handle , CURLOPT_MAXREDIRS , 15 ) ;
curl_easy_setopt ( http_data - > curl_handle , CURLOPT_URL , http_data - > url ) ;
curl_easy_setopt ( http_data - > curl_handle , CURLOPT_NOSIGNAL , 1 ) ;
curl_easy_setopt ( http_data - > curl_handle , CURLOPT_USERAGENT , " freeswitch-curl/1.0 " ) ;
http_data - > sendfile_response = switch_core_alloc ( http_data - > pool , sizeof ( char ) * HTTP_SENDFILE_RESPONSE_SIZE ) ;
memset ( http_data - > sendfile_response , 0 , sizeof ( char ) * HTTP_SENDFILE_RESPONSE_SIZE ) ;
// Set the function where we will copy out the response body data to
curl_easy_setopt ( http_data - > curl_handle , CURLOPT_WRITEFUNCTION , http_sendfile_response_callback ) ;
curl_easy_setopt ( http_data - > curl_handle , CURLOPT_WRITEDATA , ( void * ) http_data ) ;
/* Add the file to upload as a POST form field */
curl_formadd ( & http_data - > formpost , & http_data - > lastptr , CURLFORM_COPYNAME , http_data - > filename_element_name , CURLFORM_FILE , http_data - > filename_element , CURLFORM_END ) ;
if ( ! zstr ( http_data - > extrapost_elements ) )
{
// Now to parse out the individual post element/value pairs
char * argv [ 64 ] = { 0 } ; // Probably don't need 64 but eh does it really use that much memory?
uint32_t argc = 0 ;
char * temp_extrapost = switch_core_strdup ( http_data - > pool , http_data - > extrapost_elements ) ;
argc = switch_separate_string ( temp_extrapost , ' & ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
2013-02-28 14:30:56 -06:00
for ( count = 0 ; count < argc ; count + + )
2013-02-28 14:32:50 -05:00
{
char * argv2 [ 4 ] = { 0 } ;
uint32_t argc2 = switch_separate_string ( argv [ count ] , ' = ' , argv2 , ( sizeof ( argv2 ) / sizeof ( argv2 [ 0 ] ) ) ) ;
2014-08-20 10:22:27 +00:00
if ( argc2 = = 2 ) {
switch_url_decode ( argv2 [ 0 ] ) ;
switch_url_decode ( argv2 [ 1 ] ) ;
2013-02-28 14:32:50 -05:00
curl_formadd ( & http_data - > formpost , & http_data - > lastptr , CURLFORM_COPYNAME , argv2 [ 0 ] , CURLFORM_COPYCONTENTS , argv2 [ 1 ] , CURLFORM_END ) ;
2014-08-20 10:22:27 +00:00
}
2013-02-28 14:32:50 -05:00
}
}
/* Fill in the submit field too, even if this isn't really needed */
curl_formadd ( & http_data - > formpost , & http_data - > lastptr , CURLFORM_COPYNAME , " submit " , CURLFORM_COPYCONTENTS , " or_die " , CURLFORM_END ) ;
/* what URL that receives this POST */
curl_easy_setopt ( http_data - > curl_handle , CURLOPT_HTTPPOST , http_data - > formpost ) ;
// This part actually fires off the curl, captures the HTTP response code, and then frees up the handle.
curl_easy_perform ( http_data - > curl_handle ) ;
curl_easy_getinfo ( http_data - > curl_handle , CURLINFO_RESPONSE_CODE , & http_data - > http_response_code ) ;
curl_easy_cleanup ( http_data - > curl_handle ) ;
// Clean up the form data from POST
curl_formfree ( http_data - > formpost ) ;
}
static switch_status_t http_sendfile_test_file_open ( http_sendfile_data_t * http_data , switch_event_t * event )
{
switch_status_t retval = switch_file_open ( & http_data - > file_handle , http_data - > filename_element , SWITCH_FOPEN_READ , SWITCH_FPROT_UREAD , http_data - > pool ) ;
if ( retval ! = SWITCH_STATUS_SUCCESS )
{
if ( switch_test_flag ( http_data , CSO_EVENT ) )
{
if ( switch_event_create_subclass ( & event , SWITCH_EVENT_CUSTOM , HTTP_SENDFILE_ACK_EVENT ) = = SWITCH_STATUS_SUCCESS )
{
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Command-Execution-Identifier " , http_data - > identifier_str ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Filename " , http_data - > filename_element ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " File-Access " , " Failure " ) ;
switch_event_fire ( & event ) ;
switch_event_destroy ( & event ) ;
}
else
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Unable to create event to notify of failure to open file %s \n " , http_data - > filename_element ) ;
}
if ( ( switch_test_flag ( http_data , CSO_STREAM ) | | switch_test_flag ( http_data , CSO_NONE ) ) & & http_data - > stream )
http_data - > stream - > write_function ( http_data - > stream , " -Err Unable to open file %s \n " , http_data - > filename_element ) ;
if ( switch_test_flag ( http_data , CSO_NONE ) & & ! http_data - > stream )
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " curl_sendfile: Unable to open file %s \n " , http_data - > filename_element ) ;
}
return retval ;
}
static void http_sendfile_success_report ( http_sendfile_data_t * http_data , switch_event_t * event )
{
if ( switch_test_flag ( http_data , CSO_EVENT ) )
{
if ( switch_event_create_subclass ( & event , SWITCH_EVENT_CUSTOM , HTTP_SENDFILE_ACK_EVENT ) = = SWITCH_STATUS_SUCCESS )
{
char * code_as_string = switch_core_alloc ( http_data - > pool , 16 ) ;
memset ( code_as_string , 0 , 16 ) ;
switch_snprintf ( code_as_string , 16 , " %d " , http_data - > http_response_code ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Command-Execution-Identifier " , http_data - > identifier_str ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Filename " , http_data - > filename_element ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " File-Access " , " Success " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " REST-HTTP-Code " , code_as_string ) ;
switch_event_add_body ( event , " %s " , http_data - > sendfile_response ) ;
switch_event_fire ( & event ) ;
switch_event_destroy ( & event ) ;
}
else
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Unable to create a event to report on success of curl_sendfile. \n " ) ;
}
if ( ( switch_test_flag ( http_data , CSO_STREAM ) | | switch_test_flag ( http_data , CSO_NONE ) | | switch_test_flag ( http_data , CSO_EVENT ) ) & & http_data - > stream )
{
if ( http_data - > http_response_code = = 200 )
http_data - > stream - > write_function ( http_data - > stream , " +200 Ok \n " ) ;
else
http_data - > stream - > write_function ( http_data - > stream , " -%d Err \n " , http_data - > http_response_code ) ;
if ( http_data - > sendfile_response_count & & switch_test_flag ( http_data , CSO_STREAM ) )
http_data - > stream - > write_function ( http_data - > stream , " %s \n " , http_data - > sendfile_response ) ;
}
if ( switch_test_flag ( http_data , CSO_NONE ) & & ! http_data - > stream )
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Sending of file %s to url %s resulted with code %lu \n " , http_data - > filename_element , http_data - > url , http_data - > http_response_code ) ;
}
# define HTTP_SENDFILE_APP_SYNTAX "<url> <filenameParamName=filepath> [nopost|postparam1=foo&postparam2=bar... [event|none [identifier ]]]"
SWITCH_STANDARD_APP ( http_sendfile_app_function )
{
switch_event_t * event = NULL ;
char * argv [ 10 ] = { 0 } , * argv2 [ 10 ] = { 0 } ;
int argc = 0 , argc2 = 0 ;
http_sendfile_data_t * http_data = NULL ;
switch_memory_pool_t * pool = switch_core_session_get_pool ( session ) ;
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
http_data = switch_core_alloc ( pool , sizeof ( http_sendfile_data_t ) ) ;
memset ( http_data , 0 , sizeof ( http_sendfile_data_t ) ) ;
http_data - > pool = pool ;
// Either the parameters are provided on the data="" or else they are provided as chanvars. No mixing & matching
if ( ! zstr ( data ) )
{
http_data - > mydata = switch_core_strdup ( http_data - > pool , data ) ;
if ( ( argc = switch_separate_string ( http_data - > mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) )
{
uint8_t i = 0 ;
if ( argc < 2 | | argc > 5 )
goto http_sendfile_app_usage ;
http_data - > url = switch_core_strdup ( http_data - > pool , argv [ i + + ] ) ;
switch_url_decode ( argv [ i ] ) ;
argc2 = switch_separate_string ( argv [ i + + ] , ' = ' , argv2 , ( sizeof ( argv2 ) / sizeof ( argv2 [ 0 ] ) ) ) ;
if ( argc2 = = 2 )
{
http_data - > filename_element_name = switch_core_strdup ( pool , argv2 [ 0 ] ) ;
http_data - > filename_element = switch_core_strdup ( pool , argv2 [ 1 ] ) ;
}
else
goto http_sendfile_app_usage ;
if ( argc > 2 )
{
http_data - > extrapost_elements = switch_core_strdup ( pool , argv [ i + + ] ) ;
if ( argc > 3 )
{
if ( ! strncasecmp ( argv [ i + + ] , " event " , 5 ) )
{
switch_set_flag ( http_data , CSO_EVENT ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Setting output to event handler. \n " ) ;
}
if ( argc > 4 )
{
if ( strncasecmp ( argv [ i ] , " uuid " , 4 ) )
http_data - > identifier_str = switch_core_session_get_uuid ( session ) ;
else
http_data - > identifier_str = switch_core_strdup ( pool , argv [ i + + ] ) ;
}
}
}
}
}
else
{
char * send_output = ( char * ) switch_channel_get_variable_dup ( channel , " curl_sendfile_report " , SWITCH_TRUE , - 1 ) ;
char * identifier = ( char * ) switch_channel_get_variable_dup ( channel , " curl_sendfile_identifier " , SWITCH_TRUE , - 1 ) ;
http_data - > url = ( char * ) switch_channel_get_variable_dup ( channel , " curl_sendfile_url " , SWITCH_TRUE , - 1 ) ;
http_data - > filename_element_name = ( char * ) switch_channel_get_variable_dup ( channel , " curl_sendfile_filename_element " , SWITCH_TRUE , - 1 ) ;
http_data - > filename_element = ( char * ) switch_channel_get_variable_dup ( channel , " curl_sendfile_filename " , SWITCH_TRUE , - 1 ) ;
http_data - > extrapost_elements = ( char * ) switch_channel_get_variable_dup ( channel , " curl_sendfile_extrapost " , SWITCH_TRUE , - 1 ) ;
if ( zstr ( http_data - > url ) | | zstr ( http_data - > filename_element ) | | zstr ( http_data - > filename_element_name ) )
goto http_sendfile_app_usage ;
if ( ! zstr ( send_output ) )
{
if ( ! strncasecmp ( send_output , " event " , 5 ) )
switch_set_flag ( http_data , CSO_EVENT ) ;
else if ( ! strncasecmp ( send_output , " none " , 4 ) )
switch_set_flag ( http_data , CSO_NONE ) ;
else
{
switch_set_flag ( http_data , CSO_NONE ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Invalid parameter %s specified for curl_sendfile_report. Setting default of 'none'. \n " , send_output ) ;
}
}
else
{
switch_set_flag ( http_data , CSO_NONE ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " No parameter specified for curl_sendfile_report. Setting default of 'none'. \n " ) ;
}
if ( ! zstr ( identifier ) )
{
if ( ! strncasecmp ( identifier , " uuid " , 4 ) )
http_data - > identifier_str = switch_core_session_get_uuid ( session ) ;
else if ( ! zstr ( identifier ) )
http_data - > identifier_str = identifier ;
}
}
switch_url_decode ( http_data - > filename_element_name ) ;
switch_url_decode ( http_data - > filename_element ) ;
// We need to check the file now...
if ( http_sendfile_test_file_open ( http_data , event ) ! = SWITCH_STATUS_SUCCESS )
goto http_sendfile_app_done ;
switch_file_close ( http_data - > file_handle ) ;
switch_url_decode ( http_data - > url ) ;
http_sendfile_initialize_curl ( http_data ) ;
http_sendfile_success_report ( http_data , event ) ;
goto http_sendfile_app_done ;
http_sendfile_app_usage :
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Failure: Usage: <data= \" %s \" > \n Or you can set chanvars curl_senfile_url, curl_sendfile_filename_element, curl_sendfile_filename, curl_sendfile_extrapost \n " , HTTP_SENDFILE_APP_SYNTAX ) ;
http_sendfile_app_done :
2014-04-29 14:34:49 -04:00
if ( http_data - > headers )
2013-02-28 14:32:50 -05:00
{
switch_curl_slist_free_all ( http_data - > headers ) ;
}
return ;
}
# define HTTP_SENDFILE_SYNTAX "<url> <filenameParamName=filepath> [nopost|postparam1=foo&postparam2=bar... [event|stream|both|none [identifier ]]]"
SWITCH_STANDARD_API ( http_sendfile_function )
{
2014-01-23 12:21:41 +01:00
switch_status_t status = SWITCH_STATUS_FALSE ;
2013-02-28 14:32:50 -05:00
switch_bool_t new_memory_pool = SWITCH_FALSE ;
char * argv [ 10 ] = { 0 } , * argv2 [ 10 ] = { 0 } ;
int argc = 0 , argc2 = 0 ;
http_sendfile_data_t * http_data = NULL ;
switch_memory_pool_t * pool = NULL ;
switch_event_t * event = NULL ;
if ( zstr ( cmd ) )
{
status = SWITCH_STATUS_SUCCESS ;
goto http_sendfile_usage ;
}
if ( session )
{
pool = switch_core_session_get_pool ( session ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " We're using a session's memory pool for curl_sendfile. Maybe we should consider always making a new memory pool? \n " ) ;
}
else
{
switch_core_new_memory_pool ( & pool ) ;
new_memory_pool = SWITCH_TRUE ; // So we can properly destroy the memory pool
}
http_data = switch_core_alloc ( pool , sizeof ( http_sendfile_data_t ) ) ;
memset ( http_data , 0 , sizeof ( http_sendfile_data_t ) ) ;
http_data - > mydata = switch_core_strdup ( pool , cmd ) ;
http_data - > stream = stream ;
http_data - > pool = pool ;
// stream->write_function(stream,"\ncmd is %s\nmydata is %s\n", cmd, http_data->mydata);
if ( ( argc = switch_separate_string ( http_data - > mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) )
{
uint8_t i = 0 ;
if ( argc < 2 | | argc > 5 )
{
status = SWITCH_STATUS_SUCCESS ;
goto http_sendfile_usage ;
}
http_data - > url = switch_core_strdup ( pool , argv [ i + + ] ) ;
switch_url_decode ( argv [ i ] ) ;
argc2 = switch_separate_string ( argv [ i + + ] , ' = ' , argv2 , ( sizeof ( argv2 ) / sizeof ( argv2 [ 0 ] ) ) ) ;
if ( argc2 = = 2 )
{
http_data - > filename_element_name = switch_core_strdup ( pool , argv2 [ 0 ] ) ;
http_data - > filename_element = switch_core_strdup ( pool , argv2 [ 1 ] ) ;
}
else
goto http_sendfile_usage ;
switch_url_decode ( http_data - > filename_element_name ) ;
switch_url_decode ( http_data - > filename_element ) ;
if ( argc > 2 )
{
http_data - > extrapost_elements = switch_core_strdup ( pool , argv [ i + + ] ) ;
if ( argc > 3 )
{
if ( ! strncasecmp ( argv [ i ] , " event " , 5 ) )
switch_set_flag ( http_data , CSO_EVENT ) ;
else if ( ! strncasecmp ( argv [ i ] , " stream " , 6 ) )
switch_set_flag ( http_data , CSO_STREAM ) ;
else if ( ! strncasecmp ( argv [ i ] , " both " , 4 ) )
{
switch_set_flag ( http_data , CSO_EVENT ) ;
switch_set_flag ( http_data , CSO_STREAM ) ;
}
else
{
if ( strncasecmp ( argv [ i ] , " none " , 4 ) )
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Invalid 4th parameter set for curl_sendfile. Defaulting to \" none \" \n " ) ;
switch_set_flag ( http_data , CSO_NONE ) ;
}
i + + ;
if ( argc > 4 )
http_data - > identifier_str = switch_core_strdup ( pool , argv [ i + + ] ) ;
}
}
}
// We need to check the file now...
if ( http_sendfile_test_file_open ( http_data , event ) ! = SWITCH_STATUS_SUCCESS )
goto http_sendfile_done ;
switch_file_close ( http_data - > file_handle ) ;
switch_url_decode ( http_data - > url ) ;
http_sendfile_initialize_curl ( http_data ) ;
http_sendfile_success_report ( http_data , event ) ;
status = SWITCH_STATUS_SUCCESS ;
goto http_sendfile_done ;
http_sendfile_usage :
stream - > write_function ( stream , " -USAGE \n %s \n " , HTTP_SENDFILE_SYNTAX ) ;
goto http_sendfile_done ;
http_sendfile_done :
if ( http_data & & http_data - > headers )
{
switch_curl_slist_free_all ( http_data - > headers ) ;
}
if ( new_memory_pool = = SWITCH_TRUE )
{
switch_core_destroy_memory_pool ( & pool ) ;
}
return status ;
}
2009-07-01 20:03:48 +00:00
SWITCH_STANDARD_APP ( curl_app_function )
{
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2010-02-06 03:38:24 +00:00
2009-07-01 20:03:48 +00:00
char * argv [ 10 ] = { 0 } ;
int argc ;
char * mydata = NULL ;
2014-04-29 14:34:49 -04:00
switch_memory_pool_t * pool = switch_core_session_get_pool ( session ) ;
2009-07-01 20:03:48 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
char * url = NULL ;
2009-07-24 17:06:22 +00:00
char * method = NULL ;
char * postdata = NULL ;
2013-02-13 15:08:19 -05:00
char * content_type = NULL ;
2009-07-01 22:26:59 +00:00
switch_bool_t do_headers = SWITCH_FALSE ;
switch_bool_t do_json = SWITCH_FALSE ;
2009-07-01 20:03:48 +00:00
http_data_t * http_data = NULL ;
2011-11-29 15:35:36 -06:00
switch_curl_slist_t * slist = NULL ;
2009-07-01 22:26:59 +00:00
switch_stream_handle_t stream = { 0 } ;
2009-07-24 17:06:22 +00:00
int i = 0 ;
2013-07-30 16:35:46 +08:00
curl_options_t options = { 0 } ;
const char * curl_timeout ;
2010-02-06 03:38:24 +00:00
2009-07-01 20:03:48 +00:00
if ( ! ( mydata = switch_core_session_strdup ( session , data ) ) ) {
return ;
}
2010-02-06 03:38:24 +00:00
2009-07-01 20:03:48 +00:00
if ( ( argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) ) {
if ( argc = = 0 ) {
switch_goto_status ( SWITCH_STATUS_SUCCESS , usage ) ;
}
2010-02-06 03:38:24 +00:00
2009-07-01 22:26:59 +00:00
url = switch_core_strdup ( pool , argv [ 0 ] ) ;
2010-02-06 03:38:24 +00:00
for ( i = 1 ; i < argc ; i + + ) {
2009-07-24 17:06:22 +00:00
if ( ! strcasecmp ( " headers " , argv [ i ] ) ) {
2009-07-01 22:26:59 +00:00
do_headers = SWITCH_TRUE ;
2009-07-24 17:06:22 +00:00
} else if ( ! strcasecmp ( " json " , argv [ i ] ) ) {
2009-07-01 22:26:59 +00:00
do_json = SWITCH_TRUE ;
2010-02-06 03:38:24 +00:00
} else if ( ! strcasecmp ( " get " , argv [ i ] ) | | ! strcasecmp ( " head " , argv [ i ] ) ) {
2009-07-24 17:06:22 +00:00
method = switch_core_strdup ( pool , argv [ i ] ) ;
} else if ( ! strcasecmp ( " post " , argv [ i ] ) ) {
2010-09-01 07:00:33 -05:00
method = " post " ;
2010-02-06 03:38:24 +00:00
if ( + + i < argc ) {
2009-07-24 17:06:22 +00:00
postdata = switch_core_strdup ( pool , argv [ i ] ) ;
switch_url_decode ( postdata ) ;
} else {
postdata = " " ;
}
2014-07-31 02:29:02 +00:00
} else if ( ! strcasecmp ( " delete " , argv [ i ] ) ) {
method = " delete " ;
if ( + + i < argc ) {
postdata = switch_core_strdup ( pool , argv [ i ] ) ;
switch_url_decode ( postdata ) ;
} else {
postdata = " " ;
}
2014-07-04 01:48:13 +00:00
} else if ( ! strcasecmp ( " put " , argv [ i ] ) ) {
method = " put " ;
if ( + + i < argc ) {
postdata = switch_core_strdup ( pool , argv [ i ] ) ;
switch_url_decode ( postdata ) ;
} else {
postdata = " " ;
}
2013-02-13 15:08:19 -05:00
} else if ( ! strcasecmp ( " content-type " , argv [ i ] ) ) {
if ( + + i < argc ) {
content_type = switch_core_strdup ( pool , argv [ i ] ) ;
}
2009-07-01 22:26:59 +00:00
}
2009-07-01 20:03:48 +00:00
}
}
2010-02-06 03:38:24 +00:00
2013-07-30 16:35:46 +08:00
curl_timeout = switch_channel_get_variable ( channel , " curl_connect_timeout " ) ;
if ( curl_timeout ) options . connect_timeout = atoi ( curl_timeout ) ;
curl_timeout = switch_channel_get_variable ( channel , " curl_timeout " ) ;
if ( curl_timeout ) options . timeout = atoi ( curl_timeout ) ;
http_data = do_lookup_url ( pool , url , method , postdata , content_type , & options ) ;
2009-07-01 22:26:59 +00:00
if ( do_json ) {
switch_channel_set_variable ( channel , " curl_response_data " , print_json ( pool , http_data ) ) ;
} else {
SWITCH_STANDARD_STREAM ( stream ) ;
2009-12-11 01:20:26 +00:00
if ( do_headers ) {
2009-07-01 22:26:59 +00:00
slist = http_data - > headers ;
2010-02-06 03:38:24 +00:00
while ( slist ) {
2009-07-01 22:26:59 +00:00
stream . write_function ( & stream , " %s \n " , slist - > data ) ;
slist = slist - > next ;
}
stream . write_function ( & stream , " \n " ) ;
}
stream . write_function ( & stream , " %s " , http_data - > http_response ? http_data - > http_response : " " ) ;
switch_channel_set_variable ( channel , " curl_response_data " , stream . data ) ;
}
2010-02-06 03:38:24 +00:00
switch_channel_set_variable ( channel , " curl_response_code " , switch_core_sprintf ( pool , " %ld " , http_data - > http_response_code ) ) ;
2009-07-24 17:06:22 +00:00
switch_channel_set_variable ( channel , " curl_method " , method ) ;
2009-07-01 20:03:48 +00:00
switch_goto_status ( SWITCH_STATUS_SUCCESS , done ) ;
2010-02-06 03:38:24 +00:00
usage :
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Usage: %s \n " , SYNTAX ) ;
2009-07-01 20:03:48 +00:00
switch_goto_status ( status , done ) ;
2010-02-06 03:38:24 +00:00
done :
2009-07-01 22:26:59 +00:00
switch_safe_free ( stream . data ) ;
2009-07-02 15:23:54 +00:00
if ( http_data & & http_data - > headers ) {
2011-11-29 15:35:36 -06:00
switch_curl_slist_free_all ( http_data - > headers ) ;
2009-07-02 15:23:54 +00:00
}
2009-07-02 15:29:25 +00:00
if ( ! session & & pool ) {
2009-07-01 20:03:48 +00:00
switch_core_destroy_memory_pool ( & pool ) ;
}
}
2010-02-06 03:38:24 +00:00
2009-07-01 20:03:48 +00:00
SWITCH_STANDARD_API ( curl_function )
{
switch_status_t status ;
char * argv [ 10 ] = { 0 } ;
int argc ;
char * mydata = NULL ;
char * url = NULL ;
2009-07-24 17:06:22 +00:00
char * method = NULL ;
char * postdata = NULL ;
2013-02-13 15:08:19 -05:00
char * content_type = NULL ;
2009-07-01 22:26:59 +00:00
switch_bool_t do_headers = SWITCH_FALSE ;
switch_bool_t do_json = SWITCH_FALSE ;
2011-11-29 15:35:36 -06:00
switch_curl_slist_t * slist = NULL ;
2009-07-01 20:03:48 +00:00
http_data_t * http_data = NULL ;
2009-07-24 17:06:22 +00:00
int i = 0 ;
2009-07-01 20:03:48 +00:00
switch_memory_pool_t * pool = NULL ;
2014-03-03 22:58:45 +05:00
curl_options_t options = { 0 } ;
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( cmd ) ) {
2009-07-01 20:03:48 +00:00
switch_goto_status ( SWITCH_STATUS_SUCCESS , usage ) ;
}
if ( session ) {
pool = switch_core_session_get_pool ( session ) ;
} else {
switch_core_new_memory_pool ( & pool ) ;
}
mydata = strdup ( cmd ) ;
if ( ( argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) ) {
if ( argc < 1 ) {
switch_goto_status ( SWITCH_STATUS_SUCCESS , usage ) ;
}
2010-02-06 03:38:24 +00:00
2009-07-01 20:03:48 +00:00
url = switch_core_strdup ( pool , argv [ 0 ] ) ;
2010-02-06 03:38:24 +00:00
for ( i = 1 ; i < argc ; i + + ) {
2009-07-24 17:06:22 +00:00
if ( ! strcasecmp ( " headers " , argv [ i ] ) ) {
2009-07-01 22:26:59 +00:00
do_headers = SWITCH_TRUE ;
2009-07-24 17:06:22 +00:00
} else if ( ! strcasecmp ( " json " , argv [ i ] ) ) {
2009-07-01 22:26:59 +00:00
do_json = SWITCH_TRUE ;
2010-02-06 03:38:24 +00:00
} else if ( ! strcasecmp ( " get " , argv [ i ] ) | | ! strcasecmp ( " head " , argv [ i ] ) ) {
2009-07-24 17:06:22 +00:00
method = switch_core_strdup ( pool , argv [ i ] ) ;
} else if ( ! strcasecmp ( " post " , argv [ i ] ) ) {
method = " post " ;
2010-02-06 03:38:24 +00:00
if ( + + i < argc ) {
2014-07-04 01:48:13 +00:00
postdata = switch_core_strdup ( pool , argv [ i ] ) ;
switch_url_decode ( postdata ) ;
} else {
postdata = " " ;
}
2014-07-31 02:29:02 +00:00
} else if ( ! strcasecmp ( " delete " , argv [ i ] ) ) {
method = " delete " ;
if ( + + i < argc ) {
postdata = switch_core_strdup ( pool , argv [ i ] ) ;
switch_url_decode ( postdata ) ;
} else {
postdata = " " ;
}
2014-07-04 01:48:13 +00:00
} else if ( ! strcasecmp ( " put " , argv [ i ] ) ) {
method = " put " ;
if ( + + i < argc ) {
2009-07-24 17:06:22 +00:00
postdata = switch_core_strdup ( pool , argv [ i ] ) ;
2013-02-15 14:47:49 -05:00
switch_url_decode ( postdata ) ;
2009-07-24 17:06:22 +00:00
} else {
postdata = " " ;
}
2013-02-13 15:08:19 -05:00
} else if ( ! strcasecmp ( " content-type " , argv [ i ] ) ) {
if ( + + i < argc ) {
content_type = switch_core_strdup ( pool , argv [ i ] ) ;
}
2014-11-16 19:16:39 +00:00
} else if ( ! strcasecmp ( " connect-timeout " , argv [ i ] ) ) {
if ( + + i < argc ) {
int tmp = atoi ( argv [ i ] ) ;
if ( tmp > 0 ) {
options . connect_timeout = tmp ;
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Invalid connect-timeout! \n " ) ;
}
}
2014-03-03 22:58:45 +05:00
} else if ( ! strcasecmp ( " timeout " , argv [ i ] ) ) {
if ( + + i < argc ) {
int tmp = atoi ( argv [ i ] ) ;
if ( tmp > 0 ) {
2014-11-16 19:20:07 +00:00
options . timeout = tmp ;
2014-03-03 22:58:45 +05:00
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Invalid timeout! \n " ) ;
}
}
2009-07-01 20:03:48 +00:00
}
}
2010-02-06 03:38:24 +00:00
2014-03-03 22:58:45 +05:00
http_data = do_lookup_url ( pool , url , method , postdata , content_type , & options ) ;
2009-07-01 22:26:59 +00:00
if ( do_json ) {
stream - > write_function ( stream , " %s " , print_json ( pool , http_data ) ) ;
} else {
2009-12-11 01:20:26 +00:00
if ( do_headers ) {
2009-07-01 22:26:59 +00:00
slist = http_data - > headers ;
2010-02-06 03:38:24 +00:00
while ( slist ) {
2009-07-01 22:26:59 +00:00
stream - > write_function ( stream , " %s \n " , slist - > data ) ;
slist = slist - > next ;
}
stream - > write_function ( stream , " \n " ) ;
2009-07-01 20:03:48 +00:00
}
2009-07-01 22:26:59 +00:00
stream - > write_function ( stream , " %s " , http_data - > http_response ? http_data - > http_response : " " ) ;
2009-07-01 20:03:48 +00:00
}
}
switch_goto_status ( SWITCH_STATUS_SUCCESS , done ) ;
2010-02-06 03:38:24 +00:00
usage :
2009-07-01 20:03:48 +00:00
stream - > write_function ( stream , " -ERR \n %s \n " , SYNTAX ) ;
switch_goto_status ( status , done ) ;
2010-02-06 03:38:24 +00:00
done :
2009-07-02 15:23:54 +00:00
if ( http_data & & http_data - > headers ) {
2011-11-29 15:35:36 -06:00
switch_curl_slist_free_all ( http_data - > headers ) ;
2009-07-02 15:23:54 +00:00
}
2009-07-01 20:03:48 +00:00
switch_safe_free ( mydata ) ;
2009-07-02 15:29:25 +00:00
if ( ! session & & pool ) {
2009-07-01 20:03:48 +00:00
switch_core_destroy_memory_pool ( & pool ) ;
}
return status ;
}
/* Macro expands to: switch_status_t mod_cidlookup_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */
SWITCH_MODULE_LOAD_FUNCTION ( mod_curl_load )
{
switch_api_interface_t * api_interface ;
switch_application_interface_t * app_interface ;
2015-09-21 18:00:14 -05:00
if ( switch_event_reserve_subclass ( HTTP_SENDFILE_ACK_EVENT ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't register subclass %s! \n " , HTTP_SENDFILE_ACK_EVENT ) ;
return SWITCH_STATUS_TERM ;
}
2009-07-01 20:03:48 +00:00
/* connect my internal structure to the blank pointer passed to me */
* module_interface = switch_loadable_module_create_module_interface ( pool , modname ) ;
memset ( & globals , 0 , sizeof ( globals ) ) ;
2010-02-06 03:38:24 +00:00
2009-07-01 20:03:48 +00:00
globals . pool = pool ;
SWITCH_ADD_API ( api_interface , " curl " , " curl API " , curl_function , SYNTAX ) ;
SWITCH_ADD_APP ( app_interface , " curl " , " Perform a http request " , " Perform a http request " ,
2009-09-18 22:55:33 +00:00
curl_app_function , SYNTAX , SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC ) ;
2013-02-28 14:32:50 -05:00
SWITCH_ADD_API ( api_interface , " curl_sendfile " , " curl_sendfile API " , http_sendfile_function , HTTP_SENDFILE_SYNTAX ) ;
SWITCH_ADD_APP ( app_interface , " curl_sendfile " , " Send a file and some optional post variables via HTTP " , " Send a file and some optional post variables via HTTP " ,
http_sendfile_app_function , HTTP_SENDFILE_APP_SYNTAX , SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC ) ;
2009-07-01 20:03:48 +00:00
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS ;
}
/*
Called when the system shuts down
Macro expands to : switch_status_t mod_cidlookup_shutdown ( ) */
SWITCH_MODULE_SHUTDOWN_FUNCTION ( mod_curl_shutdown )
{
2015-09-21 18:00:14 -05:00
switch_event_free_subclass ( HTTP_SENDFILE_ACK_EVENT ) ;
2009-07-01 20:03:48 +00:00
/* Cleanup dynamically allocated config settings */
return SWITCH_STATUS_SUCCESS ;
}
/* For Emacs:
* Local Variables :
* mode : c
* indent - tabs - mode : t
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
2013-06-25 11:50:17 -05:00
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 noet
2009-07-01 20:03:48 +00:00
*/