Index: main/manager.c
===================================================================
--- main/manager.c (revision 195520)
+++ main/manager.c (working copy)
@@ -3682,12 +3682,14 @@
FORMAT_RAW,
FORMAT_HTML,
FORMAT_XML,
+ FORMAT_JSON,
};
static char *contenttype[] = {
- [FORMAT_RAW] = "plain",
- [FORMAT_HTML] = "html",
- [FORMAT_XML] = "xml",
+ [FORMAT_RAW] = "text/plain",
+ [FORMAT_HTML] = "text/html",
+ [FORMAT_XML] = "text/xml",
+ [FORMAT_JSON] = "application/json",
};
/*!
@@ -3823,6 +3825,8 @@
* mode & 1 -> lowercase;
* mode & 2 -> replace non-alphanumeric chars with underscore
*/
+#define LOWERCASE 1
+#define UNDERSCORE_REPLACE 2
static void xml_copy_escape(struct ast_str **out, const char *src, int mode)
{
/* store in a local buffer to avoid calling ast_str_append too often */
@@ -3841,7 +3845,7 @@
}
}
- if ( (mode & 2) && !isalnum(*src)) {
+ if ((mode & UNDERSCORE_REPLACE) && !isalnum(*src)) {
*dst++ = '_';
space--;
continue;
@@ -3874,7 +3878,7 @@
break;
default:
- *dst++ = mode ? tolower(*src) : *src;
+ *dst++ = mode & LOWERCASE ? tolower(*src) : *src;
space--;
}
}
@@ -3938,8 +3942,8 @@
char *var, *val;
const char *objtype = NULL;
int in_data = 0; /* parsing data */
- int inobj = 0;
- int xml = (format == FORMAT_XML);
+ int inobj = 0, first = 1;
+ int xml = (format == FORMAT_XML), json = (format == FORMAT_JSON);
struct variable_count *vc = NULL;
struct ao2_container *vco = NULL;
@@ -3972,13 +3976,15 @@
/* empty line */
if (in_data) {
/* close data in Opaque mode */
- ast_str_append(out, 0, xml ? "'" : "\n");
+ ast_str_append(out, 0, xml ? "'" :
+ json ? "\"" : "\n");
in_data = 0;
}
if (inobj) {
/* close block */
ast_str_append(out, 0, xml ? " />\n" :
+ json ? "}," :
"
|
\r\n");
inobj = 0;
ao2_ref(vco, -1);
@@ -3991,6 +3997,9 @@
/* start new block */
if (xml) {
ast_str_append(out, 0, "<%s", dest, objtype);
+ } else if (json) {
+ ast_str_append(out, 0, "{");
+ first = 1;
}
vco = ao2_container_alloc(37, variable_count_hash_fn, variable_count_cmp_fn);
inobj = 1;
@@ -3999,7 +4008,7 @@
if (in_data) {
/* Process data field in Opaque mode */
xml_copy_escape(out, val, 0); /* data field */
- ast_str_append(out, 0, xml ? "\n" : "
\n");
+ ast_str_append(out, 0, xml ? "\n" : json ? "\n" : "
\n");
continue;
}
@@ -4017,7 +4026,8 @@
}
- ast_str_append(out, 0, xml ? " " : "");
+ ast_str_append(out, 0, xml ? " " : json ? (first ? "\"" : ",\"") : " |
");
+ first = 0;
if ((vc = ao2_find(vco, var, 0))) {
vc->count++;
} else {
@@ -4028,18 +4038,19 @@
ao2_link(vco, vc);
}
- xml_copy_escape(out, var, xml ? 1 | 2 : 0); /* data name */
+ xml_copy_escape(out, var, xml ? LOWERCASE | UNDERSCORE_REPLACE : 0); /* data name */
if (vc->count > 1) {
ast_str_append(out, 0, "-%d", vc->count);
}
ao2_ref(vc, -1);
- ast_str_append(out, 0, xml ? "='" : " | ");
+ ast_str_append(out, 0, xml ? "='" : json ? "\":\"" : " | ");
xml_copy_escape(out, val, 0); /* data field */
- ast_str_append(out, 0, xml ? "'" : " |
\n");
+ ast_str_append(out, 0, xml ? "'" : json ? "\"" : "\n");
}
if (inobj) {
ast_str_append(out, 0, xml ? " />\n" :
+ json ? "}" :
"
|
\r\n");
ao2_ref(vco, -1);
}
@@ -4157,7 +4168,7 @@
}
ast_str_append(&http_header, 0,
- "Content-type: text/%s\r\n"
+ "Content-type: %s\r\n"
"Cache-Control: no-cache;\r\n"
"Set-Cookie: mansession_id=\"%08x\"; Version=\"1\"; Max-Age=%d"
"Pragma: SuppressEvents\r\n",
@@ -4166,6 +4177,8 @@
if (format == FORMAT_XML) {
ast_str_append(&out, 0, "\n");
+ } else if (format == FORMAT_JSON) {
+ ast_str_append(&out, 0, "[");
} else if (format == FORMAT_HTML) {
/*
* When handling AMI-over-HTTP in HTML format, we provide a simple form for
@@ -4202,14 +4215,14 @@
if (MAP_FAILED == (buf = mmap(NULL, l, PROT_READ | PROT_WRITE, MAP_PRIVATE, s.fd, 0))) {
ast_log(LOG_WARNING, "mmap failed. Manager output was not processed\n");
} else {
- if (format == FORMAT_XML || format == FORMAT_HTML) {
+ if (format == FORMAT_XML || format == FORMAT_HTML || format == FORMAT_JSON) {
xml_translate(&out, buf, params, format);
} else {
ast_str_append(&out, 0, "%s", buf);
}
munmap(buf, l);
}
- } else if (format == FORMAT_XML || format == FORMAT_HTML) {
+ } else if (format == FORMAT_XML || format == FORMAT_HTML || format == FORMAT_JSON) {
xml_translate(&out, "", params, format);
}
fclose(s.f);
@@ -4219,6 +4232,8 @@
if (format == FORMAT_XML) {
ast_str_append(&out, 0, "\n");
+ } else if (format == FORMAT_JSON) {
+ ast_str_append(&out, 0, "0]");
} else if (format == FORMAT_HTML) {
ast_str_append(&out, 0, "