From 295424544dc3ecdff10b00c04aac3725c1e7b686 Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthony.minessale@gmail.com>
Date: Wed, 10 May 2006 19:07:38 +0000
Subject: [PATCH] update

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@1425 d0543943-73ff-0310-b7d9-9358b9ac24b2
---
 src/include/switch_event.h                    |  9 +++
 src/include/switch_module_interfaces.h        |  1 +
 .../mod_event_test/mod_event_test.c           | 20 +++++-
 src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c     | 13 ++++
 src/switch_event.c                            | 72 +++++++++++++++++++
 src/switch_loadable_module.c                  | 25 ++++---
 6 files changed, 129 insertions(+), 11 deletions(-)

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);
 	}