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: https://origsvn.digium.com/svn/asterisk/trunk@45334 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.6.0
Luigi Rizzo 19 years ago
parent a8a26ad389
commit 3abf04cc26

@ -296,7 +296,7 @@ static char *xml_translate(char *in, struct ast_variable *vars)
int colons = 0; int colons = 0;
int breaks = 0; int breaks = 0;
size_t len; size_t len;
int count = 1; int in_data = 0; /* parsing data */
int escaped = 0; int escaped = 0;
int inobj = 0; int inobj = 0;
int x; int x;
@ -311,6 +311,11 @@ static char *xml_translate(char *in, struct ast_variable *vars)
dest = "unknown"; dest = "unknown";
if (!objtype) if (!objtype)
objtype = "generic"; 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++) { for (x = 0; in[x]; x++) {
if (in[x] == ':') if (in[x] == ':')
colons++; 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\"", "&amp;" */ len = (size_t) (strlen(in) + colons * 5 + breaks * (40 + strlen(dest) + strlen(objtype)) + escaped * 10); /* foo="bar", "<response type=\"object\" id=\"dest\"", "&amp;" */
out = ast_malloc(len); out = ast_malloc(len);
if (!out) if (!out)
return 0; return NULL;
tmp = out; tmp = out;
while (*in) { /* we want to stop when we find an empty line */
var = in; while (in && *in) {
while (*in && (*in >= 32)) in = ast_skip_blanks(in); /* trailing \n from before */
in++; val = strsep(&in, "\r\n"); /* mark start and end of line */
if (*in) { ast_trim_blanks(val);
if ((count > 3) && inobj) { ast_verbose("inobj %d in_data %d line <%s>\n", inobj, in_data, val);
ast_build_string(&tmp, &len, " /></response>\n"); if (ast_strlen_zero(val)) {
inobj = 0; if (in_data) { /* close data */
ast_build_string(&tmp, &len, "'");
in_data = 0;
} }
count = 0; ast_build_string(&tmp, &len, " /></response>\n");
while (*in && (*in < 32)) { inobj = 0;
*in = '\0'; continue;
in++; }
count++; /* 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) { if (!inobj) {
*val = '\0'; ast_build_string(&tmp, &len, "<response type='object' id='%s'><%s", dest, objtype);
val++; inobj = 1;
if (*val == ' ') }
val++; if (!in_data) {
if (!inobj) { ast_build_string(&tmp, &len, " ");
ast_build_string(&tmp, &len, "<response type='object' id='%s'><%s", dest, objtype); xml_copy_escape(&tmp, &len, var, 1 | 2);
inobj = 1; ast_build_string(&tmp, &len, "='");
} xml_copy_escape(&tmp, &len, val, 0);
ast_build_string(&tmp, &len, " "); if (!strcmp(var, "Opaque-data")) {
xml_copy_escape(&tmp, &len, var, 1); in_data = 1;
ast_build_string(&tmp, &len, "='"); } else {
xml_copy_escape(&tmp, &len, val, 0);
ast_build_string(&tmp, &len, "'"); ast_build_string(&tmp, &len, "'");
} }
} else {
xml_copy_escape(&tmp, &len, val, 0);
} }
} }
if (inobj) if (inobj)

Loading…
Cancel
Save