Trouble parsing multiline AGI response

Hi everyone,

I’m writing a PHP library for interacting with AGI and I’m having trouble parsing multiline responses from Asterisk.

Since most AGI commands create single-line responses from Asterisk, I had no problem until now. I’d simply use fgets() to grab the line and I’d check that it has at least 3 characters (for the status code). If the line was shortener, I knew that I was done reading.

The problem I’m currently facing is that I want to be able to read multi-line AGI responses. For example, the following command would return a multi-line response:

Command:

GET FULL VARIABLE "${CURL(http://domain.com/test.txt)}"

Response from Asterisk:

<PJSIP/6001-0000000a>AGI Rx << GET FULL VARIABLE "${CURL(http://domain.com/test.txt)}"
<PJSIP/6001-0000000a>AGI Tx >> 200 result=1 (<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>)

The thing is I don’t know up until where I should read data:

  • I cannot stop reading at a newline character (since the response may contain newline chars)
  • I cannot stop reading at EOF (because apparently there is no EOF char sent)

Here’s an idea I’ve had, although not optimal:

  • Read the first line and check for a known pattern ( 200 result=0 for example). Then, continue reading lines and append the data if the lines do NOT have the same pattern at the beginning of the string. What if this pattern is part of the CURL response for example ?

Do you see any way to detect the end of the message sent by Asterisk ? Have any of you had to deal with this kind of responses ?

Regards.


Edit: I think I might have found a way but it really feels hacky:

If after each command I could also send the following command:

<PJSIP/6001-00000011>AGI Rx << GET FULL VARIABLE "separator"
<PJSIP/6001-00000011>AGI Tx >> 200 result=1 (separator)

I could use it as an End-of-message marker and strip in from the response (since its content is predictable).

I’d still prefer to find a real solution because this involves sending and receiving more data that I fell is necessary.

EOF isn’t a character! EOF would be closing the pipe.

I think the only way you could detect would be with a timeout. I don’t think Asterisk is generally happy with variables containing newline characters.

You’re right about EOF, sorry.

Since Asterisk provides functions that may return multiline data, I would expect it to handle such cases. I believe some kind of End-of-message marker would be appropriate.

I’ll try handling this with a timeout. Thanks for your input.

I don’t think AGI was envisioned to encounter such a scenario, so it’s likely broken within the protocol itself.

Thank you for your reply @jcolp. I ended up patching res_agi.c to inject an ETX character after each message to serve as an End-of-message marker because the timeout method felt slightly unreliable, specifically in the context of CURL requests.

Are you guys open to changes to AGI ? I’d be happy to share my patch if that is the case.

Any changes that go up for review are reviewed. From a general inclusion perspective, it depends on the actual patch and the impact of it.

Alright, will look into this. Thanks again.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.