@@ -13,6 +13,7 @@ import { StatsManager } from "../core/stats/StatsManager";
13
13
import { PacketReceiver } from "./polling/PacketReceiver" ;
14
14
import { CONSTANTS } from "./Constants" ;
15
15
import { stringify } from "../../utils/json" ;
16
+ import { isNodeSdk } from "../../utils/environment" ;
16
17
17
18
// URL query parameters associated with longpolling
18
19
// TODO: move more of these out of the global namespace
@@ -175,7 +176,8 @@ export class BrowserPollConnection {
175
176
if ( self . lastSessionId ) {
176
177
urlParams [ CONSTANTS . LAST_SESSION_PARAM ] = self . lastSessionId ;
177
178
}
178
- if ( typeof location !== 'undefined' &&
179
+ if ( ! isNodeSdk ( ) &&
180
+ typeof location !== 'undefined' &&
179
181
location . href &&
180
182
location . href . indexOf ( CONSTANTS . FORGE_DOMAIN ) !== - 1 ) {
181
183
urlParams [ CONSTANTS . REFERER_PARAM ] = CONSTANTS . FORGE_REF ;
@@ -220,7 +222,8 @@ export class BrowserPollConnection {
220
222
! BrowserPollConnection . forceDisallow_ &&
221
223
typeof document !== 'undefined' && document . createElement != null &&
222
224
! isChromeExtensionContentScript ( ) &&
223
- ! isWindowsStoreApp ( )
225
+ ! isWindowsStoreApp ( ) &&
226
+ ! isNodeSdk ( )
224
227
) ;
225
228
} ;
226
229
@@ -313,6 +316,7 @@ export class BrowserPollConnection {
313
316
* @param {!string } pw
314
317
*/
315
318
addDisconnectPingFrame ( id , pw ) {
319
+ if ( isNodeSdk ( ) ) return ;
316
320
this . myDisconnFrame = document . createElement ( 'iframe' ) ;
317
321
var urlParams = { } ;
318
322
urlParams [ FIREBASE_LONGPOLL_DISCONN_FRAME_REQUEST_PARAM ] = 't' ;
@@ -370,36 +374,42 @@ function FirebaseIFrameScriptHolder(commandCB, onMessageCB, onDisconnectCB, urlF
370
374
// incoming data from the server that we're waiting for).
371
375
this . sendNewPolls = true ;
372
376
373
- //Each script holder registers a couple of uniquely named callbacks with the window. These are called from the
374
- //iframes where we put the long-polling script tags. We have two callbacks:
375
- // 1) Command Callback - Triggered for control issues, like starting a connection.
376
- // 2) Message Callback - Triggered when new data arrives.
377
- this . uniqueCallbackIdentifier = LUIDGenerator ( ) ;
378
- window [ FIREBASE_LONGPOLL_COMMAND_CB_NAME + this . uniqueCallbackIdentifier ] = commandCB ;
379
- window [ FIREBASE_LONGPOLL_DATA_CB_NAME + this . uniqueCallbackIdentifier ] = onMessageCB ;
380
-
381
- //Create an iframe for us to add script tags to.
382
- this . myIFrame = this . createIFrame_ ( ) ;
383
-
384
- // Set the iframe's contents.
385
- var script = '' ;
386
- // if we set a javascript url, it's IE and we need to set the document domain. The javascript url is sufficient
387
- // for ie9, but ie8 needs to do it again in the document itself.
388
- if ( this . myIFrame . src && this . myIFrame . src . substr ( 0 , 'javascript:' . length ) === 'javascript:' ) {
389
- var currentDomain = document . domain ;
390
- script = '<script>document.domain="' + currentDomain + '";</script>' ;
391
- }
392
- var iframeContents = '<html><body>' + script + '</body></html>' ;
393
- try {
394
- this . myIFrame . doc . open ( ) ;
395
- this . myIFrame . doc . write ( iframeContents ) ;
396
- this . myIFrame . doc . close ( ) ;
397
- } catch ( e ) {
398
- log ( 'frame writing exception' ) ;
399
- if ( e . stack ) {
400
- log ( e . stack ) ;
377
+
378
+ if ( ! isNodeSdk ( ) ) {
379
+ //Each script holder registers a couple of uniquely named callbacks with the window. These are called from the
380
+ //iframes where we put the long-polling script tags. We have two callbacks:
381
+ // 1) Command Callback - Triggered for control issues, like starting a connection.
382
+ // 2) Message Callback - Triggered when new data arrives.
383
+ this . uniqueCallbackIdentifier = LUIDGenerator ( ) ;
384
+ window [ FIREBASE_LONGPOLL_COMMAND_CB_NAME + this . uniqueCallbackIdentifier ] = commandCB ;
385
+ window [ FIREBASE_LONGPOLL_DATA_CB_NAME + this . uniqueCallbackIdentifier ] = onMessageCB ;
386
+
387
+ //Create an iframe for us to add script tags to.
388
+ this . myIFrame = this . createIFrame_ ( ) ;
389
+
390
+ // Set the iframe's contents.
391
+ var script = '' ;
392
+ // if we set a javascript url, it's IE and we need to set the document domain. The javascript url is sufficient
393
+ // for ie9, but ie8 needs to do it again in the document itself.
394
+ if ( this . myIFrame . src && this . myIFrame . src . substr ( 0 , 'javascript:' . length ) === 'javascript:' ) {
395
+ var currentDomain = document . domain ;
396
+ script = '<script>document.domain="' + currentDomain + '";</script>' ;
397
+ }
398
+ var iframeContents = '<html><body>' + script + '</body></html>' ;
399
+ try {
400
+ this . myIFrame . doc . open ( ) ;
401
+ this . myIFrame . doc . write ( iframeContents ) ;
402
+ this . myIFrame . doc . close ( ) ;
403
+ } catch ( e ) {
404
+ log ( 'frame writing exception' ) ;
405
+ if ( e . stack ) {
406
+ log ( e . stack ) ;
407
+ }
408
+ log ( e ) ;
401
409
}
402
- log ( e ) ;
410
+ } else {
411
+ this . commandCB = commandCB ;
412
+ this . onMessageCB = onMessageCB ;
403
413
}
404
414
}
405
415
@@ -468,6 +478,15 @@ FirebaseIFrameScriptHolder.prototype.close = function() {
468
478
} , Math . floor ( 0 ) ) ;
469
479
}
470
480
481
+ if ( isNodeSdk ( ) && this . myID ) {
482
+ var urlParams = { } ;
483
+ urlParams [ FIREBASE_LONGPOLL_DISCONN_FRAME_PARAM ] = 't' ;
484
+ urlParams [ FIREBASE_LONGPOLL_ID_PARAM ] = this . myID ;
485
+ urlParams [ FIREBASE_LONGPOLL_PW_PARAM ] = this . myPW ;
486
+ var theURL = this . urlFn ( urlParams ) ;
487
+ FirebaseIFrameScriptHolder . nodeRestRequest ( theURL ) ;
488
+ }
489
+
471
490
// Protect from being called recursively.
472
491
var onDisconnect = this . onDisconnect ;
473
492
if ( onDisconnect ) {
@@ -590,33 +609,87 @@ FirebaseIFrameScriptHolder.prototype.addLongPollTag_ = function(url, serial) {
590
609
* @param {!function() } loadCB - A callback to be triggered once the script has loaded.
591
610
*/
592
611
FirebaseIFrameScriptHolder . prototype . addTag = function ( url , loadCB ) {
593
- var self = this ;
594
- setTimeout ( function ( ) {
595
- try {
596
- // if we're already closed, don't add this poll
597
- if ( ! self . sendNewPolls ) return ;
598
- var newScript = self . myIFrame . doc . createElement ( 'script' ) ;
599
- newScript . type = 'text/javascript' ;
600
- newScript . async = true ;
601
- newScript . src = url ;
602
- newScript . onload = newScript . onreadystatechange = function ( ) {
603
- var rstate = newScript . readyState ;
604
- if ( ! rstate || rstate === 'loaded' || rstate === 'complete' ) {
605
- newScript . onload = newScript . onreadystatechange = null ;
606
- if ( newScript . parentNode ) {
607
- newScript . parentNode . removeChild ( newScript ) ;
612
+ if ( isNodeSdk ( ) ) {
613
+ this . doNodeLongPoll ( url , loadCB ) ;
614
+ } else {
615
+ var self = this ;
616
+ setTimeout ( function ( ) {
617
+ try {
618
+ // if we're already closed, don't add this poll
619
+ if ( ! self . sendNewPolls ) return ;
620
+ var newScript = self . myIFrame . doc . createElement ( 'script' ) ;
621
+ newScript . type = 'text/javascript' ;
622
+ newScript . async = true ;
623
+ newScript . src = url ;
624
+ newScript . onload = newScript . onreadystatechange = function ( ) {
625
+ var rstate = newScript . readyState ;
626
+ if ( ! rstate || rstate === 'loaded' || rstate === 'complete' ) {
627
+ newScript . onload = newScript . onreadystatechange = null ;
628
+ if ( newScript . parentNode ) {
629
+ newScript . parentNode . removeChild ( newScript ) ;
630
+ }
631
+ loadCB ( ) ;
608
632
}
609
- loadCB ( ) ;
610
- }
611
- } ;
612
- newScript . onerror = function ( ) {
613
- log ( 'Long-poll script failed to load: ' + url ) ;
614
- self . sendNewPolls = false ;
615
- self . close ( ) ;
616
- } ;
617
- self . myIFrame . doc . body . appendChild ( newScript ) ;
618
- } catch ( e ) {
619
- // TODO: we should make this error visible somehow
620
- }
621
- } , Math . floor ( 1 ) ) ;
622
- } ;
633
+ } ;
634
+ newScript . onerror = function ( ) {
635
+ log ( 'Long-poll script failed to load: ' + url ) ;
636
+ self . sendNewPolls = false ;
637
+ self . close ( ) ;
638
+ } ;
639
+ self . myIFrame . doc . body . appendChild ( newScript ) ;
640
+ } catch ( e ) {
641
+ // TODO: we should make this error visible somehow
642
+ }
643
+ } , Math . floor ( 1 ) ) ;
644
+ }
645
+ } ;
646
+
647
+ if ( isNodeSdk ( ) ) {
648
+ /**
649
+ * @type {?function({url: string, forever: boolean}, function(Error, number, string)) }
650
+ */
651
+ ( FirebaseIFrameScriptHolder as any ) . request = null ;
652
+
653
+ /**
654
+ * @param {{url: string, forever: boolean} } req
655
+ * @param {function(string)= } onComplete
656
+ */
657
+ ( FirebaseIFrameScriptHolder as any ) . nodeRestRequest = function ( req , onComplete ) {
658
+ if ( ! ( FirebaseIFrameScriptHolder as any ) . request )
659
+ ( FirebaseIFrameScriptHolder as any ) . request =
660
+ /** @type {function({url: string, forever: boolean}, function(Error, number, string)) } */ ( require ( 'request' ) ) ;
661
+
662
+ ( FirebaseIFrameScriptHolder as any ) . request ( req , function ( error , response , body ) {
663
+ if ( error )
664
+ throw 'Rest request for ' + req . url + ' failed.' ;
665
+
666
+ if ( onComplete )
667
+ onComplete ( body ) ;
668
+ } ) ;
669
+ } ;
670
+
671
+ /**
672
+ * @param {!string } url
673
+ * @param {function() } loadCB
674
+ */
675
+ FirebaseIFrameScriptHolder . prototype . doNodeLongPoll = function ( url , loadCB ) {
676
+ var self = this ;
677
+ ( FirebaseIFrameScriptHolder as any ) . nodeRestRequest ( { url : url , forever : true } , function ( body ) {
678
+ self . evalBody ( body ) ;
679
+ loadCB ( ) ;
680
+ } ) ;
681
+ } ;
682
+
683
+ /**
684
+ * Evaluates the string contents of a jsonp response.
685
+ * @param {!string } body
686
+ */
687
+ FirebaseIFrameScriptHolder . prototype . evalBody = function ( body ) {
688
+ var jsonpCB ;
689
+ //jsonpCB is externed in firebase-extern.js
690
+ eval ( 'jsonpCB = function(' + FIREBASE_LONGPOLL_COMMAND_CB_NAME + ', ' + FIREBASE_LONGPOLL_DATA_CB_NAME + ') {' +
691
+ body +
692
+ '}' ) ;
693
+ jsonpCB ( this . commandCB , this . onMessageCB ) ;
694
+ } ;
695
+ }
0 commit comments