[jdev] Flash Patch
Marcel Bootsma
marcel.bootsma at logicacmg.com
Thu Dec 16 05:52:11 CST 2004
Hello Jabbers,
For our project we use a flash based client for Jabber 2.0
As most of you know this normally doesn't work because of
Flash not being 100% compatible with XML streams.
I did read the discussions about this topic (mainly in April)
And agree that using a patch in jaber is not the nicest solution
And a proxy would be much better...
But I never build a proxy and didn't have time to learn how to
Because it had to work fast (as always).
So, I just ported the old 1.4 patch into 2.0 and it worked within
a couple of days (hey, I am knew to networking and Jabber)
You don't have to embed it into your code but its just for anyone
who can use it.
Grt
Marcel
Here it is:
diff -Naur /home/jabber/jabberd-2.0s6.orig/c2s/c2s.c jabberd-2.0s6/c2s/c2s.c
--- /home/jabber/jabberd-2.0s6.orig/c2s/c2s.c 2004-12-15
11:03:08.000000000 +0100
+++ jabberd-2.0s6/c2s/c2s.c 2004-12-16 11:50:42.000000000 +0100
@@ -20,6 +20,67 @@
#include "c2s.h"
+
+/*
+ * M.Bootsma, LogicaCMG Hoofddorp, Netherlands
+ * October 2004
+ *
+ * Added a patch for flash:stream support
+ *
+ * Flash is not 100% compatible with the XML stream standard:
+ * 1. it terminates every XML message with a '\0'
+ * 2. it terminates the stream header with a /
+ * (this would close the stream)
+ * 3. it starts the stream with a flash:stream header instead of
+ * a stream:stream header.
+ *
+ * The patch checks the first message of a starting session stream
+ * for any '\0'. If found it flags the session as a Flash session
+ * and replases the complete header with a Jabber compatible
+ * header.
+ * After that every incomming message is filtered from '\0' which
+ * are substuted for ' '
+ * For every outgoing message a '\0' is appended and the response
+ * of the header is replaced for a flash friendly version
+ *
+ * The whole flash patch can be switch off undefining CP2005_FLASH_PATCH
+ * in config.h(.in)
+ */
+
+#ifdef CP2005_FLASH_PATCH
+
+#define FLASH_BUFFER_SIZE 256
+
+static const char caStreamHeader [] = "<?xml version='1.0'?><stream:stream
xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client'
to='%s' >";
+static const char caFlashHeader [] = "<?xml version='1.0'?><flash:stream
xmlns:flash='http://www.jabber.com/streams/flash'
xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client'
from='%s' id='%s' />";
+
+static void ExtractValue (char *pMessage, char *pVariable, char *pValue)
+{
+int iLen;
+char *p;
+char *pEnd;
+
+ /*
+ * extract the value of an attribute from a XML message
+ * eg: <.... id='1234567890' ....> returns 1234567890
+ */
+
+ p = strstr (pMessage, pVariable);
+ if (p != NULL) {
+ p += (strlen (pVariable) + 1);
+ /* find end of value, search for closing ' or " */
+ pEnd = strchr (p, p [-1]);
+ iLen = pEnd - p;
+ if (iLen < FLASH_BUFFER_SIZE) {
+ memcpy (pValue, p, iLen);
+ pValue [iLen] = '\0';
+ log_debug (ZONE, "++++ Extracted Var %s: [%s]\n", pVariable,
pValue);
+ }
+ }
+}
+#endif
+
+
static int _c2s_client_sx_callback(sx_t s, sx_event_t e, void *data, void
*arg) {
sess_t sess = (sess_t) arg;
sx_buf_t buf = (sx_buf_t) data;
@@ -28,6 +89,12 @@
nad_t nad;
char root[9];
+#ifdef CP2005_FLASH_PATCH
+ char *p, *pEnd;
+ char caHost [FLASH_BUFFER_SIZE];
+ char caID [FLASH_BUFFER_SIZE];
+#endif
+
switch(e) {
case event_WANT_READ:
log_debug(ZONE, "want read");
@@ -94,15 +161,79 @@
return -1;
}
- log_debug(ZONE, "read %d bytes", len);
-
buf->len = len;
+#ifdef CP2005_FLASH_PATCH
+ /* check for 0 bytes in the first packet
+ * if found it must be a flash client
+ * remove any 0 in the data and
+ * the / that ends the <?xml... header
+ */
+
+ pEnd = &buf->data [len];
+
+ if (sess->s->state == state_NONE) {
+ /* stream is new, look for 0 bytes */
+ p = strchr (buf->data, '\0');
+ if ((p != NULL) && (p < pEnd)) {
+ log_debug (ZONE, "++++ Flash Stream detected\n%.*s",
buf->len, buf->data);
+
+ sess->flash_client = 1;
+ /* extract destination host */
+ ExtractValue (buf->data, "to=", caHost);
+ /* create normal stream:stream header, resize data
buffer first */
+ _sx_buffer_alloc_margin (buf, 0, sizeof
(caStreamHeader) + strlen (caHost) + 8);
+ sprintf (buf->data, caStreamHeader, caHost);
+ buf->len = strlen (buf->data);
+
+ log_debug(ZONE, "++++ Converted to\n%.*s", buf->len,
buf->data);
+ }
+ }
+
+ /*
+ * Check all other messages in the stream
+ * to remove \0's etc
+ */
+
+ if (sess->flash_client) {
+ /* remove 0's from flash packets */
+ for (p = buf->data; p < pEnd; p++) {
+ if (*p == '\0') {
+ *p = ' ';
+ }
+ }
+ }
+#endif
+ log_debug(ZONE, "read %d bytes", len);
+
return len;
case event_WRITE:
log_debug(ZONE, "writing to %d", sess->fd);
+#ifdef CP2005_FLASH_PATCH
+ if (sess->flash_client) {
+ /* look for the header <? xml ...*/
+ if (strncmp (buf->data, "<?xml ", 6) == 0) {
+ /* replace normal stream header with flash friendly
header */
+ log_debug(ZONE, "++++ Found <?xml..., \n%.*s",
buf->len, buf->data);
+
+ /* extract id from id="123456567778765" or
id='45454545454' */
+ ExtractValue (buf->data, "from=", caHost);
+ ExtractValue (buf->data, "id=", caID);
+ /* create flash:stream header, realloc buffer first */
+ _sx_buffer_alloc_margin (buf, 0, sizeof (caFlashHeader)
+ strlen (caHost) + strlen (caID) + 8);
+ sprintf (buf->data, caFlashHeader, caHost, caID);
+ buf->len = strlen (buf->data);
+
+ log_debug(ZONE, "++++ Converted to %s", buf->data);
+ }
+ /* add a 0 to flash packets */
+ buf->data [buf->len] = '\0';
+ buf->len++;
+ }
+#endif
+
len = send(sess->fd, buf->data, buf->len, 0);
if(len >= 0) {
log_debug(ZONE, "%d bytes written", len);
diff -Naur /home/jabber/jabberd-2.0s6.orig/c2s/c2s.h jabberd-2.0s6/c2s/c2s.h
--- /home/jabber/jabberd-2.0s6.orig/c2s/c2s.h 2004-12-15
11:03:08.000000000 +0100
+++ jabberd-2.0s6/c2s/c2s.h 2004-12-16 11:55:08.000000000 +0100
@@ -62,6 +64,10 @@
int bound;
int active;
+#ifdef CP2005_FLASH_PATCH
+ int flash_client;
+#endif
+
nad_t result;
int sasl_authd; /* 1 = they did a sasl auth */
This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. Thank you.
More information about the JDev
mailing list