faye 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of faye might be problematic. Click here for more details.
- data/History.txt +7 -0
- data/README.rdoc +2 -2
- data/lib/faye-browser-min.js +1 -1
- data/lib/faye.rb +1 -1
- data/lib/faye/adapters/rack_adapter.rb +11 -7
- data/lib/faye/engines/memory.rb +21 -10
- data/lib/faye/util/namespace.rb +4 -0
- data/spec/javascript/node_adapter_spec.js +5 -4
- data/spec/javascript/server/handshake_spec.js +6 -6
- data/spec/ruby/rack_adapter_spec.rb +6 -5
- data/spec/ruby/server/handshake_spec.rb +6 -6
- metadata +72 -8
- data/Rakefile +0 -21
data/History.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
=== 0.6.1 / 2011-06-06
|
2
|
+
TestSwarm build: http://swarm.jcoglan.com/job/37/
|
3
|
+
|
4
|
+
* Fix cross-origin-long-polling support in RackAdapter
|
5
|
+
* Plug some potential memory leaks in Memory engine
|
6
|
+
|
7
|
+
|
1
8
|
=== 0.6.0 / 2011-05-21
|
2
9
|
TestSwarm build: http://swarm.jcoglan.com/job/27/
|
3
10
|
|
data/README.rdoc
CHANGED
data/lib/faye-browser-min.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
if(!this.Faye)Faye={};Faye.extend=function(a,b,c){if(!b)return a;for(var d in b){if(!b.hasOwnProperty(d))continue;if(a.hasOwnProperty(d)&&c===false)continue;if(a[d]!==b[d])a[d]=b[d]}return a};Faye.extend(Faye,{VERSION:'0.6.0',BAYEUX_VERSION:'1.0',ID_LENGTH:128,JSONP_CALLBACK:'jsonpcallback',CONNECTION_TYPES:['long-polling','cross-origin-long-polling','callback-polling','websocket','in-process'],MANDATORY_CONNECTION_TYPES:['long-polling','callback-polling','in-process'],ENV:(function(){return this})(),random:function(a){a=a||this.ID_LENGTH;if(a>32){var b=Math.ceil(a/32),c='';while(b--)c+=this.random(32);return c}var d=Math.pow(2,a)-1,f=d.toString(36).length,c=Math.floor(Math.random()*d).toString(36);while(c.length<f)c='0'+c;return c},commonElement:function(a,b){for(var c=0,d=a.length;c<d;c++){if(this.indexOf(b,a[c])!==-1)return a[c]}return null},indexOf:function(a,b){for(var c=0,d=a.length;c<d;c++){if(a[c]===b)return c}return-1},each:function(a,b,c){if(a instanceof Array){for(var d=0,f=a.length;d<f;d++){if(a[d]!==undefined)b.call(c||null,a[d],d)}}else{for(var g in a){if(a.hasOwnProperty(g))b.call(c||null,g,a[g])}}},map:function(a,b,c){var d=[];this.each(a,function(){d.push(b.apply(c||null,arguments))});return d},filter:function(a,b,c){var d=[];this.each(a,function(){if(b.apply(c,arguments))d.push(arguments[0])});return d},size:function(a){var b=0;this.each(a,function(){b+=1});return b},enumEqual:function(c,d){if(d instanceof Array){if(!(c instanceof Array))return false;var f=c.length;if(f!==d.length)return false;while(f--){if(c[f]!==d[f])return false}return true}else{if(!(c instanceof Object))return false;if(this.size(d)!==this.size(c))return false;var g=true;this.each(c,function(a,b){g=g&&(d[a]===b)});return g}},asyncEach:function(a,b,c,d){var f=a.length,g=-1,h=0,j=false;var i=function(){h-=1;g+=1;if(g===f)return c&&c.call(d);b(a[g],m)};var k=function(){if(j)return;j=true;while(h>0)i();j=false};var m=function(){h+=1;k()};m()},toJSON:function(a){if(this.stringify)return this.stringify(a,function(key,value){return(this[key]instanceof Array)?this[key]:value});return JSON.stringify(a)},timestamp:function(){var b=new Date(),c=b.getFullYear(),d=b.getMonth()+1,f=b.getDate(),g=b.getHours(),h=b.getMinutes(),j=b.getSeconds();var i=function(a){return a<10?'0'+a:String(a)};return i(c)+'-'+i(d)+'-'+i(f)+' '+i(g)+':'+i(h)+':'+i(j)}});Faye.Class=function(a,b){if(typeof a!=='function'){b=a;a=Object}var c=function(){if(!this.initialize)return this;return this.initialize.apply(this,arguments)||this};var d=function(){};d.prototype=a.prototype;c.prototype=new d();Faye.extend(c.prototype,b);return c};Faye.Namespace=Faye.Class({initialize:function(){this._r={}},generate:function(){var a=Faye.random();while(this._r.hasOwnProperty(a))a=Faye.random();return this._r[a]=a}});Faye.Error=Faye.Class({initialize:function(a,b,c){this.code=a;this.params=Array.prototype.slice.call(b);this.message=c},toString:function(){return this.code+':'+this.params.join(',')+':'+this.message}});Faye.Error.parse=function(a){a=a||'';if(!Faye.Grammar.ERROR.test(a))return new this(null,[],a);var b=a.split(':'),c=parseInt(b[0]),d=b[1].split(','),a=b[2];return new this(c,d,a)};Faye.Error.versionMismatch=function(){return new this(300,arguments,"Version mismatch").toString()};Faye.Error.conntypeMismatch=function(){return new this(301,arguments,"Connection types not supported").toString()};Faye.Error.extMismatch=function(){return new this(302,arguments,"Extension mismatch").toString()};Faye.Error.badRequest=function(){return new this(400,arguments,"Bad request").toString()};Faye.Error.clientUnknown=function(){return new this(401,arguments,"Unknown client").toString()};Faye.Error.parameterMissing=function(){return new this(402,arguments,"Missing required parameter").toString()};Faye.Error.channelForbidden=function(){return new this(403,arguments,"Forbidden channel").toString()};Faye.Error.channelUnknown=function(){return new this(404,arguments,"Unknown channel").toString()};Faye.Error.channelInvalid=function(){return new this(405,arguments,"Invalid channel").toString()};Faye.Error.extUnknown=function(){return new this(406,arguments,"Unknown extension").toString()};Faye.Error.publishFailed=function(){return new this(407,arguments,"Failed to publish").toString()};Faye.Error.serverError=function(){return new this(500,arguments,"Internal server error").toString()};Faye.Deferrable={callback:function(a,b){if(!a)return;if(this._s==='succeeded')return a.apply(b,this._h);this._i=this._i||[];this._i.push([a,b])},errback:function(a,b){if(!a)return;if(this._s==='failed')return a.apply(b,this._h);this._j=this._j||[];this._j.push([a,b])},setDeferredStatus:function(){var a=Array.prototype.slice.call(arguments),b=a.shift(),c;this._s=b;this._h=a;if(b==='succeeded')c=this._i;else if(b==='failed')c=this._j;if(!c)return;var d;while(d=c.shift())d[0].apply(d[1],this._h)}};Faye.Publisher={countSubscribers:function(a){if(!this._3||!this._3[a])return 0;return this._3[a].length},addSubscriber:function(a,b,c){this._3=this._3||{};var d=this._3[a]=this._3[a]||[];d.push([b,c])},removeSubscriber:function(a,b,c){if(!this._3||!this._3[a])return;if(!b){delete this._3[a];return}var d=this._3[a],f=d.length;while(f--){if(b!==d[f][0])continue;if(c&&d[f][1]!==c)continue;d.splice(f,1)}},removeSubscribers:function(){this._3={}},publishEvent:function(){var b=Array.prototype.slice.call(arguments),c=b.shift();if(!this._3||!this._3[c])return;Faye.each(this._3[c],function(a){a[0].apply(a[1],b)})}};Faye.Timeouts={addTimeout:function(a,b,c,d){this._4=this._4||{};if(this._4.hasOwnProperty(a))return;var f=this;this._4[a]=Faye.ENV.setTimeout(function(){delete f._4[a];c.call(d)},1000*b)},removeTimeout:function(a){this._4=this._4||{};var b=this._4[a];if(!b)return;clearTimeout(b);delete this._4[a]}};Faye.Logging={LOG_LEVELS:{error:3,warn:2,info:1,debug:0},logLevel:'error',log:function(a,b){if(!Faye.logger)return;var c=Faye.Logging.LOG_LEVELS;if(c[Faye.Logging.logLevel]>c[b])return;var a=Array.prototype.slice.apply(a),d=' ['+b.toUpperCase()+'] [Faye',f=this.className,g=a.shift().replace(/\?/g,function(){try{return Faye.toJSON(a.shift())}catch(e){return'[Object]'}});for(var h in Faye){if(f)continue;if(typeof Faye[h]!=='function')continue;if(this instanceof Faye[h])f=h}if(f)d+='.'+f;d+='] ';Faye.logger(Faye.timestamp()+d+g)}};Faye.each(Faye.Logging.LOG_LEVELS,function(a,b){Faye.Logging[a]=function(){this.log(arguments,a)}});Faye.Grammar={LOWALPHA:/^[a-z]$/,UPALPHA:/^[A-Z]$/,ALPHA:/^([a-z]|[A-Z])$/,DIGIT:/^[0-9]$/,ALPHANUM:/^(([a-z]|[A-Z])|[0-9])$/,MARK:/^(\-|\_|\!|\~|\(|\)|\$|\@)$/,STRING:/^(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*$/,TOKEN:/^(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+$/,INTEGER:/^([0-9])+$/,CHANNEL_SEGMENT:/^(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+$/,CHANNEL_SEGMENTS:/^(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+(\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+)*$/,CHANNEL_NAME:/^\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+(\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+)*$/,WILD_CARD:/^\*{1,2}$/,CHANNEL_PATTERN:/^(\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+)*\/\*{1,2}$/,VERSION_ELEMENT:/^(([a-z]|[A-Z])|[0-9])(((([a-z]|[A-Z])|[0-9])|\-|\_))*$/,VERSION:/^([0-9])+(\.(([a-z]|[A-Z])|[0-9])(((([a-z]|[A-Z])|[0-9])|\-|\_))*)*$/,CLIENT_ID:/^((([a-z]|[A-Z])|[0-9]))+$/,ID:/^((([a-z]|[A-Z])|[0-9]))+$/,ERROR_MESSAGE:/^(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*$/,ERROR_ARGS:/^(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*(,(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*)*$/,ERROR_CODE:/^[0-9][0-9][0-9]$/,ERROR:/^([0-9][0-9][0-9]:(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*(,(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*)*:(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*|[0-9][0-9][0-9]::(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*)$/};Faye.Extensible={addExtension:function(a){this._5=this._5||[];this._5.push(a);if(a.added)a.added()},removeExtension:function(a){if(!this._5)return;var b=this._5.length;while(b--){if(this._5[b]!==a)continue;this._5.splice(b,1);if(a.removed)a.removed()}},pipeThroughExtensions:function(c,d,f,g){this.debug('Passing through ? extensions: ?',c,d);if(!this._5)return f.call(g,d);var h=this._5.slice();var j=function(a){if(!a)return f.call(g,a);var b=h.shift();if(!b)return f.call(g,a);if(b[c])b[c](a,j);else j(a)};j(d)}};Faye.extend(Faye.Extensible,Faye.Logging);Faye.Channel=Faye.Class({initialize:function(a){this.id=this.name=a},push:function(a){this.publishEvent('message',a)},isUnused:function(){return this.countSubscribers('message')===0}});Faye.extend(Faye.Channel.prototype,Faye.Publisher);Faye.extend(Faye.Channel,{HANDSHAKE:'/meta/handshake',CONNECT:'/meta/connect',SUBSCRIBE:'/meta/subscribe',UNSUBSCRIBE:'/meta/unsubscribe',DISCONNECT:'/meta/disconnect',META:'meta',SERVICE:'service',expand:function(a){var b=this.parse(a),c=['/**',a];var d=b.slice();d[d.length-1]='*';c.push(this.unparse(d));for(var f=1,g=b.length;f<g;f++){d=b.slice(0,f);d.push('**');c.push(this.unparse(d))}return c},isValid:function(a){return Faye.Grammar.CHANNEL_NAME.test(a)||Faye.Grammar.CHANNEL_PATTERN.test(a)},parse:function(a){if(!this.isValid(a))return null;return a.split('/').slice(1)},unparse:function(a){return'/'+a.join('/')},isMeta:function(a){var b=this.parse(a);return b?(b[0]===this.META):null},isService:function(a){var b=this.parse(a);return b?(b[0]===this.SERVICE):null},isSubscribable:function(a){if(!this.isValid(a))return null;return!this.isMeta(a)&&!this.isService(a)},Set:Faye.Class({initialize:function(){this._2={}},getKeys:function(){var c=[];Faye.each(this._2,function(a,b){c.push(a)});return c},remove:function(a){delete this._2[a]},hasSubscription:function(a){return this._2.hasOwnProperty(a)},subscribe:function(c,d,f){if(!d)return;Faye.each(c,function(a){var b=this._2[a]=this._2[a]||new Faye.Channel(a);b.addSubscriber('message',d,f)},this)},unsubscribe:function(a,b,c){var d=this._2[a];if(!d)return false;d.removeSubscriber('message',b,c);if(d.isUnused()){this.remove(a);return true}else{return false}},distributeMessage:function(c){var d=Faye.Channel.expand(c.channel);Faye.each(d,function(a){var b=this._2[a];if(b)b.publishEvent('message',c.data)},this)}})});Faye.Subscription=Faye.Class({initialize:function(a,b,c,d){this._8=a;this._2=b;this._k=c;this._l=d;this._t=false},cancel:function(){if(this._t)return;this._8.unsubscribe(this._2,this._k,this._l);this._t=true},unsubscribe:function(){this.cancel()}});Faye.extend(Faye.Subscription.prototype,Faye.Deferrable);Faye.Client=Faye.Class({UNCONNECTED:1,CONNECTING:2,CONNECTED:3,DISCONNECTED:4,HANDSHAKE:'handshake',RETRY:'retry',NONE:'none',CONNECTION_TIMEOUT:60.0,DEFAULT_ENDPOINT:'/bayeux',INTERVAL:0.0,initialize:function(b,c){this.info('New client created for ?',b);this.endpoint=b||this.DEFAULT_ENDPOINT;this._u=c||{};Faye.Transport.get(this,Faye.MANDATORY_CONNECTION_TYPES,function(a){this._c=a},this);this._1=this.UNCONNECTED;this._2=new Faye.Channel.Set();this._y=new Faye.Namespace();this._m={};this._6={reconnect:this.RETRY,interval:1000*(this._u.interval||this.INTERVAL),timeout:1000*(this._u.timeout||this.CONNECTION_TIMEOUT)};if(Faye.Event)Faye.Event.on(Faye.ENV,'beforeunload',this.disconnect,this)},getClientId:function(){return this._0},getState:function(){switch(this._1){case this.UNCONNECTED:return'UNCONNECTED';case this.CONNECTING:return'CONNECTING';case this.CONNECTED:return'CONNECTED';case this.DISCONNECTED:return'DISCONNECTED'}},handshake:function(c,d){if(this._6.reconnect===this.NONE)return;if(this._1!==this.UNCONNECTED)return;this._1=this.CONNECTING;var f=this;this.info('Initiating handshake with ?',this.endpoint);this._9({channel:Faye.Channel.HANDSHAKE,version:Faye.BAYEUX_VERSION,supportedConnectionTypes:[this._c.connectionType]},function(b){if(b.successful){this._1=this.CONNECTED;this._0=b.clientId;Faye.Transport.get(this,b.supportedConnectionTypes,function(a){this._c=a},this);this.info('Handshake successful: ?',this._0);this.subscribe(this._2.getKeys(),true);if(c)c.call(d)}else{this.info('Handshake unsuccessful');Faye.ENV.setTimeout(function(){f.handshake(c,d)},this._6.interval);this._1=this.UNCONNECTED}},this)},connect:function(a,b){if(this._6.reconnect===this.NONE)return;if(this._1===this.DISCONNECTED)return;if(this._1===this.UNCONNECTED)return this.handshake(function(){this.connect(a,b)},this);this.callback(a,b);if(this._1!==this.CONNECTED)return;this.info('Calling deferred actions for ?',this._0);this.setDeferredStatus('succeeded');this.setDeferredStatus('deferred');if(this._n)return;this._n=true;this.info('Initiating connection for ?',this._0);this._9({channel:Faye.Channel.CONNECT,clientId:this._0,connectionType:this._c.connectionType},this._v,this)},disconnect:function(){if(this._1!==this.CONNECTED)return;this._1=this.DISCONNECTED;this.info('Disconnecting ?',this._0);this._9({channel:Faye.Channel.DISCONNECT,clientId:this._0});this.info('Clearing channel listeners for ?',this._0);this._2=new Faye.Channel.Set()},subscribe:function(c,d,f){if(c instanceof Array)return Faye.each(c,function(channel){this.subscribe(channel,d,f)},this);var g=new Faye.Subscription(this,c,d,f);var h=(d===true);if(!h&&this._2.hasSubscription(c)){this._2.subscribe([c],d,f);g.setDeferredStatus('succeeded');return g}this.connect(function(){this.info('Client ? attempting to subscribe to ?',this._0,c);this._9({channel:Faye.Channel.SUBSCRIBE,clientId:this._0,subscription:c},function(a){if(!a.successful)return g.setDeferredStatus('failed',Faye.Error.parse(a.error));var b=[].concat(a.subscription);this.info('Subscription acknowledged for ? to ?',this._0,b);this._2.subscribe(b,d,f);g.setDeferredStatus('succeeded')},this)},this);return g},unsubscribe:function(c,d,f){if(c instanceof Array)return Faye.each(c,function(channel){this.unsubscribe(channel,d,f)},this);var g=this._2.unsubscribe(c,d,f);if(!g)return;this.connect(function(){this.info('Client ? attempting to unsubscribe from ?',this._0,c);this._9({channel:Faye.Channel.UNSUBSCRIBE,clientId:this._0,subscription:c},function(a){if(!a.successful)return;var b=[].concat(a.subscription);this.info('Unsubscription acknowledged for ? from ?',this._0,b)},this)},this)},publish:function(a,b){if(!Faye.Grammar.CHANNEL_NAME.test(a))throw new Error("Cannot publish: '"+a+"' is not a valid channel name");this.connect(function(){this.info('Client ? queueing published message to ?: ?',this._0,a,b);this._9({channel:a,data:b,clientId:this._0})},this)},receiveMessage:function(c){this.pipeThroughExtensions('incoming',c,function(a){if(!a)return;if(a.advice)this._z(a.advice);var b=this._m[a.id];if(b){delete this._m[a.id];b[0].call(b[1],a)}this._A(a)},this)},_9:function(b,c,d){b.id=this._y.generate();if(c)this._m[b.id]=[c,d];this.pipeThroughExtensions('outgoing',b,function(a){if(!a)return;this._c.send(a,this._6.timeout/1000)},this)},_z:function(a){Faye.extend(this._6,a);if(this._6.reconnect===this.HANDSHAKE&&this._1!==this.DISCONNECTED){this._1=this.UNCONNECTED;this._0=null;this._v()}},_A:function(a){if(!a.channel||!a.data)return;this.info('Client ? calling listeners for ? with ?',this._0,a.channel,a.data);this._2.distributeMessage(a)},_B:function(){if(!this._n)return;this._n=null;this.info('Closed connection for ?',this._0)},_v:function(){this._B();var a=this;Faye.ENV.setTimeout(function(){a.connect()},this._6.interval)}});Faye.extend(Faye.Client.prototype,Faye.Deferrable);Faye.extend(Faye.Client.prototype,Faye.Logging);Faye.extend(Faye.Client.prototype,Faye.Extensible);Faye.Transport=Faye.extend(Faye.Class({MAX_DELAY:0.0,batching:true,initialize:function(a,b){this.debug('Created new ? transport for ?',this.connectionType,b);this._8=a;this._a=b;this._d=[]},send:function(a,b){this.debug('Client ? sending message to ?: ?',this._8._0,this._a,a);if(!this.batching)return this.request([a],b);this._d.push(a);this._7=b;if(a.channel===Faye.Channel.HANDSHAKE)return this.flush();if(a.channel===Faye.Channel.CONNECT)this._o=a;this.addTimeout('publish',this.MAX_DELAY,this.flush,this)},flush:function(){this.removeTimeout('publish');if(this._d.length>1&&this._o)this._o.advice={timeout:0};this.request(this._d,this._7);this._o=null;this._d=[]},receive:function(a){this.debug('Client ? received from ?: ?',this._8._0,this._a,a);Faye.each(a,this._8.receiveMessage,this._8)},retry:function(a,b){var c=this;return function(){Faye.ENV.setTimeout(function(){c.request(a,2*b)},1000*b)}}}),{get:function(g,h,j,i){var k=g.endpoint;if(h===undefined)h=this.supportedConnectionTypes();Faye.asyncEach(this._p,function(b,c){var d=b[0],f=b[1];if(Faye.indexOf(h,d)<0)return c();f.isUsable(k,function(a){if(a)j.call(i,new f(g,k));else c()})},function(){throw new Error('Could not find a usable connection type for '+k);})},register:function(a,b){this._p.push([a,b]);b.prototype.connectionType=a},_p:[],supportedConnectionTypes:function(){return Faye.map(this._p,function(a){return a[0]})}});Faye.extend(Faye.Transport.prototype,Faye.Logging);Faye.extend(Faye.Transport.prototype,Faye.Timeouts);Faye.Event={_e:[],on:function(a,b,c,d){var f=function(){c.call(d)};if(a.addEventListener)a.addEventListener(b,f,false);else a.attachEvent('on'+b,f);this._e.push({_f:a,_q:b,_k:c,_l:d,_w:f})},detach:function(a,b,c,d){var f=this._e.length,g;while(f--){g=this._e[f];if((a&&a!==g._f)||(b&&b!==g._q)||(c&&c!==g._k)||(d&&d!==g._l))continue;if(g._f.removeEventListener)g._f.removeEventListener(g._q,g._w,false);else g._f.detachEvent('on'+g._q,g._w);this._e.splice(f,1);g=null}}};Faye.Event.on(Faye.ENV,'unload',Faye.Event.detach,Faye.Event);Faye.URI=Faye.extend(Faye.Class({queryString:function(){var c=[],d;Faye.each(this.params,function(a,b){c.push(encodeURIComponent(a)+'='+encodeURIComponent(b))});return c.join('&')},isLocal:function(){var a=Faye.URI.parse(Faye.ENV.location.href);var b=(a.hostname!==this.hostname)||(a.port!==this.port)||(a.protocol!==this.protocol);return!b},toURL:function(){var a=this.queryString();return this.protocol+this.hostname+':'+this.port+this.pathname+(a?'?'+a:'')}}),{parse:function(d,f){if(typeof d!=='string')return d;var g=new this();var h=function(b,c){d=d.replace(c,function(a){if(a)g[b]=a;return''})};h('protocol',/^https?\:\/+/);h('hostname',/^[^\/\:]+/);h('port',/^:[0-9]+/);Faye.extend(g,{protocol:'http://',hostname:Faye.ENV.location.hostname,port:Faye.ENV.location.port},false);if(!g.port)g.port=(g.protocol==='https://')?'443':'80';g.port=g.port.replace(/\D/g,'');var j=d.split('?'),i=j.shift(),k=j.join('?'),m=k?k.split('&'):[],o=m.length,l={};while(o--){j=m[o].split('=');l[decodeURIComponent(j[0]||'')]=decodeURIComponent(j[1]||'')}if(typeof f==='object')Faye.extend(l,f);g.pathname=i;g.params=l;return g}});if(!this.JSON){JSON={}}(function(){function k(a){return a<10?'0'+a:a}if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(a){return this.getUTCFullYear()+'-'+k(this.getUTCMonth()+1)+'-'+k(this.getUTCDate())+'T'+k(this.getUTCHours())+':'+k(this.getUTCMinutes())+':'+k(this.getUTCSeconds())+'Z'};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(a){return this.valueOf()}}var m=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,o=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,l,p,s={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},n;function r(c){o.lastIndex=0;return o.test(c)?'"'+c.replace(o,function(a){var b=s[a];return typeof b==='string'?b:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+c+'"'}function q(a,b){var c,d,f,g,h=l,j,i=b[a];if(i&&typeof i==='object'&&typeof i.toJSON==='function'){i=i.toJSON(a)}if(typeof n==='function'){i=n.call(b,a,i)}switch(typeof i){case'string':return r(i);case'number':return isFinite(i)?String(i):'null';case'boolean':case'null':return String(i);case'object':if(!i){return'null'}l+=p;j=[];if(Object.prototype.toString.apply(i)==='[object Array]'){g=i.length;for(c=0;c<g;c+=1){j[c]=q(c,i)||'null'}f=j.length===0?'[]':l?'[\n'+l+j.join(',\n'+l)+'\n'+h+']':'['+j.join(',')+']';l=h;return f}if(n&&typeof n==='object'){g=n.length;for(c=0;c<g;c+=1){d=n[c];if(typeof d==='string'){f=q(d,i);if(f){j.push(r(d)+(l?': ':':')+f)}}}}else{for(d in i){if(Object.hasOwnProperty.call(i,d)){f=q(d,i);if(f){j.push(r(d)+(l?': ':':')+f)}}}}f=j.length===0?'{}':l?'{\n'+l+j.join(',\n'+l)+'\n'+h+'}':'{'+j.join(',')+'}';l=h;return f}}Faye.stringify=function(a,b,c){var d;l='';p='';if(typeof c==='number'){for(d=0;d<c;d+=1){p+=' '}}else if(typeof c==='string'){p=c}n=b;if(b&&typeof b!=='function'&&(typeof b!=='object'||typeof b.length!=='number')){throw new Error('JSON.stringify');}return q('',{'':a})};if(typeof JSON.stringify!=='function'){JSON.stringify=Faye.stringify}if(typeof JSON.parse!=='function'){JSON.parse=function(g,h){var j;function i(a,b){var c,d,f=a[b];if(f&&typeof f==='object'){for(c in f){if(Object.hasOwnProperty.call(f,c)){d=i(f,c);if(d!==undefined){f[c]=d}else{delete f[c]}}}}return h.call(a,b,f)}m.lastIndex=0;if(m.test(g)){g=g.replace(m,function(a){return'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(g.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+g+')');return typeof h==='function'?i({'':j},''):j}throw new SyntaxError('JSON.parse');}}}());Faye.Transport.WebSocket=Faye.extend(Faye.Class(Faye.Transport,{UNCONNECTED:1,CONNECTING:2,CONNECTED:3,batching:false,request:function(b,c){this._7=this._7||c;this._g=this._g||{};Faye.each(b,function(a){this._g[a.id]=a},this);this.withSocket(function(a){a.send(Faye.toJSON(b))})},withSocket:function(a,b){this.callback(a,b);this.connect()},connect:function(){this._1=this._1||this.UNCONNECTED;if(this._1!==this.UNCONNECTED)return;this._1=this.CONNECTING;this._b=new WebSocket(Faye.Transport.WebSocket.getSocketUrl(this._a));var d=this;this._b.onopen=function(){delete d._7;d._1=d.CONNECTED;d.setDeferredStatus('succeeded',d._b)};this._b.onmessage=function(b){var c=[].concat(JSON.parse(b.data));Faye.each(c,function(a){delete d._g[a.id]});d.receive(c)};this._b.onclose=function(){var a=(d._1===d.CONNECTED);d.setDeferredStatus('deferred');d._1=d.UNCONNECTED;delete d._b;if(a)return d.resend();Faye.ENV.setTimeout(function(){d.connect()},1000*d._7);d._7=d._7*2}},resend:function(){var c=Faye.map(this._g,function(a,b){return b});this.request(c)}}),{WEBSOCKET_TIMEOUT:1000,getSocketUrl:function(a){return Faye.URI.parse(a).toURL().replace(/^http(s?):/ig,'ws$1:')},isUsable:function(a,b,c){if(!Faye.ENV.WebSocket)return b.call(c,false);var d=false,f=this.getSocketUrl(a),g=new WebSocket(f);g.onopen=function(){d=true;g.close();b.call(c,true);g=null};var h=function(){if(!d)b.call(c,false)};g.onclose=g.onerror=h;Faye.ENV.setTimeout(h,this.WEBSOCKET_TIMEOUT)}});Faye.extend(Faye.Transport.WebSocket.prototype,Faye.Deferrable);Faye.Transport.register('websocket',Faye.Transport.WebSocket);Faye.Transport.XHR=Faye.extend(Faye.Class(Faye.Transport,{request:function(b,c){var d=this.retry(b,c),f=Faye.URI.parse(this._a).pathname,g=this,h=Faye.ENV.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();h.open('POST',f,true);h.setRequestHeader('Content-Type','application/json');h.setRequestHeader('X-Requested-With','XMLHttpRequest');h.onreadystatechange=function(){if(h.readyState!==4)return;var a=h.status;try{if((a>=200&&a<300)||a===304||a===1223)g.receive(JSON.parse(h.responseText));else d()}catch(e){d()}finally{Faye.Event.detach(Faye.ENV,'beforeunload',j);h.onreadystatechange=function(){};h=null}};var j=function(){h.abort()};Faye.Event.on(Faye.ENV,'beforeunload',j);h.send(Faye.toJSON(b))}}),{isUsable:function(a,b,c){b.call(c,Faye.URI.parse(a).isLocal())}});Faye.Transport.register('long-polling',Faye.Transport.XHR);Faye.Transport.CORS=Faye.extend(Faye.Class(Faye.Transport,{request:function(a,b){var c=Faye.ENV.XDomainRequest?XDomainRequest:XMLHttpRequest,d=new c(),f=this.retry(a,b),g=this;d.open('POST',this._a,true);d.onload=function(){try{g.receive(JSON.parse(d.responseText))}catch(e){f()}finally{d.onload=d.onerror=null;d=null}};d.onerror=f;d.onprogress=function(){};d.send('message='+encodeURIComponent(Faye.toJSON(a)))}}),{isUsable:function(a,b,c){if(Faye.URI.parse(a).isLocal())return b.call(c,false);if(Faye.ENV.XDomainRequest)return b.call(c,true);if(Faye.ENV.XMLHttpRequest){var d=new Faye.ENV.XMLHttpRequest();return b.call(c,d.withCredentials!==undefined)}return b.call(c,false)}});Faye.Transport.register('cross-origin-long-polling',Faye.Transport.CORS);Faye.Transport.JSONP=Faye.extend(Faye.Class(Faye.Transport,{request:function(b,c){var d={message:Faye.toJSON(b)},f=document.getElementsByTagName('head')[0],g=document.createElement('script'),h=Faye.Transport.JSONP.getCallbackName(),j=Faye.URI.parse(this._a,d),i=this;var k=function(){if(!g.parentNode)return false;g.parentNode.removeChild(g);return true};Faye.ENV[h]=function(a){Faye.ENV[h]=undefined;try{delete Faye.ENV[h]}catch(e){}if(!k())return;i.receive(a)};Faye.ENV.setTimeout(function(){if(!Faye.ENV[h])return;k();i.request(b,2*c)},1000*c);j.params.jsonp=h;g.type='text/javascript';g.src=j.toURL();f.appendChild(g)}}),{_x:0,getCallbackName:function(){this._x+=1;return'__jsonp'+this._x+'__'},isUsable:function(a,b,c){b.call(c,true)}});Faye.Transport.register('callback-polling',Faye.Transport.JSONP);
|
1
|
+
if(!this.Faye)Faye={};Faye.extend=function(a,b,c){if(!b)return a;for(var d in b){if(!b.hasOwnProperty(d))continue;if(a.hasOwnProperty(d)&&c===false)continue;if(a[d]!==b[d])a[d]=b[d]}return a};Faye.extend(Faye,{VERSION:'0.6.1',BAYEUX_VERSION:'1.0',ID_LENGTH:128,JSONP_CALLBACK:'jsonpcallback',CONNECTION_TYPES:['long-polling','cross-origin-long-polling','callback-polling','websocket','in-process'],MANDATORY_CONNECTION_TYPES:['long-polling','callback-polling','in-process'],ENV:(function(){return this})(),random:function(a){a=a||this.ID_LENGTH;if(a>32){var b=Math.ceil(a/32),c='';while(b--)c+=this.random(32);return c}var d=Math.pow(2,a)-1,f=d.toString(36).length,c=Math.floor(Math.random()*d).toString(36);while(c.length<f)c='0'+c;return c},commonElement:function(a,b){for(var c=0,d=a.length;c<d;c++){if(this.indexOf(b,a[c])!==-1)return a[c]}return null},indexOf:function(a,b){for(var c=0,d=a.length;c<d;c++){if(a[c]===b)return c}return-1},each:function(a,b,c){if(a instanceof Array){for(var d=0,f=a.length;d<f;d++){if(a[d]!==undefined)b.call(c||null,a[d],d)}}else{for(var g in a){if(a.hasOwnProperty(g))b.call(c||null,g,a[g])}}},map:function(a,b,c){var d=[];this.each(a,function(){d.push(b.apply(c||null,arguments))});return d},filter:function(a,b,c){var d=[];this.each(a,function(){if(b.apply(c,arguments))d.push(arguments[0])});return d},size:function(a){var b=0;this.each(a,function(){b+=1});return b},enumEqual:function(c,d){if(d instanceof Array){if(!(c instanceof Array))return false;var f=c.length;if(f!==d.length)return false;while(f--){if(c[f]!==d[f])return false}return true}else{if(!(c instanceof Object))return false;if(this.size(d)!==this.size(c))return false;var g=true;this.each(c,function(a,b){g=g&&(d[a]===b)});return g}},asyncEach:function(a,b,c,d){var f=a.length,g=-1,h=0,j=false;var i=function(){h-=1;g+=1;if(g===f)return c&&c.call(d);b(a[g],m)};var k=function(){if(j)return;j=true;while(h>0)i();j=false};var m=function(){h+=1;k()};m()},toJSON:function(a){if(this.stringify)return this.stringify(a,function(key,value){return(this[key]instanceof Array)?this[key]:value});return JSON.stringify(a)},timestamp:function(){var b=new Date(),c=b.getFullYear(),d=b.getMonth()+1,f=b.getDate(),g=b.getHours(),h=b.getMinutes(),j=b.getSeconds();var i=function(a){return a<10?'0'+a:String(a)};return i(c)+'-'+i(d)+'-'+i(f)+' '+i(g)+':'+i(h)+':'+i(j)}});Faye.Class=function(a,b){if(typeof a!=='function'){b=a;a=Object}var c=function(){if(!this.initialize)return this;return this.initialize.apply(this,arguments)||this};var d=function(){};d.prototype=a.prototype;c.prototype=new d();Faye.extend(c.prototype,b);return c};Faye.Namespace=Faye.Class({initialize:function(){this._c={}},exists:function(a){return this._c.hasOwnProperty(a)},generate:function(){var a=Faye.random();while(this._c.hasOwnProperty(a))a=Faye.random();return this._c[a]=a},release:function(a){delete this._c[a]}});Faye.Error=Faye.Class({initialize:function(a,b,c){this.code=a;this.params=Array.prototype.slice.call(b);this.message=c},toString:function(){return this.code+':'+this.params.join(',')+':'+this.message}});Faye.Error.parse=function(a){a=a||'';if(!Faye.Grammar.ERROR.test(a))return new this(null,[],a);var b=a.split(':'),c=parseInt(b[0]),d=b[1].split(','),a=b[2];return new this(c,d,a)};Faye.Error.versionMismatch=function(){return new this(300,arguments,"Version mismatch").toString()};Faye.Error.conntypeMismatch=function(){return new this(301,arguments,"Connection types not supported").toString()};Faye.Error.extMismatch=function(){return new this(302,arguments,"Extension mismatch").toString()};Faye.Error.badRequest=function(){return new this(400,arguments,"Bad request").toString()};Faye.Error.clientUnknown=function(){return new this(401,arguments,"Unknown client").toString()};Faye.Error.parameterMissing=function(){return new this(402,arguments,"Missing required parameter").toString()};Faye.Error.channelForbidden=function(){return new this(403,arguments,"Forbidden channel").toString()};Faye.Error.channelUnknown=function(){return new this(404,arguments,"Unknown channel").toString()};Faye.Error.channelInvalid=function(){return new this(405,arguments,"Invalid channel").toString()};Faye.Error.extUnknown=function(){return new this(406,arguments,"Unknown extension").toString()};Faye.Error.publishFailed=function(){return new this(407,arguments,"Failed to publish").toString()};Faye.Error.serverError=function(){return new this(500,arguments,"Internal server error").toString()};Faye.Deferrable={callback:function(a,b){if(!a)return;if(this._s==='succeeded')return a.apply(b,this._i);this._j=this._j||[];this._j.push([a,b])},errback:function(a,b){if(!a)return;if(this._s==='failed')return a.apply(b,this._i);this._k=this._k||[];this._k.push([a,b])},setDeferredStatus:function(){var a=Array.prototype.slice.call(arguments),b=a.shift(),c;this._s=b;this._i=a;if(b==='succeeded')c=this._j;else if(b==='failed')c=this._k;if(!c)return;var d;while(d=c.shift())d[0].apply(d[1],this._i)}};Faye.Publisher={countSubscribers:function(a){if(!this._3||!this._3[a])return 0;return this._3[a].length},addSubscriber:function(a,b,c){this._3=this._3||{};var d=this._3[a]=this._3[a]||[];d.push([b,c])},removeSubscriber:function(a,b,c){if(!this._3||!this._3[a])return;if(!b){delete this._3[a];return}var d=this._3[a],f=d.length;while(f--){if(b!==d[f][0])continue;if(c&&d[f][1]!==c)continue;d.splice(f,1)}},removeSubscribers:function(){this._3={}},publishEvent:function(){var b=Array.prototype.slice.call(arguments),c=b.shift();if(!this._3||!this._3[c])return;Faye.each(this._3[c],function(a){a[0].apply(a[1],b)})}};Faye.Timeouts={addTimeout:function(a,b,c,d){this._4=this._4||{};if(this._4.hasOwnProperty(a))return;var f=this;this._4[a]=Faye.ENV.setTimeout(function(){delete f._4[a];c.call(d)},1000*b)},removeTimeout:function(a){this._4=this._4||{};var b=this._4[a];if(!b)return;clearTimeout(b);delete this._4[a]}};Faye.Logging={LOG_LEVELS:{error:3,warn:2,info:1,debug:0},logLevel:'error',log:function(a,b){if(!Faye.logger)return;var c=Faye.Logging.LOG_LEVELS;if(c[Faye.Logging.logLevel]>c[b])return;var a=Array.prototype.slice.apply(a),d=' ['+b.toUpperCase()+'] [Faye',f=this.className,g=a.shift().replace(/\?/g,function(){try{return Faye.toJSON(a.shift())}catch(e){return'[Object]'}});for(var h in Faye){if(f)continue;if(typeof Faye[h]!=='function')continue;if(this instanceof Faye[h])f=h}if(f)d+='.'+f;d+='] ';Faye.logger(Faye.timestamp()+d+g)}};Faye.each(Faye.Logging.LOG_LEVELS,function(a,b){Faye.Logging[a]=function(){this.log(arguments,a)}});Faye.Grammar={LOWALPHA:/^[a-z]$/,UPALPHA:/^[A-Z]$/,ALPHA:/^([a-z]|[A-Z])$/,DIGIT:/^[0-9]$/,ALPHANUM:/^(([a-z]|[A-Z])|[0-9])$/,MARK:/^(\-|\_|\!|\~|\(|\)|\$|\@)$/,STRING:/^(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*$/,TOKEN:/^(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+$/,INTEGER:/^([0-9])+$/,CHANNEL_SEGMENT:/^(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+$/,CHANNEL_SEGMENTS:/^(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+(\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+)*$/,CHANNEL_NAME:/^\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+(\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+)*$/,WILD_CARD:/^\*{1,2}$/,CHANNEL_PATTERN:/^(\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+)*\/\*{1,2}$/,VERSION_ELEMENT:/^(([a-z]|[A-Z])|[0-9])(((([a-z]|[A-Z])|[0-9])|\-|\_))*$/,VERSION:/^([0-9])+(\.(([a-z]|[A-Z])|[0-9])(((([a-z]|[A-Z])|[0-9])|\-|\_))*)*$/,CLIENT_ID:/^((([a-z]|[A-Z])|[0-9]))+$/,ID:/^((([a-z]|[A-Z])|[0-9]))+$/,ERROR_MESSAGE:/^(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*$/,ERROR_ARGS:/^(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*(,(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*)*$/,ERROR_CODE:/^[0-9][0-9][0-9]$/,ERROR:/^([0-9][0-9][0-9]:(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*(,(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*)*:(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*|[0-9][0-9][0-9]::(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*)$/};Faye.Extensible={addExtension:function(a){this._5=this._5||[];this._5.push(a);if(a.added)a.added()},removeExtension:function(a){if(!this._5)return;var b=this._5.length;while(b--){if(this._5[b]!==a)continue;this._5.splice(b,1);if(a.removed)a.removed()}},pipeThroughExtensions:function(c,d,f,g){this.debug('Passing through ? extensions: ?',c,d);if(!this._5)return f.call(g,d);var h=this._5.slice();var j=function(a){if(!a)return f.call(g,a);var b=h.shift();if(!b)return f.call(g,a);if(b[c])b[c](a,j);else j(a)};j(d)}};Faye.extend(Faye.Extensible,Faye.Logging);Faye.Channel=Faye.Class({initialize:function(a){this.id=this.name=a},push:function(a){this.publishEvent('message',a)},isUnused:function(){return this.countSubscribers('message')===0}});Faye.extend(Faye.Channel.prototype,Faye.Publisher);Faye.extend(Faye.Channel,{HANDSHAKE:'/meta/handshake',CONNECT:'/meta/connect',SUBSCRIBE:'/meta/subscribe',UNSUBSCRIBE:'/meta/unsubscribe',DISCONNECT:'/meta/disconnect',META:'meta',SERVICE:'service',expand:function(a){var b=this.parse(a),c=['/**',a];var d=b.slice();d[d.length-1]='*';c.push(this.unparse(d));for(var f=1,g=b.length;f<g;f++){d=b.slice(0,f);d.push('**');c.push(this.unparse(d))}return c},isValid:function(a){return Faye.Grammar.CHANNEL_NAME.test(a)||Faye.Grammar.CHANNEL_PATTERN.test(a)},parse:function(a){if(!this.isValid(a))return null;return a.split('/').slice(1)},unparse:function(a){return'/'+a.join('/')},isMeta:function(a){var b=this.parse(a);return b?(b[0]===this.META):null},isService:function(a){var b=this.parse(a);return b?(b[0]===this.SERVICE):null},isSubscribable:function(a){if(!this.isValid(a))return null;return!this.isMeta(a)&&!this.isService(a)},Set:Faye.Class({initialize:function(){this._2={}},getKeys:function(){var c=[];Faye.each(this._2,function(a,b){c.push(a)});return c},remove:function(a){delete this._2[a]},hasSubscription:function(a){return this._2.hasOwnProperty(a)},subscribe:function(c,d,f){if(!d)return;Faye.each(c,function(a){var b=this._2[a]=this._2[a]||new Faye.Channel(a);b.addSubscriber('message',d,f)},this)},unsubscribe:function(a,b,c){var d=this._2[a];if(!d)return false;d.removeSubscriber('message',b,c);if(d.isUnused()){this.remove(a);return true}else{return false}},distributeMessage:function(c){var d=Faye.Channel.expand(c.channel);Faye.each(d,function(a){var b=this._2[a];if(b)b.publishEvent('message',c.data)},this)}})});Faye.Subscription=Faye.Class({initialize:function(a,b,c,d){this._8=a;this._2=b;this._l=c;this._m=d;this._t=false},cancel:function(){if(this._t)return;this._8.unsubscribe(this._2,this._l,this._m);this._t=true},unsubscribe:function(){this.cancel()}});Faye.extend(Faye.Subscription.prototype,Faye.Deferrable);Faye.Client=Faye.Class({UNCONNECTED:1,CONNECTING:2,CONNECTED:3,DISCONNECTED:4,HANDSHAKE:'handshake',RETRY:'retry',NONE:'none',CONNECTION_TIMEOUT:60.0,DEFAULT_ENDPOINT:'/bayeux',INTERVAL:0.0,initialize:function(b,c){this.info('New client created for ?',b);this.endpoint=b||this.DEFAULT_ENDPOINT;this._u=c||{};Faye.Transport.get(this,Faye.MANDATORY_CONNECTION_TYPES,function(a){this._d=a},this);this._1=this.UNCONNECTED;this._2=new Faye.Channel.Set();this._y=new Faye.Namespace();this._n={};this._6={reconnect:this.RETRY,interval:1000*(this._u.interval||this.INTERVAL),timeout:1000*(this._u.timeout||this.CONNECTION_TIMEOUT)};if(Faye.Event)Faye.Event.on(Faye.ENV,'beforeunload',this.disconnect,this)},getClientId:function(){return this._0},getState:function(){switch(this._1){case this.UNCONNECTED:return'UNCONNECTED';case this.CONNECTING:return'CONNECTING';case this.CONNECTED:return'CONNECTED';case this.DISCONNECTED:return'DISCONNECTED'}},handshake:function(c,d){if(this._6.reconnect===this.NONE)return;if(this._1!==this.UNCONNECTED)return;this._1=this.CONNECTING;var f=this;this.info('Initiating handshake with ?',this.endpoint);this._9({channel:Faye.Channel.HANDSHAKE,version:Faye.BAYEUX_VERSION,supportedConnectionTypes:[this._d.connectionType]},function(b){if(b.successful){this._1=this.CONNECTED;this._0=b.clientId;Faye.Transport.get(this,b.supportedConnectionTypes,function(a){this._d=a},this);this.info('Handshake successful: ?',this._0);this.subscribe(this._2.getKeys(),true);if(c)c.call(d)}else{this.info('Handshake unsuccessful');Faye.ENV.setTimeout(function(){f.handshake(c,d)},this._6.interval);this._1=this.UNCONNECTED}},this)},connect:function(a,b){if(this._6.reconnect===this.NONE)return;if(this._1===this.DISCONNECTED)return;if(this._1===this.UNCONNECTED)return this.handshake(function(){this.connect(a,b)},this);this.callback(a,b);if(this._1!==this.CONNECTED)return;this.info('Calling deferred actions for ?',this._0);this.setDeferredStatus('succeeded');this.setDeferredStatus('deferred');if(this._o)return;this._o=true;this.info('Initiating connection for ?',this._0);this._9({channel:Faye.Channel.CONNECT,clientId:this._0,connectionType:this._d.connectionType},this._v,this)},disconnect:function(){if(this._1!==this.CONNECTED)return;this._1=this.DISCONNECTED;this.info('Disconnecting ?',this._0);this._9({channel:Faye.Channel.DISCONNECT,clientId:this._0});this.info('Clearing channel listeners for ?',this._0);this._2=new Faye.Channel.Set()},subscribe:function(c,d,f){if(c instanceof Array)return Faye.each(c,function(channel){this.subscribe(channel,d,f)},this);var g=new Faye.Subscription(this,c,d,f);var h=(d===true);if(!h&&this._2.hasSubscription(c)){this._2.subscribe([c],d,f);g.setDeferredStatus('succeeded');return g}this.connect(function(){this.info('Client ? attempting to subscribe to ?',this._0,c);this._9({channel:Faye.Channel.SUBSCRIBE,clientId:this._0,subscription:c},function(a){if(!a.successful)return g.setDeferredStatus('failed',Faye.Error.parse(a.error));var b=[].concat(a.subscription);this.info('Subscription acknowledged for ? to ?',this._0,b);this._2.subscribe(b,d,f);g.setDeferredStatus('succeeded')},this)},this);return g},unsubscribe:function(c,d,f){if(c instanceof Array)return Faye.each(c,function(channel){this.unsubscribe(channel,d,f)},this);var g=this._2.unsubscribe(c,d,f);if(!g)return;this.connect(function(){this.info('Client ? attempting to unsubscribe from ?',this._0,c);this._9({channel:Faye.Channel.UNSUBSCRIBE,clientId:this._0,subscription:c},function(a){if(!a.successful)return;var b=[].concat(a.subscription);this.info('Unsubscription acknowledged for ? from ?',this._0,b)},this)},this)},publish:function(a,b){if(!Faye.Grammar.CHANNEL_NAME.test(a))throw new Error("Cannot publish: '"+a+"' is not a valid channel name");this.connect(function(){this.info('Client ? queueing published message to ?: ?',this._0,a,b);this._9({channel:a,data:b,clientId:this._0})},this)},receiveMessage:function(c){this.pipeThroughExtensions('incoming',c,function(a){if(!a)return;if(a.advice)this._z(a.advice);var b=this._n[a.id];if(b){delete this._n[a.id];b[0].call(b[1],a)}this._A(a)},this)},_9:function(b,c,d){b.id=this._y.generate();if(c)this._n[b.id]=[c,d];this.pipeThroughExtensions('outgoing',b,function(a){if(!a)return;this._d.send(a,this._6.timeout/1000)},this)},_z:function(a){Faye.extend(this._6,a);if(this._6.reconnect===this.HANDSHAKE&&this._1!==this.DISCONNECTED){this._1=this.UNCONNECTED;this._0=null;this._v()}},_A:function(a){if(!a.channel||!a.data)return;this.info('Client ? calling listeners for ? with ?',this._0,a.channel,a.data);this._2.distributeMessage(a)},_B:function(){if(!this._o)return;this._o=null;this.info('Closed connection for ?',this._0)},_v:function(){this._B();var a=this;Faye.ENV.setTimeout(function(){a.connect()},this._6.interval)}});Faye.extend(Faye.Client.prototype,Faye.Deferrable);Faye.extend(Faye.Client.prototype,Faye.Logging);Faye.extend(Faye.Client.prototype,Faye.Extensible);Faye.Transport=Faye.extend(Faye.Class({MAX_DELAY:0.0,batching:true,initialize:function(a,b){this.debug('Created new ? transport for ?',this.connectionType,b);this._8=a;this._a=b;this._e=[]},send:function(a,b){this.debug('Client ? sending message to ?: ?',this._8._0,this._a,a);if(!this.batching)return this.request([a],b);this._e.push(a);this._7=b;if(a.channel===Faye.Channel.HANDSHAKE)return this.flush();if(a.channel===Faye.Channel.CONNECT)this._p=a;this.addTimeout('publish',this.MAX_DELAY,this.flush,this)},flush:function(){this.removeTimeout('publish');if(this._e.length>1&&this._p)this._p.advice={timeout:0};this.request(this._e,this._7);this._p=null;this._e=[]},receive:function(a){this.debug('Client ? received from ?: ?',this._8._0,this._a,a);Faye.each(a,this._8.receiveMessage,this._8)},retry:function(a,b){var c=this;return function(){Faye.ENV.setTimeout(function(){c.request(a,2*b)},1000*b)}}}),{get:function(g,h,j,i){var k=g.endpoint;if(h===undefined)h=this.supportedConnectionTypes();Faye.asyncEach(this._q,function(b,c){var d=b[0],f=b[1];if(Faye.indexOf(h,d)<0)return c();f.isUsable(k,function(a){if(a)j.call(i,new f(g,k));else c()})},function(){throw new Error('Could not find a usable connection type for '+k);})},register:function(a,b){this._q.push([a,b]);b.prototype.connectionType=a},_q:[],supportedConnectionTypes:function(){return Faye.map(this._q,function(a){return a[0]})}});Faye.extend(Faye.Transport.prototype,Faye.Logging);Faye.extend(Faye.Transport.prototype,Faye.Timeouts);Faye.Event={_f:[],on:function(a,b,c,d){var f=function(){c.call(d)};if(a.addEventListener)a.addEventListener(b,f,false);else a.attachEvent('on'+b,f);this._f.push({_g:a,_r:b,_l:c,_m:d,_w:f})},detach:function(a,b,c,d){var f=this._f.length,g;while(f--){g=this._f[f];if((a&&a!==g._g)||(b&&b!==g._r)||(c&&c!==g._l)||(d&&d!==g._m))continue;if(g._g.removeEventListener)g._g.removeEventListener(g._r,g._w,false);else g._g.detachEvent('on'+g._r,g._w);this._f.splice(f,1);g=null}}};Faye.Event.on(Faye.ENV,'unload',Faye.Event.detach,Faye.Event);Faye.URI=Faye.extend(Faye.Class({queryString:function(){var c=[],d;Faye.each(this.params,function(a,b){c.push(encodeURIComponent(a)+'='+encodeURIComponent(b))});return c.join('&')},isLocal:function(){var a=Faye.URI.parse(Faye.ENV.location.href);var b=(a.hostname!==this.hostname)||(a.port!==this.port)||(a.protocol!==this.protocol);return!b},toURL:function(){var a=this.queryString();return this.protocol+this.hostname+':'+this.port+this.pathname+(a?'?'+a:'')}}),{parse:function(d,f){if(typeof d!=='string')return d;var g=new this();var h=function(b,c){d=d.replace(c,function(a){if(a)g[b]=a;return''})};h('protocol',/^https?\:\/+/);h('hostname',/^[^\/\:]+/);h('port',/^:[0-9]+/);Faye.extend(g,{protocol:'http://',hostname:Faye.ENV.location.hostname,port:Faye.ENV.location.port},false);if(!g.port)g.port=(g.protocol==='https://')?'443':'80';g.port=g.port.replace(/\D/g,'');var j=d.split('?'),i=j.shift(),k=j.join('?'),m=k?k.split('&'):[],o=m.length,l={};while(o--){j=m[o].split('=');l[decodeURIComponent(j[0]||'')]=decodeURIComponent(j[1]||'')}if(typeof f==='object')Faye.extend(l,f);g.pathname=i;g.params=l;return g}});if(!this.JSON){JSON={}}(function(){function k(a){return a<10?'0'+a:a}if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(a){return this.getUTCFullYear()+'-'+k(this.getUTCMonth()+1)+'-'+k(this.getUTCDate())+'T'+k(this.getUTCHours())+':'+k(this.getUTCMinutes())+':'+k(this.getUTCSeconds())+'Z'};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(a){return this.valueOf()}}var m=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,o=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,l,p,s={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},n;function r(c){o.lastIndex=0;return o.test(c)?'"'+c.replace(o,function(a){var b=s[a];return typeof b==='string'?b:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+c+'"'}function q(a,b){var c,d,f,g,h=l,j,i=b[a];if(i&&typeof i==='object'&&typeof i.toJSON==='function'){i=i.toJSON(a)}if(typeof n==='function'){i=n.call(b,a,i)}switch(typeof i){case'string':return r(i);case'number':return isFinite(i)?String(i):'null';case'boolean':case'null':return String(i);case'object':if(!i){return'null'}l+=p;j=[];if(Object.prototype.toString.apply(i)==='[object Array]'){g=i.length;for(c=0;c<g;c+=1){j[c]=q(c,i)||'null'}f=j.length===0?'[]':l?'[\n'+l+j.join(',\n'+l)+'\n'+h+']':'['+j.join(',')+']';l=h;return f}if(n&&typeof n==='object'){g=n.length;for(c=0;c<g;c+=1){d=n[c];if(typeof d==='string'){f=q(d,i);if(f){j.push(r(d)+(l?': ':':')+f)}}}}else{for(d in i){if(Object.hasOwnProperty.call(i,d)){f=q(d,i);if(f){j.push(r(d)+(l?': ':':')+f)}}}}f=j.length===0?'{}':l?'{\n'+l+j.join(',\n'+l)+'\n'+h+'}':'{'+j.join(',')+'}';l=h;return f}}Faye.stringify=function(a,b,c){var d;l='';p='';if(typeof c==='number'){for(d=0;d<c;d+=1){p+=' '}}else if(typeof c==='string'){p=c}n=b;if(b&&typeof b!=='function'&&(typeof b!=='object'||typeof b.length!=='number')){throw new Error('JSON.stringify');}return q('',{'':a})};if(typeof JSON.stringify!=='function'){JSON.stringify=Faye.stringify}if(typeof JSON.parse!=='function'){JSON.parse=function(g,h){var j;function i(a,b){var c,d,f=a[b];if(f&&typeof f==='object'){for(c in f){if(Object.hasOwnProperty.call(f,c)){d=i(f,c);if(d!==undefined){f[c]=d}else{delete f[c]}}}}return h.call(a,b,f)}m.lastIndex=0;if(m.test(g)){g=g.replace(m,function(a){return'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(g.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+g+')');return typeof h==='function'?i({'':j},''):j}throw new SyntaxError('JSON.parse');}}}());Faye.Transport.WebSocket=Faye.extend(Faye.Class(Faye.Transport,{UNCONNECTED:1,CONNECTING:2,CONNECTED:3,batching:false,request:function(b,c){this._7=this._7||c;this._h=this._h||{};Faye.each(b,function(a){this._h[a.id]=a},this);this.withSocket(function(a){a.send(Faye.toJSON(b))})},withSocket:function(a,b){this.callback(a,b);this.connect()},connect:function(){this._1=this._1||this.UNCONNECTED;if(this._1!==this.UNCONNECTED)return;this._1=this.CONNECTING;this._b=new WebSocket(Faye.Transport.WebSocket.getSocketUrl(this._a));var d=this;this._b.onopen=function(){delete d._7;d._1=d.CONNECTED;d.setDeferredStatus('succeeded',d._b)};this._b.onmessage=function(b){var c=[].concat(JSON.parse(b.data));Faye.each(c,function(a){delete d._h[a.id]});d.receive(c)};this._b.onclose=function(){var a=(d._1===d.CONNECTED);d.setDeferredStatus('deferred');d._1=d.UNCONNECTED;delete d._b;if(a)return d.resend();Faye.ENV.setTimeout(function(){d.connect()},1000*d._7);d._7=d._7*2}},resend:function(){var c=Faye.map(this._h,function(a,b){return b});this.request(c)}}),{WEBSOCKET_TIMEOUT:1000,getSocketUrl:function(a){return Faye.URI.parse(a).toURL().replace(/^http(s?):/ig,'ws$1:')},isUsable:function(a,b,c){if(!Faye.ENV.WebSocket)return b.call(c,false);var d=false,f=this.getSocketUrl(a),g=new WebSocket(f);g.onopen=function(){d=true;g.close();b.call(c,true);g=null};var h=function(){if(!d)b.call(c,false)};g.onclose=g.onerror=h;Faye.ENV.setTimeout(h,this.WEBSOCKET_TIMEOUT)}});Faye.extend(Faye.Transport.WebSocket.prototype,Faye.Deferrable);Faye.Transport.register('websocket',Faye.Transport.WebSocket);Faye.Transport.XHR=Faye.extend(Faye.Class(Faye.Transport,{request:function(b,c){var d=this.retry(b,c),f=Faye.URI.parse(this._a).pathname,g=this,h=Faye.ENV.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();h.open('POST',f,true);h.setRequestHeader('Content-Type','application/json');h.setRequestHeader('X-Requested-With','XMLHttpRequest');h.onreadystatechange=function(){if(h.readyState!==4)return;var a=h.status;try{if((a>=200&&a<300)||a===304||a===1223)g.receive(JSON.parse(h.responseText));else d()}catch(e){d()}finally{Faye.Event.detach(Faye.ENV,'beforeunload',j);h.onreadystatechange=function(){};h=null}};var j=function(){h.abort()};Faye.Event.on(Faye.ENV,'beforeunload',j);h.send(Faye.toJSON(b))}}),{isUsable:function(a,b,c){b.call(c,Faye.URI.parse(a).isLocal())}});Faye.Transport.register('long-polling',Faye.Transport.XHR);Faye.Transport.CORS=Faye.extend(Faye.Class(Faye.Transport,{request:function(a,b){var c=Faye.ENV.XDomainRequest?XDomainRequest:XMLHttpRequest,d=new c(),f=this.retry(a,b),g=this;d.open('POST',this._a,true);d.onload=function(){try{g.receive(JSON.parse(d.responseText))}catch(e){f()}finally{d.onload=d.onerror=null;d=null}};d.onerror=f;d.onprogress=function(){};d.send('message='+encodeURIComponent(Faye.toJSON(a)))}}),{isUsable:function(a,b,c){if(Faye.URI.parse(a).isLocal())return b.call(c,false);if(Faye.ENV.XDomainRequest)return b.call(c,true);if(Faye.ENV.XMLHttpRequest){var d=new Faye.ENV.XMLHttpRequest();return b.call(c,d.withCredentials!==undefined)}return b.call(c,false)}});Faye.Transport.register('cross-origin-long-polling',Faye.Transport.CORS);Faye.Transport.JSONP=Faye.extend(Faye.Class(Faye.Transport,{request:function(b,c){var d={message:Faye.toJSON(b)},f=document.getElementsByTagName('head')[0],g=document.createElement('script'),h=Faye.Transport.JSONP.getCallbackName(),j=Faye.URI.parse(this._a,d),i=this;var k=function(){if(!g.parentNode)return false;g.parentNode.removeChild(g);return true};Faye.ENV[h]=function(a){Faye.ENV[h]=undefined;try{delete Faye.ENV[h]}catch(e){}if(!k())return;i.receive(a)};Faye.ENV.setTimeout(function(){if(!Faye.ENV[h])return;k();i.request(b,2*c)},1000*c);j.params.jsonp=h;g.type='text/javascript';g.src=j.toURL();f.appendChild(g)}}),{_x:0,getCallbackName:function(){this._x+=1;return'__jsonp'+this._x+'__'},isUsable:function(a,b,c){b.call(c,true)}});Faye.Transport.register('callback-polling',Faye.Transport.JSONP);
|
data/lib/faye.rb
CHANGED
@@ -2,6 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'json'
|
3
3
|
require 'rack'
|
4
4
|
require 'thin'
|
5
|
+
require 'cgi'
|
5
6
|
require Faye::ROOT + '/thin_extensions'
|
6
7
|
|
7
8
|
module Faye
|
@@ -97,13 +98,16 @@ module Faye
|
|
97
98
|
private
|
98
99
|
|
99
100
|
def message_from_request(request)
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
101
|
+
return request.params['message'] unless request.post?
|
102
|
+
|
103
|
+
# Some clients do not send a content-type, e.g.
|
104
|
+
# Internet Explorer when using cross-origin-long-polling
|
105
|
+
content_type = request.env['CONTENT_TYPE'] || ''
|
106
|
+
|
107
|
+
case content_type.split(';').first
|
108
|
+
when 'application/json' then request.body.read
|
109
|
+
when 'text/plain' then CGI.parse(request.body.read)['message'][0]
|
110
|
+
else request.params['message']
|
107
111
|
end
|
108
112
|
end
|
109
113
|
|
data/lib/faye/engines/memory.rb
CHANGED
@@ -3,35 +3,36 @@ module Faye
|
|
3
3
|
|
4
4
|
class Memory < Base
|
5
5
|
def initialize(options)
|
6
|
+
@namespace = Namespace.new
|
6
7
|
@clients = {}
|
7
8
|
@channels = {}
|
8
9
|
@messages = {}
|
9
|
-
@namespace = Namespace.new
|
10
10
|
super
|
11
11
|
end
|
12
12
|
|
13
13
|
def create_client(&callback)
|
14
14
|
client_id = @namespace.generate
|
15
15
|
debug 'Created new client ?', client_id
|
16
|
-
@clients[client_id] = Set.new
|
17
16
|
ping(client_id)
|
18
17
|
callback.call(client_id)
|
19
18
|
end
|
20
19
|
|
21
20
|
def destroy_client(client_id, &callback)
|
22
|
-
return unless @
|
23
|
-
|
24
|
-
|
21
|
+
return unless @namespace.exists?(client_id)
|
22
|
+
|
23
|
+
if @clients.has_key?(client_id)
|
24
|
+
@clients[client_id].each { |channel| unsubscribe(client_id, channel) }
|
25
25
|
end
|
26
|
+
|
26
27
|
remove_timeout(client_id)
|
27
|
-
@
|
28
|
+
@namespace.release(client_id)
|
28
29
|
@messages.delete(client_id)
|
29
30
|
debug 'Destroyed client ?', client_id
|
30
31
|
callback.call if callback
|
31
32
|
end
|
32
33
|
|
33
34
|
def client_exists(client_id, &callback)
|
34
|
-
callback.call(@
|
35
|
+
callback.call(@namespace.exists?(client_id))
|
35
36
|
end
|
36
37
|
|
37
38
|
def ping(client_id)
|
@@ -44,16 +45,26 @@ module Faye
|
|
44
45
|
|
45
46
|
def subscribe(client_id, channel, &callback)
|
46
47
|
@clients[client_id] ||= Set.new
|
47
|
-
@channels[channel] ||= Set.new
|
48
48
|
@clients[client_id].add(channel)
|
49
|
+
|
50
|
+
@channels[channel] ||= Set.new
|
49
51
|
@channels[channel].add(client_id)
|
52
|
+
|
50
53
|
debug 'Subscribed client ? to channel ?', client_id, channel
|
51
54
|
callback.call(true) if callback
|
52
55
|
end
|
53
56
|
|
54
57
|
def unsubscribe(client_id, channel, &callback)
|
55
|
-
|
56
|
-
|
58
|
+
if @clients.has_key?(client_id)
|
59
|
+
@clients[client_id].delete(channel)
|
60
|
+
@clients.delete(client_id) if @clients[client_id].empty?
|
61
|
+
end
|
62
|
+
|
63
|
+
if @channels.has_key?(channel)
|
64
|
+
@channels[channel].delete(client_id)
|
65
|
+
@channels.delete(channel) if @channels[channel].empty?
|
66
|
+
end
|
67
|
+
|
57
68
|
debug 'Unsubscribed client ? from channel ?', client_id, channel
|
58
69
|
callback.call(true) if callback
|
59
70
|
end
|
data/lib/faye/util/namespace.rb
CHANGED
@@ -114,6 +114,7 @@ JS.ENV.NodeAdapterSpec = JS.Test.describe("NodeAdapter", function() { with(this)
|
|
114
114
|
describe("with cross-origin access control", function() { with(this) {
|
115
115
|
before(function() { with(this) {
|
116
116
|
header("Origin", "http://example.com")
|
117
|
+
header("Content-Type", "text/plain")
|
117
118
|
}})
|
118
119
|
|
119
120
|
it("returns a matching cross-origin access control header", function() { with(this) {
|
@@ -123,13 +124,13 @@ JS.ENV.NodeAdapterSpec = JS.Test.describe("NodeAdapter", function() { with(this)
|
|
123
124
|
}})
|
124
125
|
|
125
126
|
it("forwards the message param onto the server", function() { with(this) {
|
126
|
-
expect(server, "process").given({channel: "/
|
127
|
-
post("/bayeux",
|
127
|
+
expect(server, "process").given({channel: "/plain"}, false).yielding([[]])
|
128
|
+
post("/bayeux", "message=%7B%22channel%22%3A%22%2Fplain%22%7D")
|
128
129
|
}})
|
129
130
|
|
130
131
|
it("returns the server's response as JSON", function() { with(this) {
|
131
132
|
stub(server, "process").yields([[{channel: "/meta/handshake"}]])
|
132
|
-
post("/bayeux",
|
133
|
+
post("/bayeux", "message=%5B%5D")
|
133
134
|
check_status(200)
|
134
135
|
check_content_type("application/json")
|
135
136
|
check_json([{channel: "/meta/handshake"}])
|
@@ -137,7 +138,7 @@ JS.ENV.NodeAdapterSpec = JS.Test.describe("NodeAdapter", function() { with(this)
|
|
137
138
|
|
138
139
|
it("returns a 400 response if malformed JSON is given", function() { with(this) {
|
139
140
|
expect(server, "process").exactly(0)
|
140
|
-
post("/bayeux",
|
141
|
+
post("/bayeux", "message=%7B%5B")
|
141
142
|
check_status(400)
|
142
143
|
check_content_type("text/plain")
|
143
144
|
}})
|
@@ -25,7 +25,7 @@ JS.ENV.Server.HandshakeSpec = JS.Test.describe("Server handshake", function() {
|
|
25
25
|
channel: "/meta/handshake",
|
26
26
|
successful: true,
|
27
27
|
version: "1.0",
|
28
|
-
supportedConnectionTypes: ["long-polling", "cross-origin-long-polling", "callback-polling", "websocket"],
|
28
|
+
supportedConnectionTypes: ["long-polling", "cross-origin-long-polling", "callback-polling", "websocket","in-process"],
|
29
29
|
clientId: "clientid"
|
30
30
|
}, response)
|
31
31
|
})
|
@@ -41,7 +41,7 @@ JS.ENV.Server.HandshakeSpec = JS.Test.describe("Server handshake", function() {
|
|
41
41
|
channel: "/meta/handshake",
|
42
42
|
successful: true,
|
43
43
|
version: "1.0",
|
44
|
-
supportedConnectionTypes: ["long-polling", "cross-origin-long-polling", "callback-polling", "websocket"],
|
44
|
+
supportedConnectionTypes: ["long-polling", "cross-origin-long-polling", "callback-polling", "websocket","in-process"],
|
45
45
|
clientId: "clientid",
|
46
46
|
id: "foo"
|
47
47
|
}, response)
|
@@ -65,7 +65,7 @@ JS.ENV.Server.HandshakeSpec = JS.Test.describe("Server handshake", function() {
|
|
65
65
|
successful: false,
|
66
66
|
error: "402:version:Missing required parameter",
|
67
67
|
version: "1.0",
|
68
|
-
supportedConnectionTypes: ["long-polling", "cross-origin-long-polling", "callback-polling", "websocket"]
|
68
|
+
supportedConnectionTypes: ["long-polling", "cross-origin-long-polling", "callback-polling", "websocket","in-process"]
|
69
69
|
}, response)
|
70
70
|
})
|
71
71
|
}})
|
@@ -86,7 +86,7 @@ JS.ENV.Server.HandshakeSpec = JS.Test.describe("Server handshake", function() {
|
|
86
86
|
successful: false,
|
87
87
|
error: "402:supportedConnectionTypes:Missing required parameter",
|
88
88
|
version: "1.0",
|
89
|
-
supportedConnectionTypes: ["long-polling", "cross-origin-long-polling", "callback-polling", "websocket"]
|
89
|
+
supportedConnectionTypes: ["long-polling", "cross-origin-long-polling", "callback-polling", "websocket","in-process"]
|
90
90
|
}, response)
|
91
91
|
})
|
92
92
|
}})
|
@@ -121,7 +121,7 @@ JS.ENV.Server.HandshakeSpec = JS.Test.describe("Server handshake", function() {
|
|
121
121
|
successful: false,
|
122
122
|
error: "301:iframe,flash:Connection types not supported",
|
123
123
|
version: "1.0",
|
124
|
-
supportedConnectionTypes: ["long-polling", "cross-origin-long-polling", "callback-polling", "websocket"]
|
124
|
+
supportedConnectionTypes: ["long-polling", "cross-origin-long-polling", "callback-polling", "websocket","in-process"]
|
125
125
|
}, response)
|
126
126
|
})
|
127
127
|
}})
|
@@ -144,7 +144,7 @@ JS.ENV.Server.HandshakeSpec = JS.Test.describe("Server handshake", function() {
|
|
144
144
|
successful: false,
|
145
145
|
error: "invalid",
|
146
146
|
version: "1.0",
|
147
|
-
supportedConnectionTypes: ["long-polling", "cross-origin-long-polling", "callback-polling", "websocket"]
|
147
|
+
supportedConnectionTypes: ["long-polling", "cross-origin-long-polling", "callback-polling", "websocket","in-process"]
|
148
148
|
}, response)
|
149
149
|
})
|
150
150
|
}})
|
@@ -22,6 +22,7 @@ describe Faye::RackAdapter do
|
|
22
22
|
describe "POST requests" do
|
23
23
|
describe "with cross-origin access control" do
|
24
24
|
before do
|
25
|
+
header "Content-Type", "text/plain"
|
25
26
|
header "Origin", "http://example.com"
|
26
27
|
end
|
27
28
|
|
@@ -32,13 +33,13 @@ describe Faye::RackAdapter do
|
|
32
33
|
end
|
33
34
|
|
34
35
|
it "forwards the message param onto the server" do
|
35
|
-
server.should_receive(:process).with({"channel" => "/
|
36
|
-
post "/bayeux",
|
36
|
+
server.should_receive(:process).with({"channel" => "/plain"}, false).and_yield []
|
37
|
+
post "/bayeux", "message=%7B%22channel%22%3A%22%2Fplain%22%7D"
|
37
38
|
end
|
38
39
|
|
39
40
|
it "returns the server's response as JSON" do
|
40
41
|
server.stub(:process).and_yield ["channel" => "/meta/handshake"]
|
41
|
-
post "/bayeux",
|
42
|
+
post "/bayeux", "message=%5B%5D"
|
42
43
|
status.should == 200
|
43
44
|
content_type.should == "application/json"
|
44
45
|
json.should == ["channel" => "/meta/handshake"]
|
@@ -46,14 +47,14 @@ describe Faye::RackAdapter do
|
|
46
47
|
|
47
48
|
it "returns a 400 response if malformed JSON is given" do
|
48
49
|
server.should_not_receive(:process)
|
49
|
-
post "/bayeux",
|
50
|
+
post "/bayeux", "message=%7B%5B"
|
50
51
|
status.should == 400
|
51
52
|
content_type.should == "text/plain"
|
52
53
|
end
|
53
54
|
|
54
55
|
it "returns a 404 if the path is not matched" do
|
55
56
|
server.should_not_receive(:process)
|
56
|
-
post "/blaf",
|
57
|
+
post "/blaf", 'message=%5B%5D'
|
57
58
|
status.should == 404
|
58
59
|
content_type.should == "text/plain"
|
59
60
|
end
|
@@ -27,7 +27,7 @@ describe "server handshake" do
|
|
27
27
|
"channel" => "/meta/handshake",
|
28
28
|
"successful" => true,
|
29
29
|
"version" => "1.0",
|
30
|
-
"supportedConnectionTypes" => ["long-polling","cross-origin-long-polling","callback-polling","websocket"],
|
30
|
+
"supportedConnectionTypes" => ["long-polling","cross-origin-long-polling","callback-polling","websocket","in-process"],
|
31
31
|
"clientId" => "clientid"
|
32
32
|
}
|
33
33
|
end
|
@@ -43,7 +43,7 @@ describe "server handshake" do
|
|
43
43
|
"channel" => "/meta/handshake",
|
44
44
|
"successful" => true,
|
45
45
|
"version" => "1.0",
|
46
|
-
"supportedConnectionTypes" => ["long-polling","cross-origin-long-polling","callback-polling","websocket"],
|
46
|
+
"supportedConnectionTypes" => ["long-polling","cross-origin-long-polling","callback-polling","websocket","in-process"],
|
47
47
|
"clientId" => "clientid",
|
48
48
|
"id" => "foo"
|
49
49
|
}
|
@@ -67,7 +67,7 @@ describe "server handshake" do
|
|
67
67
|
"successful" => false,
|
68
68
|
"error" => "402:version:Missing required parameter",
|
69
69
|
"version" => "1.0",
|
70
|
-
"supportedConnectionTypes" => ["long-polling","cross-origin-long-polling","callback-polling","websocket"]
|
70
|
+
"supportedConnectionTypes" => ["long-polling","cross-origin-long-polling","callback-polling","websocket","in-process"]
|
71
71
|
}
|
72
72
|
end
|
73
73
|
end
|
@@ -88,7 +88,7 @@ describe "server handshake" do
|
|
88
88
|
"successful" => false,
|
89
89
|
"error" => "402:supportedConnectionTypes:Missing required parameter",
|
90
90
|
"version" => "1.0",
|
91
|
-
"supportedConnectionTypes" => ["long-polling","cross-origin-long-polling","callback-polling","websocket"]
|
91
|
+
"supportedConnectionTypes" => ["long-polling","cross-origin-long-polling","callback-polling","websocket","in-process"]
|
92
92
|
}
|
93
93
|
end
|
94
94
|
end
|
@@ -121,7 +121,7 @@ describe "server handshake" do
|
|
121
121
|
"successful" => false,
|
122
122
|
"error" => "301:iframe,flash:Connection types not supported",
|
123
123
|
"version" => "1.0",
|
124
|
-
"supportedConnectionTypes" => ["long-polling","cross-origin-long-polling","callback-polling","websocket"]
|
124
|
+
"supportedConnectionTypes" => ["long-polling","cross-origin-long-polling","callback-polling","websocket","in-process"]
|
125
125
|
}
|
126
126
|
end
|
127
127
|
end
|
@@ -142,7 +142,7 @@ describe "server handshake" do
|
|
142
142
|
"successful" => false,
|
143
143
|
"error" => "invalid",
|
144
144
|
"version" => "1.0",
|
145
|
-
"supportedConnectionTypes" => ["long-polling","cross-origin-long-polling","callback-polling","websocket"]
|
145
|
+
"supportedConnectionTypes" => ["long-polling","cross-origin-long-polling","callback-polling","websocket","in-process"]
|
146
146
|
}
|
147
147
|
end
|
148
148
|
end
|
metadata
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: faye
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 5
|
4
5
|
prerelease:
|
5
|
-
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 6
|
9
|
+
- 1
|
10
|
+
version: 0.6.1
|
6
11
|
platform: ruby
|
7
12
|
authors:
|
8
13
|
- James Coglan
|
@@ -10,7 +15,7 @@ autorequire:
|
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
17
|
|
13
|
-
date: 2011-
|
18
|
+
date: 2011-06-06 00:00:00 +01:00
|
14
19
|
default_executable:
|
15
20
|
dependencies:
|
16
21
|
- !ruby/object:Gem::Dependency
|
@@ -21,6 +26,11 @@ dependencies:
|
|
21
26
|
requirements:
|
22
27
|
- - ~>
|
23
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 47
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 12
|
33
|
+
- 0
|
24
34
|
version: 0.12.0
|
25
35
|
type: :runtime
|
26
36
|
version_requirements: *id001
|
@@ -32,6 +42,10 @@ dependencies:
|
|
32
42
|
requirements:
|
33
43
|
- - ">="
|
34
44
|
- !ruby/object:Gem::Version
|
45
|
+
hash: 15
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
- 2
|
35
49
|
version: "0.2"
|
36
50
|
type: :runtime
|
37
51
|
version_requirements: *id002
|
@@ -43,6 +57,11 @@ dependencies:
|
|
43
57
|
requirements:
|
44
58
|
- - ">="
|
45
59
|
- !ruby/object:Gem::Version
|
60
|
+
hash: 29
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
- 0
|
64
|
+
- 1
|
46
65
|
version: 0.0.1
|
47
66
|
type: :runtime
|
48
67
|
version_requirements: *id003
|
@@ -54,6 +73,10 @@ dependencies:
|
|
54
73
|
requirements:
|
55
74
|
- - ">="
|
56
75
|
- !ruby/object:Gem::Version
|
76
|
+
hash: 15
|
77
|
+
segments:
|
78
|
+
- 1
|
79
|
+
- 0
|
57
80
|
version: "1.0"
|
58
81
|
type: :runtime
|
59
82
|
version_requirements: *id004
|
@@ -65,6 +88,10 @@ dependencies:
|
|
65
88
|
requirements:
|
66
89
|
- - ~>
|
67
90
|
- !ruby/object:Gem::Version
|
91
|
+
hash: 11
|
92
|
+
segments:
|
93
|
+
- 1
|
94
|
+
- 2
|
68
95
|
version: "1.2"
|
69
96
|
type: :runtime
|
70
97
|
version_requirements: *id005
|
@@ -76,6 +103,10 @@ dependencies:
|
|
76
103
|
requirements:
|
77
104
|
- - ">="
|
78
105
|
- !ruby/object:Gem::Version
|
106
|
+
hash: 15
|
107
|
+
segments:
|
108
|
+
- 1
|
109
|
+
- 0
|
79
110
|
version: "1.0"
|
80
111
|
type: :runtime
|
81
112
|
version_requirements: *id006
|
@@ -87,42 +118,70 @@ dependencies:
|
|
87
118
|
requirements:
|
88
119
|
- - ">="
|
89
120
|
- !ruby/object:Gem::Version
|
121
|
+
hash: 3
|
122
|
+
segments:
|
123
|
+
- 0
|
90
124
|
version: "0"
|
91
125
|
type: :development
|
92
126
|
version_requirements: *id007
|
93
127
|
- !ruby/object:Gem::Dependency
|
94
|
-
name:
|
128
|
+
name: rake
|
95
129
|
prerelease: false
|
96
130
|
requirement: &id008 !ruby/object:Gem::Requirement
|
97
131
|
none: false
|
98
132
|
requirements:
|
99
133
|
- - ">="
|
100
134
|
- !ruby/object:Gem::Version
|
135
|
+
hash: 3
|
136
|
+
segments:
|
137
|
+
- 0
|
101
138
|
version: "0"
|
102
139
|
type: :development
|
103
140
|
version_requirements: *id008
|
104
141
|
- !ruby/object:Gem::Dependency
|
105
|
-
name:
|
142
|
+
name: rspec
|
106
143
|
prerelease: false
|
107
144
|
requirement: &id009 !ruby/object:Gem::Requirement
|
108
145
|
none: false
|
109
146
|
requirements:
|
110
|
-
- -
|
147
|
+
- - ~>
|
111
148
|
- !ruby/object:Gem::Version
|
112
|
-
|
149
|
+
hash: 27
|
150
|
+
segments:
|
151
|
+
- 2
|
152
|
+
- 5
|
153
|
+
- 0
|
154
|
+
version: 2.5.0
|
113
155
|
type: :development
|
114
156
|
version_requirements: *id009
|
115
157
|
- !ruby/object:Gem::Dependency
|
116
|
-
name: rack-
|
158
|
+
name: rack-proxy
|
117
159
|
prerelease: false
|
118
160
|
requirement: &id010 !ruby/object:Gem::Requirement
|
119
161
|
none: false
|
120
162
|
requirements:
|
121
163
|
- - ">="
|
122
164
|
- !ruby/object:Gem::Version
|
165
|
+
hash: 3
|
166
|
+
segments:
|
167
|
+
- 0
|
123
168
|
version: "0"
|
124
169
|
type: :development
|
125
170
|
version_requirements: *id010
|
171
|
+
- !ruby/object:Gem::Dependency
|
172
|
+
name: rack-test
|
173
|
+
prerelease: false
|
174
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
175
|
+
none: false
|
176
|
+
requirements:
|
177
|
+
- - ">="
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
hash: 3
|
180
|
+
segments:
|
181
|
+
- 0
|
182
|
+
version: "0"
|
183
|
+
type: :development
|
184
|
+
version_requirements: *id011
|
126
185
|
description:
|
127
186
|
email: jcoglan@gmail.com
|
128
187
|
executables: []
|
@@ -133,7 +192,6 @@ extra_rdoc_files:
|
|
133
192
|
- README.rdoc
|
134
193
|
files:
|
135
194
|
- History.txt
|
136
|
-
- Rakefile
|
137
195
|
- README.rdoc
|
138
196
|
- lib/faye-browser-min.js
|
139
197
|
- spec/browser.html
|
@@ -207,12 +265,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
207
265
|
requirements:
|
208
266
|
- - ">="
|
209
267
|
- !ruby/object:Gem::Version
|
268
|
+
hash: 3
|
269
|
+
segments:
|
270
|
+
- 0
|
210
271
|
version: "0"
|
211
272
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
212
273
|
none: false
|
213
274
|
requirements:
|
214
275
|
- - ">="
|
215
276
|
- !ruby/object:Gem::Version
|
277
|
+
hash: 3
|
278
|
+
segments:
|
279
|
+
- 0
|
216
280
|
version: "0"
|
217
281
|
requirements: []
|
218
282
|
|
data/Rakefile
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require './lib/faye'
|
3
|
-
|
4
|
-
task :example, :port do |t, args|
|
5
|
-
system "rackup -s thin -E production -p #{args[:port]} examples/rack/config.ru"
|
6
|
-
end
|
7
|
-
|
8
|
-
task :handshake, :port, :n, :c do |t, args|
|
9
|
-
require 'cgi'
|
10
|
-
require 'json'
|
11
|
-
|
12
|
-
message = {:channel => '/meta/handshake',
|
13
|
-
:version => '1.0',
|
14
|
-
:supportedConnectionTypes => ['long-polling']}
|
15
|
-
|
16
|
-
message = CGI.escape(JSON.dump message)
|
17
|
-
url = "http://127.0.0.1:#{args[:port]}/bayeux?jsonp=callback&message=#{message}"
|
18
|
-
puts "Request URL:\n#{url}\n\n"
|
19
|
-
|
20
|
-
system "ab -n #{args[:n]} -c #{args[:c]} '#{url}'"
|
21
|
-
end
|