Mod curl

From FreeSWITCH Wiki
(Redirected from Mod http)
Jump to: navigation, search

Contents

mod_curl (HTTP request API)

mod_curl allows one to make a http request and receive the response. Output can be plain text (headers optional) or a json object.

Installing

To use mod_curl:

Tell FreeSWITCH to compile in this module by editing modules.conf in /usr/src/freeswitch/trunk and uncomment:

#applications/mod_curl

Now go recompile FreeSWITCH.

make
make install

Tell FreeSWITCH to actually use the curl module when running by adding the module to modules.conf.xml in /usr/local/freeswitch/conf/autoload_configs:

<load module="mod_curl"/>

There is no separate config file for mod_curl.

Now load up FreeSWITCH!

mod_curl provides both an API call and a dialplan application for the following:

curl - allows you to query arbitrary data from a web server
curl_sendfile - allows you to transmit an arbitrary along with arbitrary additional data elements to a web server/REST and optionally receive a report back.

See below for further information.

Application

The syntax for the curl application is:

<action application="curl" data="url [headers|json] [get|head|post [url_encode_data]]"/>

The curl application sets the variables curl_response_data and curl_response_code. curl_response_data can also be headers/body or json if requested.

<action application="curl" data="http://www.google.com"/>
<action application="info"/>
<action application="curl" data="http://www.google.com headers"/>
<action application="info"/>
<action application="curl" data="http://www.google.com json"/>
<action application="info"/>


The syntax for the curl_sendfile is either of the following two options:

<action application="curl_sendfile" data="<url> <filename_post_name=/path/to/filename [nopost|foo1=bar1&foo2=bar2&...fooN=barN [event|none [uuid|identifier]]]"/>

or an example of using the channel variable method:

<action application="set" data="curl_sendfile_report=event"/>
<action application="set" data="curl_sendfile_url=http://www.mydomain.com/test_files.php"/>
<action application="set" data="curl_sendfile_filename_element=myFile"/>
<action application="set" data="curl_sendfile_filename=/tmp/somefile.dmp"/>
<action application="set" data="curl_sendfile_extrapost=foo1=bar1&foo2=bar2&testing=a%20pain%20in%20the%20rear"/>
<action application="set" data="curl_sendfile_identifier=1234567890"/>
<action application="curl_sendfile"/>

You do need to urlencode the _url, _filename, _extrapost channel variables or data="" parameters. If you call the application and provide the parameters on the data="" parameter, you must specify 'nopost' if you have no additional post elements to add and wish to specify further parameters on the data line. If you specify 'uuid' for the identifier, the application will automatically use the session's uuid as the value here.

CLI / API

The CLI uses the api interface. The syntax for the curl API call is:

curl url [headers|json] [get|head|post [url_encode_data]]

From the commandline line issue:

curl http://www.google.com

This will return google's home page.

curl http://www.google.com/ headers

Will give you the headers followed by the body. And

curl http://www.google.com/ json

Will give you the headers and body in a structured json stream.

Send POST and GET request.

curl http://www.myhost.com/?get=myGetValue
curl http://www.myhost.com post post=myPostValue%20a%20space

Mix with headers or JSON.

curl http://www.myhost.com/?get=myGetValue json
curl http://www.myhost.com headers post post=myPostValue%20a%20space


The syntax for the curl_sendfile API call is:

[api/bgapi] curl_sendfile <url> <filenameParamName=filepath> [nopost|postparam1=foo&postparam2=bar... [event|stream|both|none  [identifier ]]]

<url> : This is the urlencoded URL of the REST that we are sending to. It should contain the whole GET parameters that are needed, such as a specific script or application URL that will handle the processing.

<filenameParamName=filepath> : This is a key=value pair. The key is the name you wish to label this POST form element as. The value is the full path to the file you wish to transmit bound to this POST form element.

