diff --git a/src/include/switch_event.h b/src/include/switch_event.h index c7e2fa9a39..15ff554206 100644 --- a/src/include/switch_event.h +++ b/src/include/switch_event.h @@ -229,6 +229,15 @@ SWITCH_DECLARE(switch_status_t) switch_event_reserve_subclass_detailed(char *own */ SWITCH_DECLARE(switch_status_t) switch_event_serialize(switch_event_t *event, char *buf, switch_size_t buflen, char *fmt, ...); +/*! + \brief Render a XML representation of an event sutable for printing or network transport + \param event the event to render + \param fmt optional body of the event (varargs see standard sprintf family) + \return the xml object if the operation was successful + \note the body supplied by this function will supersede an existing body the event may have +*/ +SWITCH_DECLARE(switch_xml_t) switch_event_xmlize(switch_event_t *event, char *fmt, ...); + /*! \brief Determine if the event system has been initilized \return SWITCH_STATUS_SUCCESS if the system is running diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index 85af4379e4..2f86cb22a6 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -68,6 +68,7 @@ struct switch_stream_handle { void *end; switch_size_t data_size; switch_size_t data_len; + switch_event_t *event; }; /*! \brief Node in which to store custom outgoing channel callback hooks */ diff --git a/src/mod/event_handlers/mod_event_test/mod_event_test.c b/src/mod/event_handlers/mod_event_test/mod_event_test.c index e829c0d42d..c941bff45c 100644 --- a/src/mod/event_handlers/mod_event_test/mod_event_test.c +++ b/src/mod/event_handlers/mod_event_test/mod_event_test.c @@ -39,15 +39,33 @@ static const char modname[] = "mod_event_test"; static void event_handler(switch_event_t *event) { char buf[1024]; + switch_xml_t xml; + char *xmlstr = "N/A"; + uint8_t dofree = 0; switch (event->event_id) { case SWITCH_EVENT_LOG: return; default: switch_event_serialize(event, buf, sizeof(buf), NULL); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\nEVENT\n--------------------------------\n%s\n", buf); + if ((xml = switch_event_xmlize(event, NULL))) { + xmlstr = switch_xml_toxml(xml); + dofree++; + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\nEVENT (text version)\n--------------------------------\n%s", buf); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\nEVENT (xml version)\n--------------------------------\n%s\n", xmlstr); break; } + + if (dofree) { + if (xml) { + switch_xml_free(xml); + } + if (xmlstr) { + free(xmlstr); + } + } } diff --git a/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c b/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c index 92e9b02848..8243ae884d 100644 --- a/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c +++ b/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c @@ -208,10 +208,23 @@ abyss_bool HandleHook(TSession *r) char *m = "text/html"; switch_stream_handle_t stream = {0}; char *command; + if(strncmp(r->uri, "/api/", 5)) { return FALSE; } + if (switch_event_create(&stream.event, SWITCH_EVENT_API) == SWITCH_STATUS_SUCCESS) { + if (r->uri) switch_event_add_header(stream.event, SWITCH_STACK_BOTTOM, "HTTP-URI", r->uri); + if (r->query) switch_event_add_header(stream.event, SWITCH_STACK_BOTTOM, "HTTP-QUERY", r->query); + if (r->host) switch_event_add_header(stream.event, SWITCH_STACK_BOTTOM, "HTTP-HOST", r->host); + if (r->from) switch_event_add_header(stream.event, SWITCH_STACK_BOTTOM, "HTTP-FROM", r->from); + if (r->useragent) switch_event_add_header(stream.event, SWITCH_STACK_BOTTOM, "HTTP-USER-AGENT", r->useragent); + if (r->referer) switch_event_add_header(stream.event, SWITCH_STACK_BOTTOM, "HTTP-REFERER", r->referer); + if (r->requestline) switch_event_add_header(stream.event, SWITCH_STACK_BOTTOM, "HTTP-REQUESTLINE", r->requestline); + if (r->user) switch_event_add_header(stream.event, SWITCH_STACK_BOTTOM, "HTTP-USER", r->user); + if (r->port) switch_event_add_header(stream.event, SWITCH_STACK_BOTTOM, "HTTP-PORT", "%u", r->port); + } + command = r->uri + 5; ResponseChunked(r); diff --git a/src/switch_event.c b/src/switch_event.c index 6eb3e1fab3..0bb5499fba 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -538,6 +538,78 @@ SWITCH_DECLARE(switch_status_t) switch_event_serialize(switch_event_t *event, ch } +static switch_xml_t add_xml_header(switch_xml_t xml, char *name, char *value, int offset) +{ + switch_xml_t header = NULL; + + if ((header = switch_xml_add_child_d(xml, "header", offset))) { + switch_xml_set_attr_d(header, "name", name); + switch_xml_set_attr_d(header, "value", value); + } + + return header; +} + +SWITCH_DECLARE(switch_xml_t) switch_event_xmlize(switch_event_t *event, char *fmt, ...) +{ + switch_event_header_t *hp; + char *data = NULL, *body = NULL; + int ret = 0; + switch_xml_t xml = NULL; + uint32_t off = 0; + va_list ap; + + if (!(xml = switch_xml_new("event"))) { + return xml; + } + + if (fmt) { + va_start(ap, fmt); +#ifdef HAVE_VASPRINTF + ret = vasprintf(&data, fmt, ap); +#else + data = (char *) malloc(2048); + vsnprintf(data, 2048, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + return NULL; + } + } + + + for (hp = event->headers; hp; hp = hp->next) { + add_xml_header(xml, hp->name, hp->value, off++); + } + + if (data) { + body = data; + } else if (event->body) { + body = event->body; + } + + if (body) { + int blen = (int) strlen(body); + char blena[25]; + snprintf(blena, sizeof(blena), "%d", blen); + if (blen) { + switch_xml_t xbody = NULL; + + add_xml_header(xml, "Content-Length", blena, off++); + if ((xbody = switch_xml_add_child_d(xml, "body", 0))) { + switch_xml_set_txt_d(xbody, body); + } + } + } + + if (data) { + free(data); + } + + return xml; +} + + SWITCH_DECLARE(switch_status_t) switch_event_fire_detailed(char *file, char *func, int line, switch_event_t **event, void *user_data) { diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index 90e616c8e1..9a48f4ca9b 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -671,12 +671,24 @@ SWITCH_DECLARE(switch_status_t) switch_api_execute(char *cmd, char *arg, switch_ { switch_api_interface_t *api; switch_status_t status; - switch_event_t *event; assert(stream != NULL); assert(stream->data != NULL); assert(stream->write_function != NULL); + if (!stream->event) { + switch_event_create(&stream->event, SWITCH_EVENT_API); + } + + if (stream->event) { + if (cmd) { + switch_event_add_header(stream->event, SWITCH_STACK_BOTTOM, "API-Command", cmd); + } + if (arg) { + switch_event_add_header(stream->event, SWITCH_STACK_BOTTOM, "API-Command-Arguement", arg); + } + } + if ((api = switch_loadable_module_get_api_interface(cmd)) != 0) { status = api->function(arg, stream); } else { @@ -685,15 +697,8 @@ SWITCH_DECLARE(switch_status_t) switch_api_execute(char *cmd, char *arg, switch_ //snprintf(retbuf, len, "INVALID COMMAND [%s]", cmd); } - if (switch_event_create(&event, SWITCH_EVENT_API) == SWITCH_STATUS_SUCCESS) { - if (cmd) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "API-Command", cmd); - } - if (arg) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "API-Command-Arguement", arg); - } - //switch_event_add_body(event, retbuf); - switch_event_fire(&event); + if (stream->event) { + switch_event_fire(&stream->event); }