[Home]

Summary:ASTERISK-16718: [patch] func_uri could use a QSFIELD function to parse x-www-form-urlencoded data
Reporter:Walter Doekes (wdoekes)Labels:
Date Opened:2010-09-23 10:18:52Date Closed:2011-02-08 14:04:38.000-0600
Priority:MajorRegression?No
Status:Closed/CompleteComponents:Functions/func_uri
Versions:Frequency of
Occurrence
Related
Issues:
Environment:Attachments:( 0) issue18037_func_uri_qsfield-1.6.2.13.patch
Description:Hi,

I've added a QSFIELD function to func_uri.c to get fields from a querystring. I thought this would be an acceptable way to read an ordered dictionary gotten through e.g. func_curl.


[Synopsis]
Gets a single field from a application/x-www-form-urlencoded query string.


[Description]
Returns the URI-decoded content from the <index>-th field with name <field>
from query string found in variable <varname>.

[Syntax]
QSFIELD(varname,field[,index])


Example:

exten => _IDX!,n,Set(qsdata=field1=pe%20%25%40%26%3dna&field1=pe+na2&field2=pena3)
exten => _IDX!,n,NoOp(qsdata is ${qsdata})
exten => _IDX!,n,NoOp(qstest ${QSFIELD(qsdata,field1,-1)})
exten => _IDX!,n,NoOp(qstest ${QSFIELD(qsdata,field2,-1)})
exten => _IDX!,n,NoOp(qstest ${QSFIELD(qsdata,field1,0)})
exten => _IDX!,n,NoOp(qstest ${QSFIELD(qsdata,field2,0)})
exten => _IDX!,n,NoOp(qstest ${QSFIELD(qsdata,field1,1)})
exten => _IDX!,n,NoOp(qstest ${QSFIELD(qsdata,field2,1)})

Set("qsdata=field1=pe%20%25%40%26%3dna&field1=pe+na2&field2=pena3")
NoOp("qsdata is field1=pe%20%25%40%26%3dna&field1=pe+na2&field2=pena3")
NoOp("qstest pe na2")
NoOp("qstest pena3")
NoOp("qstest pe %@&=na")
NoOp("qstest pena3")
NoOp("qstest pe na2")
NOTICE[4224]: func_uri.c:243 qsfield: Field field2= not found in query string from qsdata on requested index
NoOp("qstest ")
Comments:By: Walter Doekes (wdoekes) 2010-09-23 10:20:43

I could understand it if it's a bit too specific for inclusion.

Regards,
Walter Doekes
OSSO B.V.

By: Leif Madsen (lmadsen) 2010-09-23 10:53:12

I guess I just wish I knew what this was useful for :)

By: Walter Doekes (wdoekes) 2010-09-23 11:22:52

Hahaha. Okay, here an example:

Set(url=${FUNCTION_TO_GET_URL_TEMPLATE()}) ;; e.g. http://example.com/?did={did}&callerid={callerid}
Set(url=${STRREPLACE(url,"{did}","${EXTEN}")})
Set(url=${STRREPLACE(url,"{callerid}","${CALLERID(num)}")})
Set(qs=${CURL(url)}) ;; e.g. timeout=10&destination=%2B123456789
Set(timeout=${QSFIELD(qs,timeout)})
Set(destination=${QSFIELD(qs,destination)})
Dial(SIP/trunk/${destination},${timeout})

By: Walter Doekes (wdoekes) 2010-09-23 14:05:59

Hah, who's laughing now? I just found out a little hashcompat CURLOPT and HASH() accomplishes approximately the same. (QSFIELD is more versatile and properly decodes +'es to spaces, but for the aformentioned purpose, the existing curl functionality suffices.)

Well, that makes it even less likely to get included then ;P

For the record:

Set(CURLOPT(hashcompat)=1)
Set(HASH(qs)=${CURL(${url})})
Set(timeout=${HASH(qs,timeout)})
Set(destination=${HASH(qs,destination)})

By: Leif Madsen (lmadsen) 2010-10-01 14:39:46

Do you still want to consider this as something to include, or are you happy with the way you've solved the problem?

John, Russell, and myself don't quite understand what this is trying to do. Perhaps we need a "dumbed down" example :D

By: Walter Doekes (wdoekes) 2010-10-02 11:09:23

It depends a bit on whether a patch from https://issues.asterisk.org/view.php?id=18046 is included or not. Tilghman and I disagree a bit about the usefulness of decoding (the widely used) x-www-form-urlencoded data (where spaces are encoded as pluses).

What it/I'm trying to do is simple: I just need to get a small dictionary of data from the customer. (In my case using a HTTP GET request, so x-www-form-urlencoding is by far the simplest encoding scheme for the customer and myself.)

For my purposes I would need either the hashcompat-mode of CURLOPT to be tweaked, or this QSFIELD function.

Now, this QSFIELD function is more versatile (the dictionary source needn't be a CURL request and it supports duplicate keys), but the advantages over the CURLOPT method will probably not be needed by anyone. So, tweaking the hashcompat-mode seems like the least intrusive / to be preferred method.

But, if this stands a chance of being included while the CURLOPT patch isn't, then I'd rather go with this one. (I really like to keep my patches down to a minimum.)


(There is a third solution: I could get the unparsed data using CURL, STRREPLACE the pluses with spaces (or %20) and finally run a (to be created) function that does what CURLOPT(hashcompat)=yes does. But I'm not sure how desirable that is.)

By: Walter Doekes (wdoekes) 2011-01-07 13:21:44.000-0600

Ok. ASTERISK-16727 has resulted in a commit. Feel free to close this one.

Thanks.

By: Leif Madsen (lmadsen) 2011-02-08 14:04:28.000-0600

Thanks for the feedback! Closing this issue.