Server side connection parses xml using a new written handler
authorThadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Fri, 20 Oct 2006 01:49:18 +0000 (01:49 +0000)
committerThadeu Lima de Souza Cascardo <cascardo@minaslivre.org>
Fri, 20 Oct 2006 01:49:18 +0000 (01:49 +0000)
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
iksemel_extra.c [new file with mode: 0644]
iksemel_extra.h [new file with mode: 0644]
jabber.c
jabber_server.c

index 4bd1a66..fd9834d 100644 (file)
@@ -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 (file)
index 0000000..99f3937
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+** Copyright (C) 2006 Thadeu Lima de Souza Cascardo <cascardo@minaslivre.org>
+**  
+** 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 <glib.h>
+
+#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 (file)
index 0000000..eaf1482
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+** Copyright (C) 2006 Thadeu Lima de Souza Cascardo <cascardo@minaslivre.org>
+**  
+** 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 <iksemel.h>
+
+iksparser* iks_extra_stream_new (void*, iksStreamHook*);
+
+#endif
index 9efdc18..ebd7627 100644 (file)
--- a/jabber.c
+++ b/jabber.c
@@ -20,6 +20,7 @@
 #include <gnet.h>
 #include <glib.h>
 #include <iksemel.h>
+#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;
 }
index bac65fc..4528de9 100644 (file)
@@ -20,6 +20,7 @@
 #include <gnet.h>
 #include <glib.h>
 #include <iksemel.h>
+#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, "</stream:stream>", 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;
 }