Commit 07d20a2b authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gaston

Added support for Flash clients. JM-1


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@787 b35dd754-fafc-0310-a699-88a17e54d16e
parent 7c1565b8
...@@ -139,4 +139,24 @@ public interface Connection { ...@@ -139,4 +139,24 @@ public interface Connection {
* @throws UnauthorizedException If caller doesn't have permission to access this resource * @throws UnauthorizedException If caller doesn't have permission to access this resource
*/ */
void deliver(Packet packet) throws UnauthorizedException; void deliver(Packet packet) throws UnauthorizedException;
/**
* Sets whether the connected client is a flash client or not. Flash clients need to receive
* a special character (i.e. \0) at the end of each xml packet. Flash clients may send the
* character \0 in incoming packets and may start a connection using another openning tag
* such as: "flash:client".
*
* @param flashClient flag that indicates if the client is a flash client.
*/
void setFlashClient(boolean flashClient);
/**
* Returns true if the connected client is a flash client. Flash clients need to receive
* a special character (i.e. \0) at the end of each xml packet. Flash clients may send the
* character \0 in incoming packets and may start a connection using another openning tag
* such as: "flash:client".
*
* @return true if the connected client is a flash client.
*/
boolean isFlashClient();
} }
...@@ -68,6 +68,8 @@ public class SocketConnection extends BasicConnection { ...@@ -68,6 +68,8 @@ public class SocketConnection extends BasicConnection {
private XMLWriter xmlSerializer; private XMLWriter xmlSerializer;
private boolean flashClient = false;
/** /**
* Create a new session using the supplied socket. * Create a new session using the supplied socket.
* *
...@@ -182,6 +184,9 @@ public class SocketConnection extends BasicConnection { ...@@ -182,6 +184,9 @@ public class SocketConnection extends BasicConnection {
synchronized (writer) { synchronized (writer) {
try { try {
xmlSerializer.write(packet.getElement()); xmlSerializer.write(packet.getElement());
if (flashClient) {
writer.write('\0');
}
xmlSerializer.flush(); xmlSerializer.flush();
} }
catch (IOException e) { catch (IOException e) {
...@@ -192,4 +197,12 @@ public class SocketConnection extends BasicConnection { ...@@ -192,4 +197,12 @@ public class SocketConnection extends BasicConnection {
session.incrementServerPacketCount(); session.incrementServerPacketCount();
} }
} }
public void setFlashClient(boolean flashClient) {
this.flashClient = flashClient;
}
public boolean isFlashClient() {
return flashClient;
}
} }
...@@ -48,6 +48,7 @@ public class SocketReadThread extends Thread { ...@@ -48,6 +48,7 @@ public class SocketReadThread extends Thread {
private static String CHARSET = "UTF-8"; private static String CHARSET = "UTF-8";
private static final String ETHERX_NAMESPACE = "http://etherx.jabber.org/streams"; private static final String ETHERX_NAMESPACE = "http://etherx.jabber.org/streams";
private static final String FLASH_NAMESPACE = "http://www.jabber.com/streams/flash";
private Socket sock; private Socket sock;
private Session session; private Session session;
...@@ -236,26 +237,62 @@ public class SocketReadThread extends Thread { ...@@ -236,26 +237,62 @@ public class SocketReadThread extends Thread {
*/ */
private void createSession() throws UnauthorizedException, XmlPullParserException, IOException, Exception { private void createSession() throws UnauthorizedException, XmlPullParserException, IOException, Exception {
XmlPullParser xpp = reader.getXPPParser(); XmlPullParser xpp = reader.getXPPParser();
for (int eventType = xpp.getEventType(); for (int eventType = xpp.getEventType(); eventType != XmlPullParser.START_TAG;) {
eventType != XmlPullParser.START_TAG; eventType = xpp.next();
eventType = xpp.next()) {
} }
boolean isFlashClient = xpp.getPrefix().equals("flash");
// Conduct error checking, the opening tag should be 'stream' // Conduct error checking, the opening tag should be 'stream'
// in the 'etherx' namespace // in the 'etherx' namespace
if (!xpp.getName().equals("stream")) { if (!xpp.getName().equals("stream") && !isFlashClient) {
throw new XmlPullParserException(LocaleUtils.getLocalizedString("admin.error.bad-stream")); throw new XmlPullParserException(LocaleUtils.getLocalizedString("admin.error.bad-stream"));
} }
if (!xpp.getNamespace(xpp.getPrefix()).equals(ETHERX_NAMESPACE)) {
if (!xpp.getNamespace(xpp.getPrefix()).equals(ETHERX_NAMESPACE) &&
!(isFlashClient && xpp.getNamespace(xpp.getPrefix()).equals(FLASH_NAMESPACE))) {
throw new XmlPullParserException(LocaleUtils.getLocalizedString("admin.error.bad-namespace")); throw new XmlPullParserException(LocaleUtils.getLocalizedString("admin.error.bad-namespace"));
} }
Writer writer = connection.getWriter(); Writer writer = connection.getWriter();
String startPacket = "<?xml version='1.0' encoding='"+CHARSET+"'?><stream:stream xmlns:stream=\"http://etherx.jabber.org/streams\" xmlns=\"jabber:client\" from=\""+serverName+"\" id=\""+session.getStreamID().toString()+"\">"; // Build the start packet response
writer.write(startPacket); StringBuffer sb = new StringBuffer();
writer.flush(); sb.append("<?xml version='1.0' encoding='");
// TODO: check for SASL support in opening stream tag sb.append(CHARSET);
sb.append("'?>");
if (isFlashClient) {
sb.append("<flash:stream xmlns:flash=\"http://www.jabber.com/streams/flash\" ");
} }
else {
sb.append("<stream:stream ");
}
sb.append("xmlns:stream=\"http://etherx.jabber.org/streams\" xmlns=\"jabber:client\" from=\"");
sb.append(serverName);
sb.append("\" id=\"");
sb.append(session.getStreamID().toString());
sb.append("\">");
writer.write(sb.toString());
// If this is a flash client then flag the connection and append a special caracter to the
// response
if (isFlashClient) {
session.getConnection().setFlashClient(true);
writer.write('\0');
// Skip possible end of tags and \0 characters
/*final int[] holderForStartAndLength = new int[2];
final char[] chars = xpp.getTextCharacters(holderForStartAndLength);
if (chars[xpp.getColumnNumber()-2] == '/') {
xpp.next();
try {
xpp.next();
}
catch (XmlPullParserException ie) {
// We expect this exception since the parser is reading a \0 character
}
}*/
}
writer.flush();
// TODO: check for SASL support in opening stream tag
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment