From c29e0a3388be7143951c820d90308d77fb543a12 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Fri, 20 Oct 2006 01:49:18 +0000 Subject: [PATCH] Server side connection parses xml using a new written handler A new handler similar to iks_stream was written, because iks_stream handles SASL itself, blocking the parser when fed with server-side xml. The server-side connection parses its xml too now, given opportunity for filters for data that comes from the server. --- Makefile.am | 2 +- iksemel_extra.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++ iksemel_extra.h | 27 +++++++++ jabber.c | 3 +- jabber_server.c | 34 +++++++++++- 5 files changed, 205 insertions(+), 4 deletions(-) create mode 100644 iksemel_extra.c create mode 100644 iksemel_extra.h diff --git a/Makefile.am b/Makefile.am index 4bd1a66..fd9834d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,3 +1,3 @@ bin_PROGRAMS = improxy -improxy_SOURCES = improxy.c log.c log.h nethook.c nethook.h proto_detect.c proto_detect.h jabber.c jabber.h jabber_server.c +improxy_SOURCES = improxy.c log.c log.h nethook.c nethook.h proto_detect.c proto_detect.h jabber.c jabber.h jabber_server.c iksemel_extra.c iksemel_extra.h sysconf_DATA = improxy.conf diff --git a/iksemel_extra.c b/iksemel_extra.c new file mode 100644 index 0000000..99f3937 --- /dev/null +++ b/iksemel_extra.c @@ -0,0 +1,143 @@ +/* +** Copyright (C) 2006 Thadeu Lima de Souza Cascardo +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +** +*/ + +#include "iksemel_extra.h" +#include + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +struct _iks_extra_stream_t +{ + iksStreamHook* hook; + void* data; + iks* node; + int top; +}; + +void iks_extra_insert_attrib (iks* node, char** atts) +{ + if (atts == NULL) + return; + while (*atts) + { + iks_insert_attrib (node, atts[0], atts[1]); + atts += 2; + } +} + +int tagHook (void* user_data, char* name, char** atts, int type) +{ + struct _iks_extra_stream_t* pdata; + pdata = (struct _iks_extra_stream_t*) user_data; + switch (type) + { + case IKS_OPEN: + if (pdata->top == FALSE || g_str_equal (name, "stream:stream")) + { + pdata->top = TRUE; + pdata->node = iks_new (name); + iks_extra_insert_attrib (pdata->node, atts); + pdata->hook (pdata->data, IKS_NODE_START, pdata->node); + pdata->node = NULL; + } + else if (pdata->node == NULL) + { + pdata->node = iks_new (name); + iks_extra_insert_attrib (pdata->node, atts); + } + else + { + pdata->node = iks_insert (pdata->node, name); + iks_extra_insert_attrib (pdata->node, atts); + } + break; + case IKS_CLOSE: + if (pdata->node == NULL) + { + pdata->node = iks_new (name); + pdata->hook (pdata->data, IKS_NODE_STOP, pdata->node); + pdata->node = NULL; + pdata->top = FALSE; + } + else if (iks_parent (pdata->node) == NULL) + { + pdata->hook (pdata->data, IKS_NODE_NORMAL, pdata->node); + pdata->node = NULL; + } + else + { + pdata->node = iks_parent (pdata->node); + } + break; + case IKS_SINGLE: + if (pdata->top == FALSE) + { + return -IKS_OK; + } + else if (pdata->node == NULL) + { + pdata->node = iks_new (name); + iks_extra_insert_attrib (pdata->node, atts); + pdata->hook (pdata->data, IKS_NODE_NORMAL, pdata->node); + pdata->node = NULL; + } + else + { + pdata->node = iks_insert (pdata->node, name); + iks_extra_insert_attrib (pdata->node, atts); + pdata->node = iks_parent (pdata->node); + } + break; + default: + break; + } + return IKS_OK; +} + +int dataHook (void* user_data, char* data, size_t len) +{ + struct _iks_extra_stream_t* pdata; + pdata = (struct _iks_extra_stream_t*) user_data; + iks_insert_cdata (pdata->node, data, len); + return IKS_OK; +} + +void deleteHook (void* user_data) +{ + iks_free (user_data); +} + +iksparser* iks_extra_stream_new (void* data, iksStreamHook* hook) +{ + iksparser* parser; + struct _iks_extra_stream_t* pdata; + pdata = iks_malloc (sizeof (struct _iks_extra_stream_t)); + pdata->hook = hook; + pdata->data = data; + pdata->node = NULL; + pdata->top = FALSE; + parser = iks_sax_extend (iks_stack_new (256, 0), + pdata, tagHook, dataHook, deleteHook); + return parser; +} diff --git a/iksemel_extra.h b/iksemel_extra.h new file mode 100644 index 0000000..eaf1482 --- /dev/null +++ b/iksemel_extra.h @@ -0,0 +1,27 @@ +/* +** Copyright (C) 2006 Thadeu Lima de Souza Cascardo +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +** +*/ + +#ifndef IKSEMEL_EXTRA_H +#define IKSEMEL_EXTRA_H + +#include + +iksparser* iks_extra_stream_new (void*, iksStreamHook*); + +#endif diff --git a/jabber.c b/jabber.c index 9efdc18..ebd7627 100644 --- a/jabber.c +++ b/jabber.c @@ -20,6 +20,7 @@ #include #include #include +#include "iksemel_extra.h" #include "jabber.h" static void jabber_connect (net_hook_t* hook) @@ -120,7 +121,7 @@ net_hook_t* jabber_hook_new (GConn* conn) hook->close = jabber_close; hook->write = jabber_write; hook->read = jabber_read; - hook->data = iks_stream_new ("jabber:client", hook, jabber_parser); + hook->data = iks_extra_stream_new (hook, jabber_parser); gnet_conn_set_callback (hook->conn, nethook_event, hook); return hook; } diff --git a/jabber_server.c b/jabber_server.c index bac65fc..4528de9 100644 --- a/jabber_server.c +++ b/jabber_server.c @@ -20,6 +20,7 @@ #include #include #include +#include "iksemel_extra.h" #include "jabber.h" static void jabber_server_connect (net_hook_t* hook) @@ -38,7 +39,36 @@ static void jabber_server_write (net_hook_t* hook) static void jabber_server_read (net_hook_t* hook, gchar* buffer, size_t len) { - gnet_conn_write (hook->peer, buffer, len); + iks_parse (hook->data, buffer, len, FALSE); +} + +int jabber_server_parser (gpointer data, int type, iks* node) +{ + net_hook_t* hook; + GString* buffer; + hook = (net_hook_t*) data; + switch (type) + { + case IKS_NODE_START: + buffer = jabber_new_start (node); + gnet_conn_write (hook->peer, buffer->str, buffer->len); + g_string_free (buffer, TRUE); + iks_delete (node); + break; + case IKS_NODE_NORMAL: + buffer = g_string_new (iks_string (iks_stack (node), node)); + gnet_conn_write (hook->peer, buffer->str, buffer->len); + g_string_free (buffer, TRUE); + iks_delete (node); + break; + case IKS_NODE_STOP: + gnet_conn_write (hook->peer, "", 16); + break; + case IKS_NODE_ERROR: + g_debug ("Parse error!!"); + break; + } + return IKS_OK; } net_hook_t* jabber_server_hook_new (net_hook_t* client_hook, char* server) @@ -52,6 +82,6 @@ net_hook_t* jabber_server_hook_new (net_hook_t* client_hook, char* server) hook->close = jabber_server_close; hook->write = jabber_server_write; hook->read = jabber_server_read; - hook->data = NULL; /*iks_stream_new ("jabber:client", hook, jabber_server_parser);*/ + hook->data = iks_extra_stream_new (hook, jabber_server_parser); return hook; } -- 2.20.1