From 04aba2dbed82d6c2d317ab06872865203dad8e16 Mon Sep 17 00:00:00 2001 From: rizzo Date: Tue, 17 Oct 2006 17:51:34 +0000 Subject: Improve the XML formatting of responses coming from web interface. Normal responses are sequences of lines of the form "Name: value", with \r\n as line terminators and an empty line as a response terminator. Generi CLI commands, however, do not have such a clean formatting, and the existing code failed to generate valid XML for them. Obviously we can only use heuristics here, and we do the following: - accept either \r or \n as a line terminator, trimming trailing whitespace; - if a line does not have a ":" in it, assume that from this point on we have unformatted data, and use "Opaque-data:" as a name; - if a line does have a ":" in it, the Name field is not always a legal identifier, so replace non-alphanum characters with underscores; All the above is to be refined as we improve the formatting of responses from the CLI. And, all the above ought to go as a comment in the code rather than just in a commit message... git-svn-id: http://svn.digium.com/svn/asterisk/trunk@45334 f38db490-d61c-443f-a65b-d21fe96a405b --- main/manager.c | 76 ++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 29 deletions(-) (limited to 'main') diff --git a/main/manager.c b/main/manager.c index 85210cc76..5e50d09b2 100644 --- a/main/manager.c +++ b/main/manager.c @@ -296,7 +296,7 @@ static char *xml_translate(char *in, struct ast_variable *vars) int colons = 0; int breaks = 0; size_t len; - int count = 1; + int in_data = 0; /* parsing data */ int escaped = 0; int inobj = 0; int x; @@ -311,6 +311,11 @@ static char *xml_translate(char *in, struct ast_variable *vars) dest = "unknown"; if (!objtype) objtype = "generic"; + + /* determine how large is the response. + * This is a heuristic - counting colons (for headers), + * newlines (for extra arguments), and escaped chars. + */ for (x = 0; in[x]; x++) { if (in[x] == ':') colons++; @@ -322,39 +327,52 @@ static char *xml_translate(char *in, struct ast_variable *vars) len = (size_t) (strlen(in) + colons * 5 + breaks * (40 + strlen(dest) + strlen(objtype)) + escaped * 10); /* foo="bar", "= 32)) - in++; - if (*in) { - if ((count > 3) && inobj) { - ast_build_string(&tmp, &len, " />\n"); - inobj = 0; + /* we want to stop when we find an empty line */ + while (in && *in) { + in = ast_skip_blanks(in); /* trailing \n from before */ + val = strsep(&in, "\r\n"); /* mark start and end of line */ + ast_trim_blanks(val); + ast_verbose("inobj %d in_data %d line <%s>\n", inobj, in_data, val); + if (ast_strlen_zero(val)) { + if (in_data) { /* close data */ + ast_build_string(&tmp, &len, "'"); + in_data = 0; } - count = 0; - while (*in && (*in < 32)) { - *in = '\0'; - in++; - count++; + ast_build_string(&tmp, &len, " />\n"); + inobj = 0; + continue; + } + /* we expect Name: value lines */ + if (in_data) { + var = NULL; + } else { + var = strsep(&val, ":"); + if (val) { /* found the field name */ + val = ast_skip_blanks(val); + ast_trim_blanks(var); + } else { /* field name not found, move to opaque mode */ + val = var; + var = "Opaque-data"; } - val = strchr(var, ':'); - if (val) { - *val = '\0'; - val++; - if (*val == ' ') - val++; - if (!inobj) { - ast_build_string(&tmp, &len, "<%s", dest, objtype); - inobj = 1; - } - ast_build_string(&tmp, &len, " "); - xml_copy_escape(&tmp, &len, var, 1); - ast_build_string(&tmp, &len, "='"); - xml_copy_escape(&tmp, &len, val, 0); + } + if (!inobj) { + ast_build_string(&tmp, &len, "<%s", dest, objtype); + inobj = 1; + } + if (!in_data) { + ast_build_string(&tmp, &len, " "); + xml_copy_escape(&tmp, &len, var, 1 | 2); + ast_build_string(&tmp, &len, "='"); + xml_copy_escape(&tmp, &len, val, 0); + if (!strcmp(var, "Opaque-data")) { + in_data = 1; + } else { ast_build_string(&tmp, &len, "'"); } + } else { + xml_copy_escape(&tmp, &len, val, 0); } } if (inobj) -- cgit v1.2.3