How To Escape The & In BackGround

Home » Asterisk Users » How To Escape The & In BackGround
Asterisk Users 11 Comments

Hi,

I am trying to play a sound file from AWS S3. The URL is something like this http://example.org?foo

11 thoughts on - How To Escape The & In BackGround

  • Does asterisk follow HTTP redirects? If so can you use something like tinyurl.com to produce an alternative URL?

    Or, base64 encode the URL, and then set a variable with Set(url=${BASE64_DECODE(${encodedURL})) ?

    Cheers, Kingsley.

  • Does asterisk follow HTTP redirects? If so can you use something like tinyurl.com to produce an alternative URL?

    Or, base64 encode the URL, and then set a variable with Set(url=${BASE64_DECODE(${encodedURL})) ?

    Cheers, Kingsley.

  • I’m (pretty) sure that that would work.

    The other similar idea I had was to use a reverse proxy server to accept an Asterisk-compatible URL and convert it into whatever the outisde world requires.

    No, doesn’t work – I tried several things yesterday to see if I could get this to work, and you don’t even need to use Base64 en/de-coding – you can set an Asterisk variable to the URL including the &, and then pass that to the Background() command, and it fails.

    I tried it pointing to a web server I run, so I can see the requests which are sent, and a ? gets through, but a & doesn’t. Converting it to %26 simply sends that through as-is, which fails at the web server end.

    So, I think this is a bug/feature-fail in Asterisk, which can’t be worked around.

    Antony.


    “In fact I wanted to be John Cleese and it took me some time to realise that the job was already taken.”

    – Douglas Adams

    Please reply to the list;
    please *don’t* CC me.

  • Or alternately, download the file, rename it, and then use it. I do this in some cases with MP3s that MP3Player() doesn’t play but Playback()
    will, or if files need to be processed before they can be played. I think some helpful context is required as to the way text parsing and applications work in Asterisk, as there seems to be a lack of understanding at how the dialplan parses things.

    1. Doing fancy things with variables and encoding is not going to work. Asterisk works differently from other languages and this can be hard to understand from a different background, where stronger notions of strings and variables exist. When an application call is made, the PBX
    core does variable substitution on the data contents (this also includes function calls). Let’s go through two examples:

    same => n,Background(${BASE64_DECODE(wsghosrghodrhgo)})

    The BASE64_DECODE function is evaluated before Background() even sees any of the contents of what was there.

    same => n,Background(${myvar})

    Likewise, the myvar variable is evaluated by the variable substituter before Background() itself is invoked.

    Background has *nothing* to do with variables or function calls –
    absolutely nothing. No matter what you do, this is what Background will see – after all function calls and variables have been resolved:
    same => n,Background(https://example.com/myurl?query=something)

    This is not like a typical programming language, where you pass a
    “variable” into a “function” (application), like Background, which then
    “evaluates” it. Applications generally don’t individually load and parse variables (though some functions do, and there are a few exceptions for applications, but these do extra work to do that). All they see is the end-result of evaluated data. Generally, this is desirable behavior; we wouldn’t want each application itself to be individually responsible for evaluating functions and variables passed into it. Background doesn’t have any fancy logic that will resolve any variables or functions. This is all done by the PBX core *before* the application is invoked.

    If that didn’t make sense, this might be more clear:
    same => n,GotoIf($[${somevar}=${somevar2}]&$[“1″=”2″|”3″=”4”]]?true:false)

    GotoIf never sees any of that. What to GotoIf sees is basically this:
    GotoIf(1?true:false) or GotoIf(0?true:false)

    Another way to think of it is like macros in C. All of your #define’s don’t exist in the final compiled program; those all get replaced by the specified values. Likewise, dialplan applications never see your variables. They just see the data after all those things are resolved. In this case, if you think of every dialplan call as a compilation, the variable substituter (preprocessor) converts everything down to raw data before the action actually starts.

    That brings me to my next point:

    2. Background, as do many applications in Asterisk, uses strsep on the &
    delimeter to delimit files for playback. You can look at the code yourself here:
    https://github.com/asterisk/asterisk/blob/master/main/pbx_builtins.c#L1237

    strsep does not handle escaping. It is a very simple C function. There is *nothing* you can do that will make it work – might as well stop wasting time trying. strsep will simply cut on the delimeter. There is nothing more, nothing less.

    There are only two solutions to your problem here:

    1) Whatever you pass *into* Background cannot have an & unless it’s a delimeter. Trying to “hide” the & using variables, functions, etc. won’t work, because it’ll just appear in the end after those are all resolved. The actual file needs to be a URL without an & or a renamed file on disk. In either case, the dialplan never sees the &. That’s what matters.

    2) The code for Background, and any other applications, would need to modified to use a parsing function that supports escaping. There are places in Asterisk where this is done, but the audio-related applications aren’t among them. It’s not hard, but somebody would need to make the changes to do this. That might also have other unanticipated side effects.

    Personally, I think you are better off going with option 1, either proxying or downloading the file as suggested. Just my two cents.

    NA

  • I have been using system commands in my dialplan for years and the &
    goes through and puts the process in background like it should, asterisk does not do anything, so you are left with what the shell does.


    Your life is like a penny. You’re going to lose it. The question is:
    How do you spend it?

    John Covici wb2una
    covici@ccs.covici.com

  • That’s completely different from trying to put an & into the Background() or Playback() commands, where Asterisk does treat the symbol specially.

    Antony.


    +++ Divide By Cucumber Error. Please Reinstall Universe And Reboot +++

    Please reply to the list;
    please *don’t* CC me.