diff --git a/Makefile b/Makefile index cdd8322..0941385 100644 --- a/Makefile +++ b/Makefile @@ -1,54 +1,41 @@ SYSTEM = Linux +include hxmpp.source include hxmpp.stable -STABLE_BASE = jabber.ServiceDiscovery -STABEL_CLIENT_BASE = jabber.client.Stream jabber.client.Roster jabber.client.NonSASLAuthentication jabber.client.SASLAuthentication jabber.client.VCard net.sasl.PlainMechanism -STABEL_CLIENT_JS = $(STABEL_BASE) $(STABEL_CLIENT_BASE) jabber.BOSHConnection - - NDLL = ndll/$(SYSTEM)/hxmpp.ndll NDLL_OBJECTS = util/sha1.o #util/base64.o +LIB_JS = out/hxmpp.js +LIB_SWC = out/hxmpp.swc +FLAGS = -cp lib/ -exclude hxmpp.exclude -all : $(NDLL) lib +all : $(NDLL) \ + $(LIB_JS) \ + $(LIB_SWC) -$(NDLL) : $(NDLL_OBJECTS) +$(NDLL) : $(NDLL_OBJECTS) $(CC) -shared -O3 -I/usr/lib/neko/include $(NDLL_OBJECTS) -o $@ -libjs : - haxe -js out/hxmpp.js -cp lib/ --no-traces -exclude hxmpp.exclude $(STABEL_CLIENT_JS) - #haxe -js tmp -cp lib/ --no-traces -exclude hxmpp.exclude $(STABEL_CLIENT_JS) - #-java -jar ~/bin/closure.jar -js=tmp --js_output_file=out/hxmpp.js - #rm tmp - haxe -js out/hxmpp-debug.js -cp lib/ -exclude hxmpp.exclude \ - -D JABBER_DEBUG \ - -D XMPP_DEBUG \ - -D JABBER_CONSOLE \ - -debug \ - $(STABEL_CLIENT_JS) - -libswc : - haxe -swf9 out/hxmpp.swc -cp lib/ --no-traces -exclude hxmpp.exclude $(STABLE_CLIENT) - haxe -swf9 out/hxmpp-debug.swc -cp lib/ -D JABBER_DEBUG -D JABBER_CONSOLE -D XMPP_DEBUG jabber.client.Stream - -#libas3 : - #haxe -as3 out/as3 - -lib : libjs libswc - -tools : +$(LIB_JS) : $(HXMPP_SRC) + haxe -js out/hxmpp.js $(FLAGS) $(STABLE_CLIENT_JS) --no-traces + haxe -js out/hxmpp-debug.js $(FLAGS) $(STABLE_CLIENT_JS) \ + -D JABBER_DEBUG -D XMPP_DEBUG -D JABBER_CONSOLE \ + -debug + +$(LIB_SWC) : $(HXMPP_SRC) + haxe -swf9 out/hxmpp.swc $(FLAGS) $(STABLE_CLIENT) --no-traces + haxe -swf9 out/hxmpp-debug.swc $(FLAGS) $(STABLE_CLIENT) \ + -D JABBER_DEBUG -D JABBER_CONSOLE -D XMPP_DEBUG \ + -debug + +utilities : haxe utilities.hxml doc : - haxe doc.hxml + #haxe doc.hxml clean : rm util/*.o .PHONY: all doc clean lib - -##find jabber/ xmpp/ -name "*.hx" | sed -e 's/\//./g' -e 's/\.hx//' > temp; -##paste -s -d' ' temp > Makefile.inc -##sed -i '1i CLASSES=' Makefile.inc - \ No newline at end of file diff --git a/hxmpp.exclude b/hxmpp.exclude index 5d09be7..877d719 100644 --- a/hxmpp.exclude +++ b/hxmpp.exclude @@ -1 +1,3 @@ xmpp.ErrorCondition +xmpp.jingle.RTMP +xmpp.Namespace diff --git a/hxmpp.source b/hxmpp.source new file mode 100644 index 0000000..548cd60 --- /dev/null +++ b/hxmpp.source @@ -0,0 +1,21 @@ + +HXMPP_SRC = jabber/*.hx \ +jabber/client/*.hx \ +jabber/component/*.hx \ +jabber/file/*.hx jabber/file/io/*.hx \ +jabber/jingle/*.hx jabber/jingle/transport/*.hx \ +jabber/remoting/*.hx \ +jabber/stream/*.hx \ +xmpp/*.hx \ +xmpp/dataform/*.hx \ +xmpp/disco/*.hx \ +xmpp/file/*.hx \ +xmpp/filter/*.hx \ +xmpp/jingle/*.hx \ +xmpp/muc/*.hx \ +xmpp/pep/*.hx \ +xmpp/privacylist/*.hx \ +xmpp/pubsub/*.hx \ +xmpp/roster/*.hx \ +xmpp/disco/*.hx \ +xmpp/vcard/*.hx \ diff --git a/hxmpp.stable b/hxmpp.stable new file mode 100644 index 0000000..1a9676c --- /dev/null +++ b/hxmpp.stable @@ -0,0 +1,56 @@ + +STABLE_XMPP = xmpp.Bind \ +xmpp.ChatState \ +xmpp.ChatStateExtension \ +xmpp.Compression \ +xmpp.DataForm \ +xmpp.DateTime \ +xmpp.Delayed \ +xmpp.Error \ +xmpp.ErrorCondition \ +xmpp.IQ \ +xmpp.MUC \ +xmpp.PlainPacket \ +xmpp.Presence \ +xmpp.PrivacyLists \ +xmpp.SASL \ +xmpp.XHTML \ +xmpp.dataform.Field xmpp.dataform.FieldOption xmpp.dataform.FieldType xmpp.dataform.Item xmpp.dataform.Reported \ +xmpp.disco.Identity xmpp.disco.Info xmpp.disco.Item xmpp.disco.Items + +STABLE = jabber.JID \ +jabber.JIDUtil \ +jabber.LastActivity \ +jabber.LastActivityListener \ +jabber.MessageListener \ +jabber.Ping \ +jabber.Pong \ +jabber.PresenceListener \ +jabber.ServiceDiscovery \ +#jabber.SocketConnection \ +jabber.SoftwareVersion \ +jabber.XMPPDebug \ +jabber.XMPPError \ + +STABLE_CLIENT = jabber.client.Stream \ +jabber.client.Account \ +jabber.client.Authentication \ +jabber.client.MUChat \ +jabber.client.NonSASLAuthentication \ +jabber.client.Roster \ +jabber.client.SASLAuthentication \ +jabber.client.VCard \ +jabber.Chat \ +jabber.ChatStateNotification \ +net.sasl.Handshake \ +net.sasl.AnonymousMechanism \ +net.sasl.PlainMechanism + +STABLE_CLIENT_JS = $(STABLE) $(STABLE_CLIENT) \ +jabber.BOSHConnection + +UNSTABLE = jabber.EntityCapabilities \ +jabber.PersonalEvent \ +jabber.PersonalEventListener \ +jabber.PubSub \ + diff --git a/jabber/BOSHConnection.hx b/jabber/BOSHConnection.hx index c6a007a..93bcb82 100644 --- a/jabber/BOSHConnection.hx +++ b/jabber/BOSHConnection.hx @@ -30,6 +30,7 @@ import flash.events.SecurityErrorEvent; // timeout timer (?), added but needed? + // neko/cpp/php // polling /// multiple streams over one connection // secure! @@ -337,7 +338,6 @@ class BOSHConnection extends jabber.stream.Connection { t = x.get( "inactivity" ); if( t != null ) inactivity = Std.parseInt( t ); // #if XMPP_DEBUG - // trace("RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR"); // XMPPDebug.inc( t ); // #end __onConnect(); diff --git a/jabber/Lib.hx b/jabber/Lib.hx index 71dcc1d..44aa070 100644 --- a/jabber/Lib.hx +++ b/jabber/Lib.hx @@ -29,7 +29,7 @@ class Lib { #if JABBER_SOCKETBRIDGE - public static var defaultSocketBridgeID = "f9bridge"; + public static var defaultSocketBridgeID = "socketbridge"; static function initSocketBridge( ?id : String ) { if( id == null ) id = defaultSocketBridgeID; diff --git a/jabber/MUCUtil.hx b/jabber/MUCUtil.hx index fc2fea1..e7ecce8 100644 --- a/jabber/MUCUtil.hx +++ b/jabber/MUCUtil.hx @@ -37,7 +37,7 @@ class MUCUtil { /** Returns Bool if the given string is a full valid muchat address (including occupant name). */ - public static inline function isValidFull( t : String ) : Bool { + public static inline function isValidFull( t : String ) : Bool { return EREG_FULL.match( t ); } diff --git a/jabber/PubSub.hx b/jabber/PubSub.hx index efd753f..68869a2 100644 --- a/jabber/PubSub.hx +++ b/jabber/PubSub.hx @@ -18,8 +18,7 @@ package jabber; /** - PubSub client implementation.<br/> - <a href="http://xmpp.org/extensions/xep-0060.html">XEP-0060: Publish-Subscribe</a> + PubSub client implementation. <a href="http://xmpp.org/extensions/xep-0060.html">XEP-0060: Publish-Subscribe</a> */ class PubSub { @@ -162,9 +161,9 @@ class PubSub { } ); } + //TODO why subid required? /** Load all items from the given node. - TODO why subid required? */ public function loadItems( node : String, ?subid : String, ?maxItems : Int, ?ids : Array<String> ) { var iq = new xmpp.IQ( null, null, service ); @@ -181,9 +180,9 @@ class PubSub { } ); } + //TODO ?? retractItems( node : String, ids : Array<String> ) /** Publisher deletes an item once it has been published to a node that supports persistent items. - //TODO ?? retractItems( node : String, ids : Array<String> ) */ public function retract( retract : xmpp.pubsub.Retract ) { var iq = new xmpp.IQ( xmpp.IQType.set, null, service ); diff --git a/jabber/SocketConnection.hx b/jabber/SocketConnection.hx index a0dbf48..f08297d 100644 --- a/jabber/SocketConnection.hx +++ b/jabber/SocketConnection.hx @@ -68,8 +68,7 @@ class SocketConnection extends jabber.stream.Connection { ?secure : Bool = false , ?timeout : Int = 10, ?maxBufSize : Int = 131072 ) { - if( port == null ) - port = 5222; + if( port == null ) port = 5222; super( host ); this.port = port; #if (flash10||neko||php||cpp) @@ -128,18 +127,18 @@ class SocketConnection extends jabber.stream.Connection { connected = true; __onConnect(); #else - #if flash10 - socket.timeout = timeout*1000; - #end + #if flash10 socket.timeout = timeout*1000; #end socket.connect( host, port ); #end } public override function disconnect() { if( !connected ) return; - #if (neko||php||cpp) reading = false; #end - connected = #if (neko||php||cpp) reading = #end false; - socket.close(); + #if (neko||php||cpp) + reading = false; + #end + connected = false; + try socket.close() catch( e : Dynamic ) {}; } public override function read( ?yes : Bool = true ) : Bool { @@ -170,7 +169,7 @@ class SocketConnection extends jabber.stream.Connection { public override function write( t : String ) : Bool { if( !connected || t == null || t.length == 0 ) return false; - #if flash9 + #if flash socket.writeUTFBytes( t ); socket.flush(); #elseif (neko||php||cpp) diff --git a/jabber/Stream.hx b/jabber/Stream.hx index 6a9134d..76afccf 100644 --- a/jabber/Stream.hx +++ b/jabber/Stream.hx @@ -29,7 +29,6 @@ import util.Base64; private typedef TDataFilter = { function filterData( t : haxe.io.Bytes ) : haxe.io.Bytes; } - private typedef TDataInterceptor = { function interceptData( t : haxe.io.Bytes ) : haxe.io.Bytes; } @@ -65,7 +64,6 @@ class Stream { //public static function onXMPP( s : Stream, p : xmpp.Packet, out : Bool ) : Void; public static function onXMPP(default,null) : EventDispatcher<XMPPTransfer>; public static function debugXMPP( t : String ) { - } #end */ @@ -77,16 +75,16 @@ class Stream { public var status : StreamStatus; public var cnx(default,setConnection) : Connection; - public var id(default,null) : String; - public var lang(default,null) : String; public var jidstr(getJIDStr,null) : String; - public var server(default,null) : Server; public var features(default,null) : StreamFeatures; + public var server(default,null) : Server; + public var id(default,null) : String; + public var lang(default,null) : String; public var version : Bool; //Indicates if the version number of the XMPP stream ("1.0") should get added to the stream opening XML element. //public var dataFilters : List<TDataFilter>; //public var dataInterceptors : List<TDataInterceptor>; /** Indicates if this streams connection is a http connection */ - public var http(default,null) : Bool; + public var http(default,null) : Bool; //TODO move to: jabber.stream.Connection var collectors : List<PacketCollector>; // public var packetCollectors : Array<TPacketCollector>; var interceptors : List<TPacketInterceptor>; // public var packetInterceptors : Array<TPacketCollector>; @@ -108,8 +106,10 @@ class Stream { //dataInterceptors = new List(); if( cnx != null ) setConnection( cnx ); + + // TODO HACK #if (flash&&JABBER_CONSOLE) - XMPPDebug.stream = this; // TODO HACK + XMPPDebug.stream = this; #end } @@ -189,14 +189,14 @@ class Stream { public function sendData( t : String ) : String { if( !cnx.connected ) return null; + //TODO //for( i in dataInterceptors ) //t = i.interceptData( t ); if( !cnx.write( t ) ) return null; numPacketsSent++; #if XMPP_DEBUG - XMPPDebug.out( t ); - //XMPPDebug.outPacket( t ); + XMPPDebug.out( t );//XMPPDebug.outPacket( t ); #end return t; } @@ -215,14 +215,6 @@ class Stream { */ /** - Runs the XMPP packet interceptor on the given packet. - */ - public function interceptPacket( p : xmpp.Packet ) : xmpp.Packet { - for( i in interceptors ) i.interceptPacket( p ); - return p; - } - - /** Send an IQ packet and forward the collected response to the given handler function. */ public function sendIQ( iq : xmpp.IQ, ?handler : xmpp.IQ->Void, @@ -261,6 +253,22 @@ class Stream { } + /* + public function sendCollect<T>( p : T, handler : T->Void ) : { + if( p.id == null ) p.id = nextID(); + collect( [cast new PacketIDFilter( p.id )], handler, false ); + sendPacket( p ); + } + */ + + /** + Runs the XMPP packet interceptor on the given packet. + */ + public function interceptPacket( p : xmpp.Packet ) : xmpp.Packet { + for( i in interceptors ) i.interceptPacket( p ); + return p; + } + /** Creates, adds and returns a packet collector. */ @@ -312,10 +320,8 @@ class Stream { if( status == StreamStatus.closed ) return -1; //TODO .. data filters - // var t : String = buf.readString( bufpos, buflen ); - //TODO - /* + /*//TODO if( xmpp.Stream.REGEXP_CLOSE.match( t ) ) { close( true ); return -1; @@ -326,58 +332,23 @@ class Stream { close( true ); return -1; } else if( StringTools.startsWith( t, '</stream:error' ) ) { - //close( true ); - //TODO - return -1; - } - //TODO - /* - if( xmpp.Stream.REGEXP_ERROR.match( t ) ) { - //if( ~/stream:error/.match( t ) ) { - var err : xmpp.StreamError = null; - try { - err = xmpp.StreamError.parse( Xml.parse( t ) ); - } catch( e : Dynamic ) { - onClose( "Invalid XMPP stream "+e ); - close( true ); - return -1; - } - onClose( err ); close( true ); return -1; } - */ switch( status ) { case closed : - return -1;//buflen; //hm? + return -1;//buflen? case pending : return processStreamInit( XmlUtil.removeXmlHeader( t ), buflen ); case open : - - // HACK flash/js Xml bug ! - #if (flash||js) - if( t.charAt( 0 ) != "<" || t.charAt( t.length-1 ) != ">" ) { - return 0; - } - /* - if( !StringTools.startsWith(t,"<") || !StringTools.endsWith(t, ">") ) { - if( !REG_HACK.match( t ) ) { - #if JABBER_DEBUG - trace( "Invalid XML " ); - #end - return 0; - } - } - */ - #end // filter data here ? var x : Xml = null; try { x = Xml.parse( t ); } catch( e : Dynamic ) { - //#if JABBER_DEBUG - //trace("WAIT FOR MORE "+t,"warn" ); - //#end + #if JABBER_DEBUG + trace( "Packet incomplete, wating for more data ..", "info" ); + #end return 0; // wait for more data } handleXml( x ); @@ -386,19 +357,19 @@ class Stream { return 0; } - //HACK - #if (flash||js) - //static inline var REG_HACK = ~/(.+)(\/[a-zA-Z-]*)>$/; - #end - //HACK - /** Inject incoming XML data to handle.<br/> - Returns array of handled packets. + Returns array of handled XMPP packets. */ public function handleXml( x : Xml ) : Array<xmpp.Packet> { var ps = new Array<xmpp.Packet>(); for( e in x.elements() ) { + //TODO + /* + var p = xmpp.Packet.parse( e ); + if( p != null && handlePacket( p ) ) + ps.push( p ); + */ var p = xmpp.Packet.parse( e ); handlePacket( p ); ps.push( p ); @@ -416,27 +387,28 @@ class Stream { #end var collected = false; for( c in collectors ) { - //if( c == null ) { - //collectors.remove( c ); - //} + /* + if( c.handlers.length == 0 ) { + collectors.remove( c ); + continue; + } + */ if( c.accept( p ) ) { collected = true; - //if( c.deliver == null ) - // collectors.remove( c ); - //if( !c.deliver( p ) ) { - //} c.deliver( p ); - if( !c.permanent ) + if( !c.permanent ) { collectors.remove( c ); - if( c.block ) + } + if( c.block ) { break; + } } } if( !collected ) { #if JABBER_DEBUG trace( "incoming '"+Type.enumConstructor( p._type )+"' packet not handled ( "+p.from+" -> "+p.to+" )", "warn" ); #end - if( p._type == xmpp.PacketType.iq ) { // send a 'feature not implemented' response + if( p._type == xmpp.PacketType.iq ) { // send 'feature not implemented' response var q : xmpp.IQ = cast p; if( q.type != xmpp.IQType.error ) { var r = new xmpp.IQ( xmpp.IQType.error, p.id, p.from, p.to ); @@ -457,11 +429,7 @@ class Stream { */ function processStreamInit( t : String, buflen : Int ) : Int { - #if JABBER_DEBUG return throw "Abstract method"; - #else - return -1; - #end } function closeHandler() { diff --git a/jabber/XMPPDebug.hx b/jabber/XMPPDebug.hx index eedcef9..456ee6b 100644 --- a/jabber/XMPPDebug.hx +++ b/jabber/XMPPDebug.hx @@ -58,9 +58,9 @@ class XMPPDebug { return; } ExternalInterface.addCallback( "sendData", function(t:String){ - if( stream != null ) - return stream.sendData( t ); - return null; + if( stream == null ) + return null; + return stream.sendData( t ); } ); #end #elseif js @@ -73,6 +73,21 @@ class XMPPDebug { } #end + /* + public static function outPacket( p : xmpp.Packet ) { + var v = haxe.Serializer.run( p ); + try { + #if flash + ExternalInterface.call( 'hxmpp.Console.printPacket("'+v+'",'+out+')' ); + #elseif js + untyped hxmpp.Console.printPacket( v, out ); + #end + } catch( e : Dynamic ) { + trace( "HXMPP.console debugging error: "+e, "warn" ); + } + } + */ + public static function inc( t : String ) { #if JABBER_CONSOLE printToXMPPConsole( t, false ); @@ -89,7 +104,7 @@ class XMPPDebug { #if JABBER_CONSOLE static function printToXMPPConsole( t : String, out : Bool ) { - var v = haxe.Serializer.run( t ); + var v = haxe.Serializer.run( t ); try { #if flash ExternalInterface.call( 'hxmpp.Console.print("'+v+'",'+out+')' ); @@ -149,8 +164,7 @@ class XMPPDebug { untyped console[level]( dir+t ); #end } else { - //TODO - haxe.Log.trace( t, { className : "", methodName : "", fileName : dir, lineNumber : 0, customParams : [] } ); + //haxe.Log.trace( t, { className : "", methodName : "", fileName : dir, lineNumber : 0, customParams : [] } ); } } diff --git a/jabber/client/Authentication.hx b/jabber/client/Authentication.hx index d3cd850..6635c2d 100644 --- a/jabber/client/Authentication.hx +++ b/jabber/client/Authentication.hx @@ -18,7 +18,7 @@ package jabber.client; /** - Abstract client account authentication. + Abstract client authentication. */ class Authentication { @@ -33,7 +33,11 @@ class Authentication { } public function authenticate( password : String, ?resource : String ) : Bool { + #if JABBER_DEBUG return throw "Abstract error"; + #else + return false; + #end } } diff --git a/jabber/client/NonSASLAuth.hx b/jabber/client/NonSASLAuth.hx new file mode 100644 index 0000000..0acb6b8 --- /dev/null +++ b/jabber/client/NonSASLAuth.hx @@ -0,0 +1,81 @@ +/* + * This file is part of HXMPP. + * Copyright (c)2009 http://www.disktree.net + * + * HXMPP is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HXMPP 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with HXMPP. If not, see <http://www.gnu.org/licenses/>. +*/ +package jabber.client; + +/** + <a href="http://xmpp.org/extensions/xep-0078.html">XEP-0078: Multi-User Chat</a><br> +*/ +class NonSASLAuth extends Authentication { + + public var active(default,null) : Bool; + public var usePlainText(default,null) : Bool; + public var username(default,null) : String; + public var password(default,null) : String; + + public function new( stream : Stream, + /*?onSuccess : Void->Void, ?onFail : jabber.XMPPError->Void,*/ + ?usePlainText : Bool = false ) { + #if JABBER_DEBUG + if( stream.http ) + throw "NonSASL authentication is not supported on HTTP/BOSH connections"; + #end + super( stream ); + this.usePlainText = usePlainText; + username = stream.jid.node; + active = false; + } + + public override function authenticate( password : String, ?resource : String ) { + if( active ) + throw "Authentication in progress"; + this.password = password; + if( resource != null ) { + this.resource = resource; + stream.jid.resource = resource; // update stream jid resource + } + active = true; + var iq = new xmpp.IQ(); + iq.x = new xmpp.Auth( username ); + stream.sendIQ( iq, handleResponse ); + return true; + } + + + function handleResponse( iq : xmpp.IQ ) { + switch( iq.type ) { + case result : + var hasDigest = ( !usePlainText && iq.x.toXml().elementsNamed( "digest" ).next() != null ); + var r = new xmpp.IQ( xmpp.IQType.set ); + r.x = if( hasDigest ) new xmpp.Auth( username, null, crypt.SHA1.encode( stream.id+password ), resource ); + else new xmpp.Auth( username, password, null, resource ); + stream.sendIQ( r, handleResult ); + case error : onFail( new jabber.XMPPError( this, iq ) ); + default : //# + } + } + + function handleResult( iq : xmpp.IQ ) { + active = false; + switch( iq.type ) { + case result : onSuccess(); + case error : onFail( new jabber.XMPPError( this, iq ) ); + default : //# + } + } + +} diff --git a/jabber/client/NonSASLAuthentication.hx b/jabber/client/NonSASLAuthentication.hx deleted file mode 100644 index 4a689e9..0000000 --- a/jabber/client/NonSASLAuthentication.hx +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of HXMPP. - * Copyright (c)2009 http://www.disktree.net - * - * HXMPP is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * HXMPP 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with HXMPP. If not, see <http://www.gnu.org/licenses/>. -*/ -package jabber.client; - -/** - <a href="http://xmpp.org/extensions/xep-0078.html">XEP-0078: Multi-User Chat</a><br> -*/ -class NonSASLAuthentication extends Authentication { - - public var active(default,null) : Bool; - public var usePlainText(default,null) : Bool; - public var username(default,null) : String; - public var password(default,null) : String; - - public function new( stream : Stream, - /*?onSuccess : Void->Void, ?onFail : jabber.XMPPError->Void,*/ - ?usePlainText : Bool = false ) { - #if JABBER_DEBUG - if( stream.http ) - throw "NonSASL authentication is not supported on HTTP/BOSH connections"; - #end - super( stream ); - this.usePlainText = usePlainText; - username = stream.jid.node; - active = false; - } - - public override function authenticate( password : String, ?resource : String ) { - if( active ) - throw "Authentication in progress"; - this.password = password; - if( resource != null ) { - this.resource = resource; - stream.jid.resource = resource; // update stream jid resource - } - active = true; - var iq = new xmpp.IQ(); - iq.x = new xmpp.Auth( username ); - stream.sendIQ( iq, handleResponse ); - return true; - } - - - function handleResponse( iq : xmpp.IQ ) { - switch( iq.type ) { - case result : - var hasDigest = ( !usePlainText && iq.x.toXml().elementsNamed( "digest" ).next() != null ); - var r = new xmpp.IQ( xmpp.IQType.set ); - trace(stream.id+" /// "+password); - r.x = if( hasDigest ) new xmpp.Auth( username, null, crypt.SHA1.encode( stream.id+password ), resource ); - else new xmpp.Auth( username, password, null, resource ); - stream.sendIQ( r, handleResult ); - case error : onFail( new jabber.XMPPError( this, iq ) ); - default : //# - } - } - - function handleResult( iq : xmpp.IQ ) { - active = false; - switch( iq.type ) { - case result : onSuccess(); - case error : onFail( new jabber.XMPPError( this, iq ) ); - default : //# - } - } - -} diff --git a/jabber/client/Roster.hx b/jabber/client/Roster.hx index 9cb49eb..ec18349 100644 --- a/jabber/client/Roster.hx +++ b/jabber/client/Roster.hx @@ -24,8 +24,6 @@ import xmpp.roster.Item; import xmpp.roster.AskType; import xmpp.roster.Subscription; -/** -*/ enum RosterSubscriptionMode { /** Accept all subscription and unsubscription requests. */ acceptAll( subscribe : Bool ); diff --git a/jabber/client/SASLAuth.hx b/jabber/client/SASLAuth.hx new file mode 100644 index 0000000..e2e5c14 --- /dev/null +++ b/jabber/client/SASLAuth.hx @@ -0,0 +1,195 @@ +/* + * This file is part of HXMPP. + * Copyright (c)2009 http://www.disktree.net + * + * HXMPP is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HXMPP 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with HXMPP. If not, see <http://www.gnu.org/licenses/>. +*/ +package jabber.client; + +import jabber.stream.PacketCollector; +import xmpp.IQ; +import xmpp.IQType; +import xmpp.filter.PacketNameFilter; +import xmpp.filter.FilterGroup; + +// try another mechanism on fail (?) + +/** + Responsible for authenticating a client account using SASL, + binding the resource to the connection and establishing a session with the server.<br/> + <a href="http://xmpp.org/rfcs/rfc3920.html#sasl">RFC3920-SASL</a><br/> + <a href="http://xmpp.org/rfcs/rfc3920.html#bind">RFC3920-BIND</a><br/> +*/ +class SASLAuth extends Authentication { + + public dynamic function onNegotiated() : Void; + + /** Used SASL method */ + public var handshake(default,null) : net.sasl.Handshake; + /** Available mechanisms ids (server) */ + public var mechanisms(default,null) : Array<String>; + //public var negotiated(default,null) : Bool; + + var onStreamOpenHandler : Void->Void; + var c_challenge : PacketCollector; + var c_fail : PacketCollector; + var c_success : PacketCollector; + + public function new( stream : Stream, mechanisms : Iterable<net.sasl.Mechanism> ) { + var x = stream.server.features.get( "mechanisms" ); + if( x == null ) + throw "Server does't support SASL"; + if( mechanisms == null || Lambda.count( mechanisms ) == 0 ) + throw "No SASL mechanisms given"; + super( stream ); + this.mechanisms = xmpp.SASL.parseMechanisms( x ); + handshake = new net.sasl.Handshake(); + for( m in mechanisms ) + handshake.mechanisms.push( m ); + } + + /** + Inits SASL authentication. + Returns false if no compatible SASL mechanism was found. + */ + public override function authenticate( password : String, ?resource : String ) : Bool { + this.resource = resource; + // update stream jid resource + if( stream.jid != null && resource != null ) + stream.jid.resource = resource; + // locate mechanism to use. + if( handshake.mechanism == null ) { + for( amechs in mechanisms ) { + for( m in handshake.mechanisms ) { + if( m.id != amechs ) + continue; + handshake.mechanism = m; + break; + } + if( handshake.mechanism != null ) + break; + } + } + if( handshake.mechanism == null ) { + #if JABBER_DEBUG + trace( "No matching SASL mechanism found.", "warn" ); + #end + return false; + } + // collect failures + var f = new FilterGroup(); + f.add( new PacketNameFilter( ~/failure/ ) ); //? + f.add( new PacketNameFilter( ~/not-authorized/ ) ); + f.add( new PacketNameFilter( ~/aborted/ ) ); + f.add( new PacketNameFilter( ~/incorrect-encoding/ ) ); + f.add( new PacketNameFilter( ~/invalid-authzid/ ) ); + f.add( new PacketNameFilter( ~/invalid-mechanism/ ) ); + f.add( new PacketNameFilter( ~/mechanism-too-weak/ ) ); + f.add( new PacketNameFilter( ~/temporary-auth-failure/ ) ); + c_fail = new PacketCollector( [cast f], handleSASLFailed ); + stream.addCollector( c_fail ); + // collect success response + c_success = new PacketCollector( [cast new PacketNameFilter( ~/success/ )], handleSASLSuccess ); + stream.addCollector( c_success ); + // collect challenge response + c_challenge = new PacketCollector( [cast new PacketNameFilter( ~/challenge/ )], handleSASLChallenge, true ); + stream.addCollector( c_challenge ); + // init auth + var t = handshake.mechanism.createAuthenticationText( stream.jid.node, stream.jid.domain, password ); + if( t != null ) t = util.Base64.encode( t ); + return stream.sendData( xmpp.SASL.createAuthXml( handshake.mechanism.id, t ).toString() ) != null; + } + + function handleSASLFailed( p : xmpp.Packet ) { + removeSASLCollectors(); + onFail(); + } + + function handleSASLChallenge( p : xmpp.Packet ) { + // create/send challenge response + var c = p.toXml().firstChild().nodeValue; + var r = util.Base64.encode( handshake.getChallengeResponse( c ) ); + stream.sendData( xmpp.SASL.createResponseXml( r ).toString() ); + } + + function handleSASLSuccess( p : xmpp.Packet ) { + removeSASLCollectors(); // remove the challenge collector + onStreamOpenHandler = stream.onOpen; // relay the stream open event + stream.onOpen = handleStreamOpen; + onNegotiated(); + //stream.version = false; + stream.open(); // re-open XMPP stream + //return p.toString().length; + } + + function handleStreamOpen() { + stream.onOpen = onStreamOpenHandler; + //onStreamOpenHandler = null; + if( stream.server.features.exists( "bind" ) ) { // bind the resource + var iq = new IQ( IQType.set ); + iq.x = new xmpp.Bind( ( handshake.mechanism.id == "ANONYMOUS" ) ? null : resource ); + stream.sendIQ( iq, handleBind ); + } else { + onSuccess(); // TODO ? + } + } + + function handleBind( iq : IQ ) { + switch( iq.type ) { + case IQType.result : + /* + // TODO required ? + var b = xmpp.Bind.parse( iq.x.toXml() ); + if( jabber.util.JIDUtil.parseResource( b.jid ) != resource ) { + throw "Unexpected resource bound ?"; + } + */ + //onBind(); + var b = xmpp.Bind.parse( iq.x.toXml() ); + var jid = new jabber.JID( b.jid ); + stream.jid.node = jid.node; + stream.jid.resource = jid.resource; + if( stream.server.features.exists( "session" ) ) { + // init session + var iq = new IQ( IQType.set ); + iq.x = new xmpp.PlainPacket( Xml.parse( '<session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>' ).firstElement() ); + stream.sendIQ( iq, handleSession ); + } else + onSuccess(); //? + case IQType.error : + onFail( new jabber.XMPPError( this, iq ) ); + } + } + + function handleSession( iq : IQ ) { + switch( iq.type ) { + case result : + ////onSession(); + onSuccess(); + case error : + onFail( new jabber.XMPPError( this, iq ) ); + default : //# + } + } + + function removeSASLCollectors() { + stream.removeCollector( c_challenge ); + c_challenge = null; + stream.removeCollector( c_fail ); + c_fail = null; + stream.removeCollector( c_success ); + c_success = null; + } + +} diff --git a/jabber/client/SASLAuthentication.hx b/jabber/client/SASLAuthentication.hx deleted file mode 100644 index d5696a7..0000000 --- a/jabber/client/SASLAuthentication.hx +++ /dev/null @@ -1,195 +0,0 @@ -/* - * This file is part of HXMPP. - * Copyright (c)2009 http://www.disktree.net - * - * HXMPP is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * HXMPP 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with HXMPP. If not, see <http://www.gnu.org/licenses/>. -*/ -package jabber.client; - -import jabber.stream.PacketCollector; -import xmpp.IQ; -import xmpp.IQType; -import xmpp.filter.PacketNameFilter; -import xmpp.filter.FilterGroup; - -// try another mechanism on fail (?) - -/** - Responsible for authenticating a client account using SASL, - binding the resource to the connection and establishing a session with the server.<br/> - <a href="http://xmpp.org/rfcs/rfc3920.html#sasl">RFC3920-SASL</a><br/> - <a href="http://xmpp.org/rfcs/rfc3920.html#bind">RFC3920-BIND</a><br/> -*/ -class SASLAuthentication extends Authentication { - - public dynamic function onNegotiated() : Void; - - /** Used SASL method */ - public var handshake(default,null) : net.sasl.Handshake; - /** Available mechanisms ids (server) */ - public var mechanisms(default,null) : Array<String>; - //public var negotiated(default,null) : Bool; - - var onStreamOpenHandler : Void->Void; - var c_challenge : PacketCollector; - var c_fail : PacketCollector; - var c_success : PacketCollector; - - public function new( stream : Stream, mechanisms : Iterable<net.sasl.Mechanism> ) { - var x = stream.server.features.get( "mechanisms" ); - if( x == null ) - throw "Server does't support SASL"; - if( mechanisms == null || Lambda.count( mechanisms ) == 0 ) - throw "No SASL mechanisms given"; - super( stream ); - this.mechanisms = xmpp.SASL.parseMechanisms( x ); - handshake = new net.sasl.Handshake(); - for( m in mechanisms ) - handshake.mechanisms.push( m ); - } - - /** - Inits SASL authentication. - Returns false if no compatible SASL mechanism was found. - */ - public override function authenticate( password : String, ?resource : String ) : Bool { - this.resource = resource; - // update stream jid resource - if( stream.jid != null && resource != null ) - stream.jid.resource = resource; - // locate mechanism to use. - if( handshake.mechanism == null ) { - for( amechs in mechanisms ) { - for( m in handshake.mechanisms ) { - if( m.id != amechs ) - continue; - handshake.mechanism = m; - break; - } - if( handshake.mechanism != null ) - break; - } - } - if( handshake.mechanism == null ) { - #if JABBER_DEBUG - trace( "No matching SASL mechanism found.", "warn" ); - #end - return false; - } - // collect failures - var f = new FilterGroup(); - f.add( new PacketNameFilter( ~/failure/ ) ); //? - f.add( new PacketNameFilter( ~/not-authorized/ ) ); - f.add( new PacketNameFilter( ~/aborted/ ) ); - f.add( new PacketNameFilter( ~/incorrect-encoding/ ) ); - f.add( new PacketNameFilter( ~/invalid-authzid/ ) ); - f.add( new PacketNameFilter( ~/invalid-mechanism/ ) ); - f.add( new PacketNameFilter( ~/mechanism-too-weak/ ) ); - f.add( new PacketNameFilter( ~/temporary-auth-failure/ ) ); - c_fail = new PacketCollector( [cast f], handleSASLFailed ); - stream.addCollector( c_fail ); - // collect success response - c_success = new PacketCollector( [cast new PacketNameFilter( ~/success/ )], handleSASLSuccess ); - stream.addCollector( c_success ); - // collect challenge response - c_challenge = new PacketCollector( [cast new PacketNameFilter( ~/challenge/ )], handleSASLChallenge, true ); - stream.addCollector( c_challenge ); - // init auth - var t = handshake.mechanism.createAuthenticationText( stream.jid.node, stream.jid.domain, password ); - if( t != null ) t = util.Base64.encode( t ); - return stream.sendData( xmpp.SASL.createAuthXml( handshake.mechanism.id, t ).toString() ) != null; - } - - function handleSASLFailed( p : xmpp.Packet ) { - removeSASLCollectors(); - onFail(); - } - - function handleSASLChallenge( p : xmpp.Packet ) { - // create/send challenge response - var c = p.toXml().firstChild().nodeValue; - var r = util.Base64.encode( handshake.getChallengeResponse( c ) ); - stream.sendData( xmpp.SASL.createResponseXml( r ).toString() ); - } - - function handleSASLSuccess( p : xmpp.Packet ) { - removeSASLCollectors(); // remove the challenge collector - onStreamOpenHandler = stream.onOpen; // relay the stream open event - stream.onOpen = handleStreamOpen; - onNegotiated(); - //stream.version = false; - stream.open(); // re-open XMPP stream - //return p.toString().length; - } - - function handleStreamOpen() { - stream.onOpen = onStreamOpenHandler; - //onStreamOpenHandler = null; - if( stream.server.features.exists( "bind" ) ) { // bind the resource - var iq = new IQ( IQType.set ); - iq.x = new xmpp.Bind( ( handshake.mechanism.id == "ANONYMOUS" ) ? null : resource ); - stream.sendIQ( iq, handleBind ); - } else { - onSuccess(); // TODO ? - } - } - - function handleBind( iq : IQ ) { - switch( iq.type ) { - case IQType.result : - /* - // TODO required ? - var b = xmpp.Bind.parse( iq.x.toXml() ); - if( jabber.util.JIDUtil.parseResource( b.jid ) != resource ) { - throw "Unexpected resource bound ?"; - } - */ - //onBind(); - var b = xmpp.Bind.parse( iq.x.toXml() ); - var jid = new jabber.JID( b.jid ); - stream.jid.node = jid.node; - stream.jid.resource = jid.resource; - if( stream.server.features.exists( "session" ) ) { - // init session - var iq = new IQ( IQType.set ); - iq.x = new xmpp.PlainPacket( Xml.parse( '<session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>' ) ); - stream.sendIQ( iq, handleSession ); - } else - onSuccess(); //? - case IQType.error : - onFail( new jabber.XMPPError( this, iq ) ); - } - } - - function handleSession( iq : IQ ) { - switch( iq.type ) { - case result : - ////onSession(); - onSuccess(); - case error : - onFail( new jabber.XMPPError( this, iq ) ); - default : //# - } - } - - function removeSASLCollectors() { - stream.removeCollector( c_challenge ); - c_challenge = null; - stream.removeCollector( c_fail ); - c_fail = null; - stream.removeCollector( c_success ); - c_success = null; - } - -} diff --git a/jabber/client/Stream.hx b/jabber/client/Stream.hx index 16b0eca..43946a7 100644 --- a/jabber/client/Stream.hx +++ b/jabber/client/Stream.hx @@ -31,7 +31,6 @@ class Stream extends jabber.Stream { public static var defaultPort = PORT_STANDARD; public var jid(default,setJID) : JID; - // public var tls(default,null) : Bool; public function new( ?jid : JID, ?cnx : Connection, ?version : Bool = true ) { if( jid == null ) @@ -39,7 +38,6 @@ class Stream extends jabber.Stream { super( cnx ); this.jid = jid; this.version = version; - //this.tls = tls; } override function getJIDStr() : String { @@ -54,12 +52,11 @@ class Stream extends jabber.Stream { override function processStreamInit( t : String, buflen : Int ) : Int { if( http ) { - var sx = Xml.parse( t ).firstElement(); - var sf = sx.firstElement(); #if XMPP_DEBUG - //jabber.XMPPDebug.inc( sf.toString() ); jabber.XMPPDebug.inc( t ); #end + var x = Xml.parse( t ).firstElement(); + var sf = x.firstElement(); parseStreamFeatures( sf ); status = StreamStatus.open; onOpen(); @@ -70,7 +67,7 @@ class Stream extends jabber.Stream { return 0; } if( id == null ) { // parse open stream - var s = t.substr( 0, sei ) + " />"; + var s = t.substr( 0, sei )+" />"; #if XMPP_DEBUG jabber.XMPPDebug.inc( s ); #end @@ -83,6 +80,7 @@ class Stream extends jabber.Stream { } } if( id == null ) { + //TODO throw error #if JABBER_DEBUG trace( "Invalid XMPP stream, missing ID" ); #end @@ -96,13 +94,13 @@ class Stream extends jabber.Stream { } } var sfi = t.indexOf( "<stream:features>" ); - var sf = t.substr( t.indexOf( "<stream:features>" ) ); + var sf = t.substr( sfi ); if( sfi != -1 ) { try { - var sfx = Xml.parse( sf ).firstElement(); - parseStreamFeatures( sfx ); + var x = Xml.parse( sf ).firstElement(); + parseStreamFeatures( x ); #if XMPP_DEBUG - jabber.XMPPDebug.inc( sfx.toString() ); + jabber.XMPPDebug.inc( x.toString() ); #end status = StreamStatus.open; onOpen(); @@ -133,8 +131,9 @@ class Stream extends jabber.Stream { } */ - function parseStreamFeatures( x : Xml ) { + inline function parseStreamFeatures( x : Xml ) { for( e in x.elements() ) server.features.set( e.nodeName, e ); } + } diff --git a/jabber/component/Stream.hx b/jabber/component/Stream.hx index 7467f7a..7e16b00 100644 --- a/jabber/component/Stream.hx +++ b/jabber/component/Stream.hx @@ -86,13 +86,34 @@ class Stream extends jabber.Stream { cnx.read( true ); } + //TODO!!!!!!!!! override function processStreamInit( t : String, len : Int ) { - //TODO var i = t.indexOf( ">" ); if( i == -1 ) return 0; + /* + try { + var x = Xml.parse( t ).firstChild(); + for( e in x.elements() ) { + trace(e.nodeName); + if( e.nodeName == "stream:error" ) { + trace(e.firstChild().nodeName); + onClose( e.firstChild().nodeName ); + return -1; + } + } + } catch( e : Dynamic ) { + trace("ERRORERRORERRORERROR "+e); + } + trace(t); + */ + //TODO id = Xml.parse( t+"</stream:stream>" ).firstChild().get( "id" ); + //.. status = jabber.StreamStatus.open; + #if XMPP_DEBUG + jabber.XMPPDebug.inc( t ); + #end onOpen(); collectors.add( new jabber.stream.PacketCollector( [ cast new xmpp.filter.PacketNameFilter( ~/handshake/ ) ], readyHandler, false ) ); sendData( util.XmlUtil.createElement( "handshake", Xml.createPCData( crypt.SHA1.encode( id+secret ) ).toString() ).toString() ); diff --git a/jabber/file/FileTransfer.hx b/jabber/file/FileTransfer.hx index d9bfc1e..1d298bf 100644 --- a/jabber/file/FileTransfer.hx +++ b/jabber/file/FileTransfer.hx @@ -23,9 +23,9 @@ package jabber.file; class FileTransfer { //public dynamic function onReject( t : Transfer ) : Void; - public dynamic function onInit( t : FileTransfer ) : Void; - public dynamic function onComplete( t : FileTransfer ) : Void; - public dynamic function onFail( t : FileTransfer, e : jabber.XMPPError ) : Void; + public dynamic function onInit( ft : FileTransfer ) : Void; + public dynamic function onComplete( ft : FileTransfer ) : Void; + public dynamic function onFail( ft : FileTransfer, e : jabber.XMPPError ) : Void; public var stream(default,null) : jabber.Stream; /** The namespace of the transfer method used */ @@ -46,7 +46,9 @@ class FileTransfer { } public function init( input : haxe.io.Input ) { + #if JABBER_DEBUG throw "Abstract method"; + #end } } diff --git a/jabber/file/io/ByteStreamInput.hx b/jabber/file/io/ByteStreamInput.hx index 741214c..51c01bd 100644 --- a/jabber/file/io/ByteStreamInput.hx +++ b/jabber/file/io/ByteStreamInput.hx @@ -52,9 +52,8 @@ typedef Buffer = { /** flash9,neko,cpp,php. Socket bytestream input. - !Attention: PHP does not support threads, means, transfer blocks until ended! + !Attention: PHP does not support threads, which means the transfer will block until finished. */ -//TODO SockInput //TODO SOCKSInput class ByteStreamInput { diff --git a/jabber/file/io/ByteStreamOutput.hx b/jabber/file/io/ByteStreamOutput.hx index f1d304b..5744d5c 100644 --- a/jabber/file/io/ByteStreamOutput.hx +++ b/jabber/file/io/ByteStreamOutput.hx @@ -33,8 +33,8 @@ enum SOCKS5State { } + //TODO SOCKS5 server /** - TODO SOCKS5 server neko,cpp. */ diff --git a/jabber/stream/Connection.hx b/jabber/stream/Connection.hx index 694e2b0..7c096cc 100644 --- a/jabber/stream/Connection.hx +++ b/jabber/stream/Connection.hx @@ -33,7 +33,7 @@ class Connection { public var __onData : haxe.io.Bytes->Int->Int->Int; /** Callback connection level errors */ - public var __onError : String->Void; + public var __onError : String->Void; //TODO remove, use: __onDisconnect(?e) /** Server IP/hostname */ public var host(default,null) : String; @@ -60,28 +60,35 @@ class Connection { Try to connect the stream data connection. */ public function connect() { + #if JABBER_DEBUG throw "Abstract method"; + #end } /** Disconnects stream connection. */ public function disconnect() { //: Bool + #if JABBER_DEBUG throw "Abstract method"; + #end } /** Starts/Stops reading data input. */ public function read( ?yes : Bool = true ) : Bool { - return throw "Abstract method"; + return false; } /** Send string. */ public function write( t : String ) : Bool { + #if JABBER_DEBUG return throw "Abstract method"; + #end + return false; } //TODO diff --git a/out/hxmpp-debug.swc b/out/hxmpp-debug.swc deleted file mode 100644 index fa3e5a9..0000000 Binary files a/out/hxmpp-debug.swc and /dev/null differ diff --git a/out/hxmpp.swc b/out/hxmpp.swc deleted file mode 100644 index a51ce47..0000000 Binary files a/out/hxmpp.swc and /dev/null differ diff --git a/samples/client/ClientDemo.hx b/samples/client/ClientDemo.hx index d0e9c1a..6521180 100644 --- a/samples/client/ClientDemo.hx +++ b/samples/client/ClientDemo.hx @@ -1,7 +1,7 @@ import jabber.SocketConnection; import jabber.ServiceDiscovery; -import jabber.client.NonSASLAuthentication; +import jabber.client.NonSASLAuth; import jabber.client.Stream; import jabber.client.Roster; import jabber.client.VCard; @@ -46,7 +46,7 @@ class ClientDemo { */ var mechanisms = new Array<net.sasl.Mechanism>(); mechanisms.push( new net.sasl.PlainMechanism() ); - var auth = new jabber.client.SASLAuthentication( stream, mechanisms ); + var auth = new jabber.client.SASLAuth( stream, mechanisms ); auth.onSuccess = handleLogin; auth.onFail = function(?e) { trace( "Authentication failed", "warn" ); diff --git a/samples/client/build.hxml b/samples/client/build.hxml index baac607..e28a8a2 100644 --- a/samples/client/build.hxml +++ b/samples/client/build.hxml @@ -36,15 +36,15 @@ -D JABBER_DEBUG -debug -#--next -#-cp ../../ -#-cp ../../lib -#-cpp client -#-main ClientDemo -#-D XMPP_DEBUG -#-D JABBER_DEBUG -#-D HXCPP_MULTI_THREADED +--next +-cp ../../ +-cp ../../lib +-cpp client +-main ClientDemo +-D XMPP_DEBUG +-D JABBER_DEBUG +-D HXCPP_MULTI_THREADED #-debug ### MXMLC-SWC --cmd mxmlc ClientDemo.as -default-size 800 600 -include-libraries ../../out//hxmpp.swc -output clientAS3.swf +#-cmd mxmlc ClientDemo.as -default-size 800 600 -include-libraries ../../out//hxmpp.swc -output clientAS3.swf diff --git a/samples/client/test.html b/samples/client/test.html new file mode 100644 index 0000000..9247a13 --- /dev/null +++ b/samples/client/test.html @@ -0,0 +1,20 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<meta name="author" content="disktree.net" /> +<title>HXMPP</title> +<script type="text/javascript" src="../swfobject.js"/></script> +<style type="text/css"> +html { height:100%; } +body { height:100%; } +</style> +</head> +<body> +<div>HXMPP flash usage</div> +<div id="swf">NO FLASHPLAYER DETECTED</div> +<script type="text/javascript"> +swfobject.embedSWF("client.swf","swf","100%","100%","9.0.0"); +</script> +</body> +</html> diff --git a/util/neko.h b/util/neko.h new file mode 100644 index 0000000..aa265bf --- /dev/null +++ b/util/neko.h @@ -0,0 +1,431 @@ +/* ************************************************************************ */ +/* */ +/* Neko Virtual Machine */ +/* Copyright (c)2005 Motion-Twin */ +/* */ +/* This library is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Lesser General Public */ +/* License as published by the Free Software Foundation; either */ +/* version 2.1 of the License, or (at your option) any later version. */ +/* */ +/* This library 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 */ +/* Lesser General Public License or the LICENSE file for more details. */ +/* */ +/* ************************************************************************ */ +#ifndef _NEKO_H +#define _NEKO_H + +// OS FLAGS +#if defined(_WIN32) +# define NEKO_WINDOWS +#endif + +#if defined(__APPLE__) || defined(__MACH__) || defined(macintosh) +# define NEKO_MAC +#endif + +#if defined(linux) || defined(__linux__) +# define NEKO_LINUX +#endif + +#if defined(__FreeBSD_kernel__) +# define NEKO_GNUKBSD +#endif + +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +# define NEKO_BSD +#endif + +// COMPILER/PROCESSOR FLAGS +#if defined(__GNUC__) +# define NEKO_GCC +#endif + +#if defined(_MSC_VER) +# define NEKO_VCC +#endif + +#if defined(__MINGW32__) +# define NEKO_MINGW +#endif + +#if defined(__i386__) || defined(_WIN32) +# define NEKO_X86 +#endif + +#if defined(__ppc__) +# define NEKO_PPC +#endif + +#if defined(_64BITS) +# define NEKO_64BITS +#endif + +#if defined(NEKO_LINUX) || defined(NEKO_MAC) || defined(NEKO_BSD) || defined(NEKO_GNUKBSD) +# define NEKO_POSIX +#endif + +#if defined(NEKO_GCC) +# define NEKO_THREADED +# define NEKO_DIRECT_THREADED +#endif + +#ifndef NEKO_NO_THREADS +# define NEKO_THREADS +#endif + +#include <stddef.h> +#ifndef NEKO_VCC +# include <stdint.h> +#endif + +#define NEKO_VERSION 181 + +typedef intptr_t int_val; + +typedef enum { + VAL_INT = 0xFF, + VAL_NULL = 0, + VAL_FLOAT = 1, + VAL_BOOL = 2, + VAL_STRING = 3, + VAL_OBJECT = 4, + VAL_ARRAY = 5, + VAL_FUNCTION = 6, + VAL_ABSTRACT = 7, + VAL_PRIMITIVE = 6 | 8, + VAL_JITFUN = 6 | 16, + VAL_32_BITS = 0xFFFFFFFF +} val_type; + +struct _value { + val_type t; +}; + +struct _buffer; +typedef int field; +typedef struct { int __zero; } *vkind; +typedef struct _value *value; + +typedef struct { + field id; + value v; +} objcell; + +typedef struct _objtable +{ + int count; + objcell *cells; +} objtable; + +typedef struct _buffer *buffer; +typedef double tfloat; + +typedef void (*finalizer)(value v); + +#pragma pack(4) +typedef struct { + val_type t; + tfloat f; +} vfloat; +#pragma pack() + +typedef struct _vobject { + val_type t; + objtable table; + struct _vobject *proto; +} vobject; + +typedef struct { + val_type t; + int nargs; + void *addr; + value env; + void *module; +} vfunction; + +typedef struct { + val_type t; + char c; +} vstring; + +typedef struct { + val_type t; + value ptr; +} varray; + +typedef struct { + val_type t; + vkind kind; + void *data; +} vabstract; + +typedef struct hcell { + int hkey; + value key; + value val; + struct hcell *next; +} hcell; + +typedef struct { + hcell **cells; + int ncells; + int nitems; +} vhash; + +struct _mt_local; +struct _mt_lock; +typedef struct _mt_local mt_local; +typedef struct _mt_lock mt_lock; + +#define val_tag(v) (*(val_type*)(v)) +#define val_is_null(v) ((v) == val_null) +#define val_is_int(v) ((((int)(int_val)(v)) & 1) != 0) +#define val_is_bool(v) ((v) == val_true || (v) == val_false) +#define val_is_number(v) (val_is_int(v) || val_tag(v) == VAL_FLOAT) +#define val_is_float(v) (!val_is_int(v) && val_tag(v) == VAL_FLOAT) +#define val_is_string(v) (!val_is_int(v) && (val_tag(v)&7) == VAL_STRING) +#define val_is_function(v) (!val_is_int(v) && (val_tag(v)&7) == VAL_FUNCTION) +#define val_is_object(v) (!val_is_int(v) && val_tag(v) == VAL_OBJECT) +#define val_is_array(v) (!val_is_int(v) && (val_tag(v)&7) == VAL_ARRAY) +#define val_is_abstract(v) (!val_is_int(v) && val_tag(v) == VAL_ABSTRACT) +#define val_is_kind(v,t) (val_is_abstract(v) && val_kind(v) == (t)) +#define val_check_kind(v,t) if( !val_is_kind(v,t) ) neko_error(); +#define val_check_function(f,n) if( !val_is_function(f) || (val_fun_nargs(f) != (n) && val_fun_nargs(f) != VAR_ARGS) ) neko_error(); +#define val_check(v,t) if( !val_is_##t(v) ) neko_error(); +#define val_data(v) ((vabstract*)(v))->data +#define val_kind(v) ((vabstract*)(v))->kind + +#define val_type(v) (val_is_int(v) ? VAL_INT : (val_tag(v)&7)) +#define val_int(v) (((int)(int_val)(v)) >> 1) +#define val_float(v) (CONV_FLOAT ((vfloat*)(v))->f) +#define val_bool(v) ((v) == val_true) +#define val_number(v) (val_is_int(v)?val_int(v):val_float(v)) +#define val_hdata(v) ((vhash*)val_data(v)) +#define val_string(v) (&((vstring*)(v))->c) +#define val_strlen(v) (val_tag(v) >> 3) +#define val_set_length(v,l) val_tag(v) = (val_tag(v)&7) | ((l) << 3) +#define val_set_size val_set_length + +#define val_array_size(v) (val_tag(v) >> 3) +#define val_array_ptr(v) (&((varray*)(v))->ptr) +#define val_fun_nargs(v) ((vfunction*)(v))->nargs +#define alloc_int(v) ((value)(int_val)((((int)(v)) << 1) | 1)) +#define alloc_bool(b) ((b)?val_true:val_false) + +#define max_array_size ((1 << 29) - 1) +#define max_string_size ((1 << 29) - 1) +#define invalid_comparison 0xFE + +#undef EXTERN +#undef EXPORT +#undef IMPORT +#if defined(NEKO_VCC) || defined(NEKO_MINGW) +# define INLINE __inline +# define EXPORT __declspec( dllexport ) +# define IMPORT __declspec( dllimport ) +#else +# define INLINE inline +# define EXPORT +# define IMPORT +#endif + +#if defined(NEKO_SOURCES) || defined(NEKO_STANDALONE) +# define EXTERN EXPORT +#else +# define EXTERN IMPORT +#endif + +#define VEXTERN extern EXTERN + +#ifdef __cplusplus +# define C_FUNCTION_BEGIN extern "C" { +# define C_FUNCTION_END }; +#else +# define C_FUNCTION_BEGIN +# define C_FUNCTION_END +# ifndef true +# define true 1 +# define false 0 + typedef int bool; +# endif +#endif + +#define alloc_int32(i) alloc_abstract(k_int32, (value)(int_val)(i)) +// the two upper bits must be either 00 or 11 +#define need_32_bits(i) ( ((((unsigned int)i) >> 30) + 1) & 2 ) +#define alloc_best_int(i) (need_32_bits(i) ? alloc_int32(i) : alloc_int(i)) +#define val_int32(v) (val_is_int(v)?val_int(v):(int)(int_val)val_data(v)) +#define val_is_int32(v) (val_is_int(v) || val_is_kind(v,k_int32)) + +#define neko_error() return NULL +#define failure(msg) _neko_failure(alloc_string(msg),__FILE__,__LINE__) +#define bfailure(buf) _neko_failure(buffer_to_string(b),__FILE__,__LINE__) + +#ifndef CONV_FLOAT +# define CONV_FLOAT +#endif + +#ifdef NEKO_POSIX +# include <errno.h> +# define POSIX_LABEL(name) name: +# define HANDLE_EINTR(label) if( errno == EINTR ) goto label +# define HANDLE_FINTR(f,label) if( ferror(f) && errno == EINTR ) goto label +#else +# define POSIX_LABEL(name) +# define HANDLE_EINTR(label) +# define HANDLE_FINTR(f,label) +#endif + +#define VAR_ARGS (-1) +#define DEFINE_PRIM_MULT(func) C_FUNCTION_BEGIN EXPORT void *func##__MULT() { return (void*)(&func); } C_FUNCTION_END +#define DEFINE_PRIM(func,nargs) C_FUNCTION_BEGIN EXPORT void *func##__##nargs() { return (void*)(&func); } C_FUNCTION_END +#define DEFINE_KIND(name) int_val __kind_##name = 0; vkind name = (vkind)&__kind_##name; + +#ifdef NEKO_STANDALONE +# define DEFINE_ENTRY_POINT(name) +#else +# define DEFINE_ENTRY_POINT(name) C_FUNCTION_BEGIN void name(); EXPORT void *__neko_entry_point() { return &name; } C_FUNCTION_END +#endif + +#ifdef HEADER_IMPORTS +# define H_EXTERN IMPORT +#else +# define H_EXTERN EXPORT +#endif + +#define DECLARE_PRIM(func,nargs) C_FUNCTION_BEGIN H_EXTERN void *func##__##nargs(); C_FUNCTION_END +#define DECLARE_KIND(name) C_FUNCTION_BEGIN H_EXTERN extern vkind name; C_FUNCTION_END + +#define alloc_float neko_alloc_float +#define alloc_string neko_alloc_string +#define alloc_empty_string neko_alloc_empty_string +#define copy_string neko_copy_string +#define val_this neko_val_this +#define val_id neko_val_id +#define val_field neko_val_field +#define alloc_object neko_alloc_object +#define alloc_field neko_alloc_field +#define alloc_array neko_alloc_array +#define val_call0 neko_val_call0 +#define val_call1 neko_val_call1 +#define val_call2 neko_val_call2 +#define val_call3 neko_val_call3 +#define val_callN neko_val_callN +#define val_ocall0 neko_val_ocall0 +#define val_ocall1 neko_val_ocall1 +#define val_ocall2 neko_val_ocall2 +#define val_ocallN neko_val_ocallN +#define val_callEx neko_val_callEx +#define alloc_root neko_alloc_root +#define free_root neko_free_root +#define alloc neko_alloc +#define alloc_private neko_alloc_private +#define alloc_abstract neko_alloc_abstract +#define alloc_function neko_alloc_function +#define alloc_buffer neko_alloc_buffer +#define buffer_append neko_buffer_append +#define buffer_append_sub neko_buffer_append_sub +#define buffer_append_char neko_buffer_append_char +#define buffer_to_string neko_buffer_to_string +#define val_buffer neko_val_buffer +#define val_compare neko_val_compare +#define val_print neko_val_print +#define val_gc neko_val_gc +#define val_throw neko_val_throw +#define val_rethrow neko_val_rethrow +#define val_iter_fields neko_val_iter_fields +#define val_field_name neko_val_field_name +#define val_hash neko_val_hash +#define k_int32 neko_k_int32 +#define k_hash neko_k_hash +#define kind_share neko_kind_share + +#define alloc_local neko_alloc_local +#define local_get neko_local_get +#define local_set neko_local_set +#define free_local neko_free_local +#define alloc_lock neko_alloc_lock +#define lock_acquire neko_lock_acquire +#define lock_try neko_lock_try +#define lock_release neko_lock_release +#define free_lock neko_free_lock + +C_FUNCTION_BEGIN + + VEXTERN vkind k_int32; + VEXTERN vkind k_hash; + + VEXTERN value val_null; + VEXTERN value val_true; + VEXTERN value val_false; + + EXTERN value alloc_float( tfloat t ); + + EXTERN value alloc_string( const char *str ); + EXTERN value alloc_empty_string( unsigned int size ); + EXTERN value copy_string( const char *str, int_val size ); + + EXTERN value val_this(); + EXTERN field val_id( const char *str ); + EXTERN value val_field( value o, field f ); + EXTERN value alloc_object( value o ); + EXTERN void alloc_field( value obj, field f, value v ); + EXTERN void val_iter_fields( value obj, void f( value v, field f, void * ), void *p ); + EXTERN value val_field_name( field f ); + + EXTERN value alloc_array( unsigned int n ); + EXTERN value alloc_abstract( vkind k, void *data ); + + EXTERN value val_call0( value f ); + EXTERN value val_call1( value f, value arg ); + EXTERN value val_call2( value f, value arg1, value arg2 ); + EXTERN value val_call3( value f, value arg1, value arg2, value arg3 ); + EXTERN value val_callN( value f, value *args, int nargs ); + EXTERN value val_ocall0( value o, field f ); + EXTERN value val_ocall1( value o, field f, value arg ); + EXTERN value val_ocall2( value o, field f, value arg1, value arg2 ); + EXTERN value val_ocallN( value o, field f, value *args, int nargs ); + EXTERN value val_callEx( value vthis, value f, value *args, int nargs, value *exc ); + + EXTERN value *alloc_root( unsigned int nvals ); + EXTERN void free_root( value *r ); + EXTERN char *alloc( unsigned int nbytes ); + EXTERN char *alloc_private( unsigned int nbytes ); + EXTERN value alloc_function( void *c_prim, unsigned int nargs, const char *name ); + + EXTERN buffer alloc_buffer( const char *init ); + EXTERN void buffer_append( buffer b, const char *s ); + EXTERN void buffer_append_sub( buffer b, const char *s, int_val len ); + EXTERN void buffer_append_char( buffer b, char c ); + EXTERN value buffer_to_string( buffer b ); + EXTERN void val_buffer( buffer b, value v ); + + EXTERN int val_compare( value a, value b ); + EXTERN void val_print( value s ); + EXTERN void val_gc( value v, finalizer f ); + EXTERN void val_throw( value v ); + EXTERN void val_rethrow( value v ); + EXTERN int val_hash( value v ); + + EXTERN void kind_share( vkind *k, const char *name ); + EXTERN void _neko_failure( value msg, const char *file, int line ); + + // MULTITHREADING API + EXTERN mt_local *alloc_local(); + EXTERN void *local_get( mt_local *l ); + EXTERN void local_set( mt_local *l, void *v ); + EXTERN void free_local( mt_local *l ); + + EXTERN mt_lock *alloc_lock(); + EXTERN void lock_acquire( mt_lock *l ); + EXTERN int lock_try( mt_lock *l ); + EXTERN void lock_release( mt_lock *l ); + EXTERN void free_lock( mt_lock *l ); + +C_FUNCTION_END + +#endif +/* ************************************************************************ */ diff --git a/xmpp/Auth.hx b/xmpp/Auth.hx index 21c438b..43f01b8 100644 --- a/xmpp/Auth.hx +++ b/xmpp/Auth.hx @@ -24,7 +24,7 @@ import util.XmlUtil; */ class Auth { - public static inline var XMLNS = "jabber:iq:auth"; + public static var XMLNS = "jabber:iq:auth"; public var username : String; public var password : String; diff --git a/xmpp/BOB.hx b/xmpp/BOB.hx index 932d4f8..2fbdbba 100644 --- a/xmpp/BOB.hx +++ b/xmpp/BOB.hx @@ -59,9 +59,9 @@ class BOB { /** Parses cids ('algo+hash@bob.xmpp.org') from the given string. - //TODO return : Array<{algo:String,hash:String}> */ public static function parseCID( t : String ) : {algo:String,hash:String} { + //TODO return : Array<{algo:String,hash:String}> var algo : String = null; var hash : String = null; ~/cid:(.*?)\+(.*?)@bob.xmpp.org/.customReplace( t, function(r) { diff --git a/xmpp/Caps.hx b/xmpp/Caps.hx index 4d276c2..39d07de 100644 --- a/xmpp/Caps.hx +++ b/xmpp/Caps.hx @@ -22,7 +22,7 @@ package xmpp; */ class Caps { - public static inline var XMLNS = xmpp.NS.PROTOCOL+"/caps"; + public static inline var XMLNS = xmpp.Namespace.PROTOCOL+"/caps"; /** The hashing algorithm used to generate the verification string, fe: sha-1. diff --git a/xmpp/ChatStateExtension.hx b/xmpp/ChatStateExtension.hx index df8755d..0a7259a 100644 --- a/xmpp/ChatStateExtension.hx +++ b/xmpp/ChatStateExtension.hx @@ -22,7 +22,7 @@ package xmpp; */ class ChatStateExtension { - public static var XMLNS = xmpp.NS.PROTOCOL+"/chatstates"; + public static var XMLNS = xmpp.Namespace.PROTOCOL+"/chatstates"; /** Adds (or changes if already has) the chat state property of the givent message packet. diff --git a/xmpp/Compression.hx b/xmpp/Compression.hx index 0297eaf..f56c41d 100644 --- a/xmpp/Compression.hx +++ b/xmpp/Compression.hx @@ -22,7 +22,7 @@ package xmpp; */ class Compression { - public static var XMLNS = xmpp.NS.PROTOCOL+'/compress'; + public static var XMLNS = xmpp.Namespace.PROTOCOL+'/compress'; /** */ diff --git a/xmpp/HXR.hx b/xmpp/HXR.hx index d416a2f..df7244b 100644 --- a/xmpp/HXR.hx +++ b/xmpp/HXR.hx @@ -1,3 +1,20 @@ +/* + * This file is part of HXMPP. + * Copyright (c)2009 http://www.disktree.net + * + * HXMPP is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HXMPP 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with HXMPP. If not, see <http://www.gnu.org/licenses/>. +*/ package xmpp; /** @@ -5,9 +22,7 @@ package xmpp; */ class HXR { - public static inline var XMLNS = "http://haxe.org/hxr"; - //public static inline var XMLNS_CALL = XMLNS+"/call"; - //public static inline var XMLNS_RESPONSE = XMLNS+"/response"; + public static var XMLNS = "http://haxe.org/hxr"; public static inline function create( ?data : String ) : Xml { var x = xmpp.IQ.createQueryXml( XMLNS ); diff --git a/xmpp/MUC.hx b/xmpp/MUC.hx index 1439d3f..f9c0e05 100644 --- a/xmpp/MUC.hx +++ b/xmpp/MUC.hx @@ -18,7 +18,5 @@ package xmpp; class MUC { - - public static var XMLNS = xmpp.NS.PROTOCOL+'/muc'; - + public static var XMLNS = xmpp.Namespace.PROTOCOL+'/muc'; } diff --git a/xmpp/NS.hx b/xmpp/NS.hx deleted file mode 100644 index e0a9fb5..0000000 --- a/xmpp/NS.hx +++ /dev/null @@ -1,22 +0,0 @@ -/* - * This file is part of HXMPP. - * Copyright (c)2009 http://www.disktree.net - * - * HXMPP is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * HXMPP 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with HXMPP. If not, see <http://www.gnu.org/licenses/>. -*/ -package xmpp; - -class NS { - public static inline var PROTOCOL = "http://jabber.org/protocol"; -} diff --git a/xmpp/Namespace.hx b/xmpp/Namespace.hx new file mode 100644 index 0000000..e2acac4 --- /dev/null +++ b/xmpp/Namespace.hx @@ -0,0 +1,24 @@ +/* + * This file is part of HXMPP. + * Copyright (c)2009 http://www.disktree.net + * + * HXMPP is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HXMPP 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with HXMPP. If not, see <http://www.gnu.org/licenses/>. +*/ +package xmpp; + +// haxe -exclude this class + +class Namespace { + public static inline var PROTOCOL = "http://jabber.org/protocol"; +} diff --git a/xmpp/PlainPacket.hx b/xmpp/PlainPacket.hx index b918690..00b30be 100644 --- a/xmpp/PlainPacket.hx +++ b/xmpp/PlainPacket.hx @@ -21,19 +21,19 @@ package xmpp; Plain/Custom XMPP packet. */ class PlainPacket extends Packet { - + /** Plain XML content of the packet. */ public var src : Xml; - public function new( x : Xml ) { + public function new( src : Xml ) { super(); this._type = xmpp.PacketType.custom; - this.src = x; + this.src = src; } - override public function toXml(): Xml { + public override function toXml(): Xml { return src; } diff --git a/xmpp/PubSub.hx b/xmpp/PubSub.hx index 30e7f51..d535a0f 100644 --- a/xmpp/PubSub.hx +++ b/xmpp/PubSub.hx @@ -19,7 +19,7 @@ package xmpp; class PubSub { - public static var XMLNS = xmpp.NS.PROTOCOL+"/pubsub"; + public static var XMLNS = xmpp.Namespace.PROTOCOL+"/pubsub"; public var subscribe : { node : String, jid : String }; public var options : xmpp.pubsub.Options; diff --git a/xmpp/XHTML.hx b/xmpp/XHTML.hx index 7cb7aaa..2df5c3e 100644 --- a/xmpp/XHTML.hx +++ b/xmpp/XHTML.hx @@ -22,7 +22,7 @@ package xmpp; */ class XHTML { - public static inline var XMLNS = xmpp.NS.PROTOCOL+"/xhtml-im"; + public static inline var XMLNS = xmpp.Namespace.PROTOCOL+"/xhtml-im"; static inline var W3NS = "http://www.w3.org/1999/xhtml"; public var body : String; @@ -78,4 +78,11 @@ class XHTML { m.properties.push( new XHTML( body ).toXml() ); return m; } + + /* + public static inline function create( body : String ) : { + return new XHTML( body ).toXml(); + } + */ + } diff --git a/xmpp/disco/Info.hx b/xmpp/disco/Info.hx index 82f951b..616297f 100644 --- a/xmpp/disco/Info.hx +++ b/xmpp/disco/Info.hx @@ -22,7 +22,7 @@ package xmpp.disco; */ class Info { - public static inline var XMLNS = xmpp.NS.PROTOCOL+'/disco#info'; + public static inline var XMLNS = xmpp.Namespace.PROTOCOL+'/disco#info'; public var identities : Array<Identity>; public var features : Array<String>; diff --git a/xmpp/disco/Items.hx b/xmpp/disco/Items.hx index 45f6b59..772ae51 100644 --- a/xmpp/disco/Items.hx +++ b/xmpp/disco/Items.hx @@ -19,7 +19,7 @@ package xmpp.disco; class Items extends List<xmpp.disco.Item> { - public static var XMLNS = xmpp.NS.PROTOCOL+'/disco#items'; + public static var XMLNS = xmpp.Namespace.PROTOCOL+'/disco#items'; public var node : String; diff --git a/xmpp/file/ByteStream.hx b/xmpp/file/ByteStream.hx index cdca01d..4d0e2e0 100644 --- a/xmpp/file/ByteStream.hx +++ b/xmpp/file/ByteStream.hx @@ -19,7 +19,7 @@ package xmpp.file; class ByteStream { - public static inline var XMLNS = xmpp.NS.PROTOCOL+"/bytestreams"; + public static inline var XMLNS = xmpp.Namespace.PROTOCOL+"/bytestreams"; public var sid : String; public var mode : String; //ByteStreamMode; diff --git a/xmpp/file/IB.hx b/xmpp/file/IB.hx index fd27ab5..2416e5a 100644 --- a/xmpp/file/IB.hx +++ b/xmpp/file/IB.hx @@ -19,7 +19,7 @@ package xmpp.file; class IB { - public static inline var XMLNS = xmpp.NS.PROTOCOL+"/ibb"; + public static inline var XMLNS = xmpp.Namespace.PROTOCOL+"/ibb"; public var type : IBType; public var sid : String; diff --git a/xmpp/filter/PacketAllFilter.hx b/xmpp/filter/PacketAllFilter.hx index 3363bf7..2c3c6ad 100644 --- a/xmpp/filter/PacketAllFilter.hx +++ b/xmpp/filter/PacketAllFilter.hx @@ -28,7 +28,7 @@ class PacketAllFilter { this.yes = yes; } - public function accept( p : xmpp.Packet ) : Bool { + public inline function accept( p : xmpp.Packet ) : Bool { return yes; } diff --git a/xmpp/filter/PacketFieldFilter.hx b/xmpp/filter/PacketFieldFilter.hx index dc3c7a7..7a6ac75 100644 --- a/xmpp/filter/PacketFieldFilter.hx +++ b/xmpp/filter/PacketFieldFilter.hx @@ -18,11 +18,13 @@ package xmpp.filter; /** + Filters XMPP packets where a packet object field matches a given value. */ class PacketFieldFilter { public var name : String; public var value : String; +// public var attributes : Array<String>; public function new( name : String, ?value : String ) { this.name = name; @@ -31,8 +33,11 @@ class PacketFieldFilter { public function accept( p : xmpp.Packet ) : Bool { if( !Reflect.hasField( p, name ) ) return false; + /* if( value == null ) return true; return Reflect.field( p, name ) == value; + */ + return ( value == null ) ? true : ( Reflect.field( p, name ) == value ); } } diff --git a/xmpp/filter/PacketFromFilter.hx b/xmpp/filter/PacketFromFilter.hx index 446140c..210530c 100644 --- a/xmpp/filter/PacketFromFilter.hx +++ b/xmpp/filter/PacketFromFilter.hx @@ -17,6 +17,8 @@ */ package xmpp.filter; +//(TODO )extends packetField filter + /** Filters XMPP packets with matching 'from' attribute. */ @@ -28,7 +30,7 @@ class PacketFromFilter { this.jid = jid; } - public function accept( p : xmpp.Packet ) : Bool { + public inline function accept( p : xmpp.Packet ) : Bool { return p.from == jid; } diff --git a/xmpp/filter/PacketIDFilter.hx b/xmpp/filter/PacketIDFilter.hx index 2548206..ec5c6a6 100644 --- a/xmpp/filter/PacketIDFilter.hx +++ b/xmpp/filter/PacketIDFilter.hx @@ -28,7 +28,7 @@ class PacketIDFilter { this.id = id; } - public function accept( p : xmpp.Packet ) : Bool { + public inline function accept( p : xmpp.Packet ) : Bool { return p.id == id; } diff --git a/xmpp/filter/PacketToFilter.hx b/xmpp/filter/PacketToFilter.hx index 15e57ed..7f89409 100644 --- a/xmpp/filter/PacketToFilter.hx +++ b/xmpp/filter/PacketToFilter.hx @@ -28,7 +28,7 @@ class PacketToFilter { this.jid = jid; } - public function accept( p : xmpp.Packet ) : Bool { + public inline function accept( p : xmpp.Packet ) : Bool { return p.to == jid; } diff --git a/xmpp/filter/PacketTypeFilter.hx b/xmpp/filter/PacketTypeFilter.hx index 6991b11..2e5c19e 100644 --- a/xmpp/filter/PacketTypeFilter.hx +++ b/xmpp/filter/PacketTypeFilter.hx @@ -17,7 +17,6 @@ */ package xmpp.filter; - /** Filters packets with matching xmpp.PacketType. */ @@ -29,7 +28,7 @@ class PacketTypeFilter { this.type = type; } - public function accept( p : xmpp.Packet ) : Bool { + public inline function accept( p : xmpp.Packet ) : Bool { return p._type == type; } diff --git a/xmpp/pep/UserActivity.hx b/xmpp/pep/UserActivity.hx index a12ea23..896b553 100644 --- a/xmpp/pep/UserActivity.hx +++ b/xmpp/pep/UserActivity.hx @@ -23,7 +23,7 @@ package xmpp.pep; */ class UserActivity extends Event { - public static var XMLNS = xmpp.NS.PROTOCOL+"/activity"; + public static var XMLNS = xmpp.Namespace.PROTOCOL+"/activity"; public var activity : Activity; public var text : String; diff --git a/xmpp/pep/UserLocation.hx b/xmpp/pep/UserLocation.hx index 61bd21d..0512e81 100644 --- a/xmpp/pep/UserLocation.hx +++ b/xmpp/pep/UserLocation.hx @@ -23,7 +23,7 @@ package xmpp.pep; */ class UserLocation extends Event { - public static var XMLNS = xmpp.NS.PROTOCOL+"/geoloc"; + public static var XMLNS = xmpp.Namespace.PROTOCOL+"/geoloc"; /** Horizontal GPS error in meters; this element obsoletes the <error/> element */ public var accuracy : Int; diff --git a/xmpp/pep/UserMood.hx b/xmpp/pep/UserMood.hx index 7aa2cbe..d999d37 100644 --- a/xmpp/pep/UserMood.hx +++ b/xmpp/pep/UserMood.hx @@ -23,7 +23,7 @@ package xmpp.pep; */ class UserMood extends Event { - public static var XMLNS = xmpp.NS.PROTOCOL+"/mood"; + public static var XMLNS = xmpp.Namespace.PROTOCOL+"/mood"; public var type : Mood; public var text : String; diff --git a/xmpp/pep/UserTune.hx b/xmpp/pep/UserTune.hx index bd5a5b9..47b507d 100644 --- a/xmpp/pep/UserTune.hx +++ b/xmpp/pep/UserTune.hx @@ -23,7 +23,7 @@ package xmpp.pep; */ class UserTune extends Event { - public static var XMLNS = xmpp.NS.PROTOCOL+"/tune"; + public static var XMLNS = xmpp.Namespace.PROTOCOL+"/tune"; /** The artist or performer of the song or piece */ public var artist : String; diff --git a/xmpp/pubsub/NodeType.hx b/xmpp/pubsub/NodeType.hx new file mode 100644 index 0000000..52cc76f --- /dev/null +++ b/xmpp/pubsub/NodeType.hx @@ -0,0 +1,23 @@ +/* + * This file is part of HXMPP. + * Copyright (c)2009 http://www.disktree.net + * + * HXMPP is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HXMPP 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with HXMPP. If not, see <http://www.gnu.org/licenses/>. +*/ +package xmpp.pubsub; + +enum NodeType { + leaf; + collection; +}