nopost|postparam1=foo&postparam2=bar... : If you wish to specify an additional set of text POST form elements, you can provide a urlencoded key=value pair string that contains them. The key is the label of the POST form element, and the value is the actual value to bind. Thus to have a POST element named jabba with a value of nobotha, specify jabba=nobotha. Additional post elements must delimit the key=value pair with a &, as you would on a GET. If you wish to attach no additional post elements, simply specify nopost.

event|stream|both|none : This parameter will determine how and where to display the output from the REST. If you specify event, it will attach the output to a custom event labeled curl_sendfile::ack and fire it off. If you specify stream, it will output to the active stream which is whichever method was used to execute the call from. If you specify both, it will fire the custom event with the output, as well as display out to the active stream. If you specify none, then no output besides +HTTP_STATUS_CODE Ok or -HTTP_STATUS_CODE Err will be displayed.

identifier : This parameter is simply an arbitrary identifier for your own purposes. It will only apply to the custom curl_sendfile::ack event, and will display there in the event header as Command-Execution-Identifier . You can use this value to track the results of your commands for completion or error statuses.

If you wish to provide the identifier value, you *must* provide the prior two optional parameters or else your command will not be parsed correctly. If you specify a reporting method that provides an event, the custom event is named curl_sendfile::ack.

Lua Usage

Note: it is good practice to check session:ready() before any long function calls such as a HTTP request so that your script stops running and releases its resources as soon as possible if the call is hung up.

This shows how to do a GET request:

session:execute("curl", "http://www.myhost.com/?name1=value1&name2=value2")
curl_response_code = session:getVariable("curl_response_code")
curl_response      = session:getVariable("curl_response_data")

This shows how to do a POST request:

session:execute("curl", "http://www.myhost.com/ post name1=value1&name2=value2")
curl_response_code = session:getVariable("curl_response_code")
curl_response      = session:getVariable("curl_response_data")

You can also use the API interface:

api = freeswitch.API();
get_response = api:execute("curl", "http://www.myhost.com/?name1=value1&name2=value2")
post_response = api:execute("curl", "http://www.myhost.com/ post name1=value1&name2=value2")

In all the above examples, the submitted values must be URL encoded.

Submit:
 first  = "a short value"
 second = "a slightly longer value"
as:
 first=a%20short%20value&second=a%20slightly%20longer%20value

This shows one method of encoding parameters to form a GET/POST request: (or use CGILua's urlcode)

function codificaParametros(paramsT)
	function escape (s)
	  s = string.gsub(
		s, 
		'([\r\n"#%%&+:;<=>?@^`{|}%\\%[%]%(%)$!~,/\'])', 
		function (c)
			return '%'..string.format("%X", string.byte(c))
		end
	)
	  s = string.gsub(s, "%s", "+")
	  return s
	end

	function encode (t)
	  local s = ""
	  for k , v in pairs(t) do
		s = s .. "&" .. escape(k) .. "=" .. escape(v)
	  end
	  return string.sub(s, 2)     -- remove first `&'
	end
	
	if type(paramsT) == 'table' then
		return encode(paramsT)
	else
		local tmp = Utils:commaText(paramsT, '&'); 
		local myParamsT = {};
		for k, v in pairs(tmp) do
			local pos = 0
			pos = string.find(v, '=')
			if not pos then return '' end
			myParamsT[string.sub(v, 1, pos-1 )] = string.sub(v, pos+1 )
		end
		return encode(myParamsT)
	end
end

 
 local paramsT  = {
    param1 = 'valor1',
    param2 = '\nh@la<>?'
 }
 local encode = codificaParametros (paramsT)
 session:answer()
 print (string.format("\n%s\n", encode));
--param1=valor1&param2=%Ah%40la%3C%3E%3F
 session:hangup();

If you want to pass basic authentication credentials then do this

local auth_url = "http://username:password@mysecure_web_service.com"
local response = api:execute("curl", auth_url)