diff options
author | rizzo <rizzo@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-10-17 17:51:34 +0000 |
---|---|---|
committer | rizzo <rizzo@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-10-17 17:51:34 +0000 |
commit | 04aba2dbed82d6c2d317ab06872865203dad8e16 (patch) | |
tree | 0a68c29a2a4018561904eaad3032769f042833c4 /main | |
parent | 491cd757970b2beaf0d85c1e0fd51a6c6c90deee (diff) |
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
Diffstat (limited to 'main')
-rw-r--r-- | main/manager.c | 76 |
1 files changed, 47 insertions, 29 deletions
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", "<response type=\"object\" id=\"dest\"", "&" */ out = ast_malloc(len); if (!out) - return 0; + return NULL; tmp = out; - while (*in) { - var = in; - while (*in && (*in >= 32)) - in++; - if (*in) { - if ((count > 3) && inobj) { - ast_build_string(&tmp, &len, " /></response>\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, " /></response>\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, "<response type='object' id='%s'><%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, "<response type='object' id='%s'><%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) |