add websocketsec protocol as default for Brisk
[brisk.git] / web / xynt-streaming.js
1 // old targetpage == page and moved into start method
2
3 //
4 // CLASS transport_ws
5 //
6 function transport_ws(doc, xynt_streaming, page)
7 {
8     // if four arguments manage if WS or WSS connection
9     if (arguments.length > 3)
10         this.is_secure = arguments[3];
11     else
12         this.is_secure = false;
13
14     if (this.is_secure)
15         this.name = "WebSocketSecure";
16     else
17         this.name = "WebSocket";
18     this.ctx_new = "";
19     var self = this;
20
21     this.doc = doc;
22     this.failed = false;
23     this.xynt_streaming = xynt_streaming;
24     try {
25         this.xynt_streaming.log("PAGE: "+page);
26         this.ws = new WebSocket(page);
27         this.ws.onopen = function () {
28             self.xynt_streaming.log("onopen");
29             if (this.readyState == 1) {
30                 // connected
31                 self.ws_cb("open");
32                 self.init_steps = 1;
33             }
34         };
35         this.ws.onmessage = function (msg) {
36             self.xynt_streaming.log("onmessage");
37             // new data in msg.data
38             self.ctx_new += msg.data;
39         };
40         this.ws.onclose = function (msg) {
41             this.onopen  = null;
42             this.onclose = null;
43             this.onerror = null;
44             self.xynt_streaming.log("onclose"+self.init_steps);
45             if (self.init_steps == 0)
46                 self.ws_cb("error");
47             else
48                 self.ws_cb("close");
49         };
50         this.ws.onerror = function () {
51             // on error
52             this.onopen  = null;
53             this.onclose = null;
54             this.onerror = null;
55             self.xynt_streaming.log("onerror");
56             self.ws_cb("error");
57         };
58     }
59     catch (ex) {
60         throw "websocket creation failed";
61     }
62
63     this.stopped = false;
64 }
65
66 transport_ws.prototype = {
67     doc: null,
68     name: null,
69     xynt_streaming: "ready",
70     ws: null,
71     stopped: true,
72     failed: false,
73
74     init_steps: 0,
75
76     ctx_old: "",
77     ctx_old_len: 0,
78     ctx_new: "",
79
80     // script_clean: 0,
81
82     destroy: function () { /* public */
83         if (this.ws != null) {
84             this.ws_abort();
85         }
86         delete this.ws;
87     },
88
89     ws_cb: function (from) {
90         var ret;
91
92         if (from == "error") {
93             if (this.xynt_streaming != "ready") {
94                 if (this.xynt_streaming.transp_fback > 0) {
95 this.xynt_streaming.log("DEC: "+this.xynt_streaming.transp_fback);
96                     this.xynt_streaming.transp_fback--;
97                     this.stopped = true;
98                     this.xynt_streaming.reload();
99                 }
100             }
101         }
102         if (this.ws != null && this.ws.readyState > 1) {
103             this.stopped = true;
104         }
105     },
106
107     ws_abort: function() {
108         if (this.ws != null) {
109 this.xynt_streaming.log("WSCLOSE");
110             this.ws.close();
111         }
112     },
113
114     xstr_is_init: function () { /* public */
115         return (true);
116     },
117
118     /* only after a successfull is_initialized call */
119     xstr_is_ready: function () { /* public */
120         return (this.ws.readyState == 1);
121     },
122
123     xstr_set: function () { /* public */
124         // already set
125     },
126
127     ctx_new_is_set: function () { /* public */
128         return (this.ctx_new != null);
129     },
130
131     ctx_new_curlen_get: function () { /* public */
132         return (this.ctx_new.length);
133     },
134
135     ctx_new_getchar: function(idx) { /* public */
136         return (this.ctx_new[idx]);
137     },
138
139     ctx_old_len_is_set: function () { /* public */
140         return (true);
141     },
142
143     ctx_old_len_get: function () { /* public */
144         return (this.ctx_old_len);
145     },
146
147     ctx_old_len_set: function (len) { /* public */
148         this.ctx_old_len = len;
149     },
150
151     ctx_old_len_add: function (len) { /* public */
152         this.ctx_old_len += len;
153     },
154
155     new_part: function () { /* public */
156         return (this.ctx_new.substr(this.ctx_old_len));
157     },
158
159     scrcls_set: function (step) { /* public */
160         // this.script_clean = step;
161     },
162
163     postproc: function () {
164         if (this.stopped && !this.xstr_is_ready()) {
165             this.xynt_streaming.reload();
166         }
167     }
168 }
169
170 //
171 // CLASS transport_xhr
172 //
173 function transport_xhr(doc, xynt_streaming, page)
174 {
175     this.name = "XHR";
176     this.doc = doc;
177     this.xynt_streaming = xynt_streaming;
178     this.xhr = createXMLHttpRequest();
179     this.xhr.open('GET', page);
180
181     var self = this;
182     this.xhr.onreadystatechange = function () { self.xhr_cb(); };
183     this.xhr.send(null);
184
185     this.stopped = false;
186 }
187
188 transport_xhr.prototype = {
189     doc: null,
190     name: null,
191     xynt_streaming: "ready",
192     xhr: null,
193     stopped: true,
194
195     ctx_old: "",
196     ctx_old_len: 0,
197     ctx_new: null,
198
199     // script_clean: 0,
200
201     destroy: function () { /* public */
202         if (this.xhr != null) {
203             this.xhr_abort();
204         }
205         delete this.xhr;
206     },
207
208     xhr_cb: function () {
209         var ret;
210
211         if (this.xhr.readyState == 4) {
212             // console.log("SS: "+safestatus(xhr));
213
214             // NOTE: delay management later
215             // try {
216             //     if ((ret = safestatus(this.xhr)) == 200) {
217             //         this.delay = 0;
218             //         // console.log("del a null "+this.delayed);
219             //     } else if (ret != -1) {
220             //         this.delay = 5000;
221             //         this.hbit('X');
222             //         // alert('There was a problem with the request.' + ret);
223             //     }
224             // } catch(b) {};
225
226             // this.delayed = null;
227             this.stopped = true;
228         }
229     },
230
231     xhr_abort: function() {
232         if (this.xhr != null) {
233             this.xhr.abort();
234         }
235     },
236
237     xstr_is_init: function () { /* public */
238         try {
239             if (this.xhr.responseText != null) {
240                 this.ctx_new = this.xhr.responseText;
241             }
242         }
243         catch (e) {
244         }
245
246         return (this.ctx_new != null);
247     },
248
249     /* only after a successfull is_initialized call */
250     xstr_is_ready: function () { /* public */
251         return (this.xynt_streaming == "ready");
252     },
253
254     xstr_set: function () { /* public */
255         // already set
256     },
257
258     ctx_new_is_set: function () { /* public */
259         return (this.ctx_new != null);
260     },
261
262     ctx_new_curlen_get: function () { /* public */
263         return (this.ctx_new.length);
264     },
265
266     ctx_new_getchar: function(idx) { /* public */
267         return (this.ctx_new[idx]);
268     },
269
270     ctx_old_len_is_set: function () { /* public */
271         return (true);
272     },
273
274     ctx_old_len_get: function () { /* public */
275         return (this.ctx_old_len);
276     },
277
278     ctx_old_len_set: function (len) { /* public */
279         this.ctx_old_len = len;
280     },
281
282     ctx_old_len_add: function (len) { /* public */
283         this.ctx_old_len += len;
284     },
285
286     new_part: function () { /* public */
287         return (this.ctx_new.substr(this.ctx_old_len));
288     },
289
290     scrcls_set: function (step) { /* public */
291         // this.script_clean = step;
292     },
293
294     postproc: function () {
295         if (this.stopped && !this.xstr_is_ready()) {
296             this.xynt_streaming.reload();
297         }
298     }
299 }
300
301 //
302 // CLASS transport_htmlfile
303 //
304 function transport_htmlfile(doc, xynt_streaming, page)
305 {
306     this.name = "HTMLFile";
307     this.doc = doc;
308     this.xynt_streaming = xynt_streaming;
309     this.transfdoc = new ActiveXObject("htmlfile");
310     this.transfdoc.open();
311     this.transfdoc.write("<html><body><iframe id='iframe'></iframe></body></html>");
312     this.transfdoc.close();
313
314     this.ifra = this.transfdoc.getElementById("iframe");
315     this.ifra.contentWindow.location.href = page;
316     this.stopped = false;
317 }
318
319 transport_htmlfile.prototype = {
320     doc: null,
321     name: null,
322     xynt_streaming: null,
323     stopped: true,
324     ifra: null,
325     tradoc: null,
326
327     destroy: function () { /* public */
328         if (this.ifra != null) {
329         //     this.doc.body.removeChild(this.ifra);
330         //     delete this.ifra;
331              this.ifra = null;
332         }
333
334         if (this.transfdoc) {
335             delete this.transfdoc;
336             this.transfdoc = null;
337         }
338     },
339
340     xstr_is_init: function () { /* public */
341         return (typeof(this.ifra.contentWindow.xynt_streaming) != 'undefined');
342     },
343
344     /* only after a successfull is_initialized call */
345     xstr_is_ready: function () { /* public */
346         return (this.ifra.contentWindow.xynt_streaming == "ready");
347     },
348
349     /* only after a successfull is_initialized call */
350     xstr_set: function () { /* public */
351         if (this.ifra.contentWindow.xynt_streaming == "ready") {
352             this.ifra.contentWindow.xynt_streaming = this.xynt_streaming;
353             return (true);
354         }
355         else if (this.ifra.contentWindow.xynt_streaming == this.xynt_streaming) {
356             return (true);
357         }
358         else {
359             return (false);
360         }
361     },
362
363     ctx_new_is_set: function () { /* public */
364         return (typeof(this.ifra.contentWindow.ctx_new) != 'undefined');
365     },
366
367     ctx_new_curlen_get: function () { /* public */
368         return (this.ifra.contentWindow.ctx_new.length);
369     },
370
371     ctx_new_getchar: function(idx) { /* public */
372         return (this.ifra.contentWindow.ctx_new.charAt(idx));
373     },
374
375     ctx_old_len_is_set: function () { /* public */
376         return (typeof(this.ifra.contentWindow.ctx_old_len) != 'undefined');
377     },
378
379     ctx_old_len_get: function () { /* public */
380         return (this.ifra.contentWindow.ctx_old_len);
381     },
382
383     ctx_old_len_set: function (len) { /* public */
384         this.ifra.contentWindow.ctx_old_len = len;
385     },
386
387     ctx_old_len_add: function (len) { /* public */
388         this.ifra.contentWindow.ctx_old_len += len;
389     },
390
391     new_part: function () { /* public */
392         return (this.ifra.contentWindow.ctx_new.substr(this.ifra.contentWindow.ctx_old_len));
393     },
394
395     scrcls_set: function (step) { /* public */
396         this.ifra.contentWindow.script_clean = step;
397     },
398
399     postproc: function () { /* public */
400         if (this.stopped && !this.xstr_is_ready()) {
401             this.xynt_streaming.reload();
402         }
403     }
404 }
405
406 //
407 // CLASS transport_iframe
408 //
409 function transport_iframe(doc, xynt_streaming, page)
410 {
411     this.name = "IFRAME";
412     this.doc = doc;
413     this.xynt_streaming = xynt_streaming;
414     this.ifra = doc.createElement("iframe");
415     this.ifra.style.visibility = "hidden";
416     doc.body.appendChild(this.ifra);
417     this.ifra.contentWindow.location.href = page;
418     this.stopped = false;
419 }
420
421 transport_iframe.prototype = {
422     doc: null,
423     name: null,
424     xynt_streaming: null,
425     stopped: true,
426     ifra: null,
427
428     destroy: function () { /* public */
429         try {
430             if (this.ifra != null) {
431                 // NOTE:  on Opera this remove child crash js if called from
432                 //        inside of the iframe, on IE on Windows without
433                 //        it stream abort fails.
434                 //        the problem is fixed setting into the iframe's onload
435                 //        function the stopped attribute to true and delegate
436                 //        postproc() fired by xynt_streaming watchdog()
437                 this.doc.body.removeChild(this.ifra);
438                 delete this.ifra;
439                 this.ifra = null;
440             }
441         } catch (b) {
442             alert("destroy exception catched");
443         }
444     },
445
446     xstr_is_init: function () { /* public */
447         return (typeof(this.ifra.contentWindow.xynt_streaming) != 'undefined');
448     },
449
450     /* only after a successfull is_initialized call */
451     xstr_is_ready: function () { /* public */
452         return (this.ifra.contentWindow.xynt_streaming == "ready");
453     },
454
455     /* only after a successfull is_initialized call */
456     xstr_set: function () { /* public */
457         if (this.ifra.contentWindow.xynt_streaming == "ready") {
458             this.ifra.contentWindow.xynt_streaming = this.xynt_streaming;
459             return (true);
460         }
461         else if (this.ifra.contentWindow.xynt_streaming == this.xynt_streaming) {
462             return (true);
463         }
464         else {
465             return (false);
466         }
467     },
468
469
470     /* only after a successfull is_ready call to be sure the accessibility of the var */
471     xstr_set_old: function (xynt_streaming) { /* public */
472         this.ifra.contentWindow.xynt_streaming = xynt_streaming;
473     },
474
475     ctx_new_is_set: function () { /* public */
476         return (typeof(this.ifra.contentWindow.ctx_new) != 'undefined');
477     },
478
479     ctx_new_curlen_get: function () { /* public */
480         return (this.ifra.contentWindow.ctx_new.length);
481     },
482
483     ctx_new_getchar: function(idx) { /* public */
484         return (this.ifra.contentWindow.ctx_new.charAt(idx));
485     },
486
487     ctx_old_len_is_set: function () { /* public */
488         return (typeof(this.ifra.contentWindow.ctx_old_len) != 'undefined');
489     },
490
491     ctx_old_len_get: function () { /* public */
492         return (this.ifra.contentWindow.ctx_old_len);
493     },
494
495     ctx_old_len_set: function (len) { /* public */
496         this.ifra.contentWindow.ctx_old_len = len;
497     },
498
499     ctx_old_len_add: function (len) { /* public */
500         this.ifra.contentWindow.ctx_old_len += len;
501     },
502
503     new_part: function () { /* public */
504         return (this.ifra.contentWindow.ctx_new.substr(this.ifra.contentWindow.ctx_old_len));
505     },
506
507     scrcls_set: function (step) { /* public */
508         this.ifra.contentWindow.script_clean = step;
509     },
510
511     postproc: function () { /* public */
512         if (this.stopped && !this.xstr_is_ready()) {
513             this.xynt_streaming.reload();
514         }
515     }
516 }
517
518 function xynt_streaming(win, transp_type, transp_port, transp_fback, console, gst, from, cookiename, sess, sandbox, page, cmdproc)
519 {
520     this.win = win;
521     this.transp_type = transp_type;
522     this.transp_port = transp_port;
523     this.transp_fback = transp_fback;
524     this.console = console;
525     this.gst = gst;
526     this.from = from;
527     this.cookiename = cookiename;
528     this.sess = sess;
529     this.sandbox = sandbox;
530     this.page = page;
531     this.cmdproc = cmdproc;
532     // this.cmdproc = function(com){/* console.log("COM: "+com); */ eval(com);}
533     this.doc = win.document;
534     this.keepalive_old = -1;
535     this.keepalive_new = -1;
536
537     this.mon_errtime = this.keepalives_eq_max * this.watchdog_checktm * this.watchdog_timeout;
538     this.mon_wrntime = this.mon_errtime / 2;
539
540     this.mon_update();
541 }
542
543 xynt_streaming.prototype = {
544     win:               null,
545     transp_type:       null,
546     transp_port:         80,
547     transp_fback:         0,
548     transp:            null,
549     console:           null,
550     gst:               null,
551     from:              null,
552     cookiename:        null,
553     sess:              null,
554     sandbox:           null,
555     page:              null,
556     cmdproc:           null,
557
558     start_time:        0,
559     restart_wait:      5000, // wait restart_wait millisec before begin to check if restart is needed
560
561     doc:               null,
562     cookiepath: "/brisk/",
563     watchdog_hdl:      null,
564     hbit:              function () {},
565     keepalive_old:    -1,
566     keepalive_new:    -1,
567     keepalives_equal:  0,
568     /* NOTE: right watch_timeout value to 100, for devel reasons use 1000 or more */
569     /* restart after  4 * 40 * 100 millisec if server ping is missing => 16secs */
570     keepalives_eq_max: 4,
571     watchdog_checktm:  40,
572     watchdog_timeout:  100,
573     watchdog_ct:       0,
574     watchable:         false,
575     restart_n:         0,
576     comm_match:        /_*@BEGIN@(.*?)@END@/g,
577     comm_clean:        /_*@BEGIN@(.*?)@END@/,
578     stream:            "",
579     the_end:           false,
580
581     mon_time:         -1,
582     mon_wrntime:       0,
583     mon_errtime:       0,
584
585     mon_stat_old:      "",
586
587     mon_update: function()
588     {
589         var date = new Date();
590
591         this.mon_time = date.getTime();
592     },
593
594     /*
595       ping arrives at least every RD_KEEPALIVE_TOUT secs (currently 4 secs)
596
597       return values: 0 unknown
598                      1 ok
599                      2 warning
600                      3 error
601      */
602     mon_status: function()
603     {
604         var delta, date;
605
606         var date = new Date();
607
608         delta = date.getTime() - this.mon_time;
609
610         if (delta < this.mon_wrntime)
611             return 1;
612         else if (delta < this.mon_errtime)
613             return 2;
614         else
615             return 3;
616     },
617
618     start: function() { /* public */
619         var transp_type;
620         var page;
621
622         // this.log("start "+this.transp_type+" "+this.transp_fback);
623         if (this.the_end)
624             return;
625
626         createCookie(this.cookiename, sess, 24*365, this.cookiepath);
627         // alert("start");
628         this.log("xynt_streaming:start restart: "+this.restart_n);
629         this.keepalives_equal = 0;
630
631         // page arrangement
632         this.page = url_complete(this.win.location.href, this.page);
633
634         // DEFAULT TRANSPORT PROTOCOL HERE websocketsec, websocket
635         if (this.transp_fback > 0) {
636             transp_type = "websocketsec";
637             transp_port = (this.transp_fback == 2 ? 80 : 8080);
638         }
639         else {
640             transp_type = this.transp_type;
641             transp_port = this.transp_port;
642         }
643
644         if (transp_type == "websocket" || transp_type == "websocketsec") {
645             var end_proto, first_slash, newpage;
646
647             // change protocol
648             this.log("precha ["+this.page+"]");
649             if (transp_type == "websocketsec") {
650                 newpage = this.page.replace(/\.php$/g, "_wss.php").replace(/\.php\?/g, "_wss.php?");
651                 }
652             else {
653                 newpage = this.page;
654                 }
655             end_proto = newpage.indexOf("://");
656             first_slash = newpage.substring(end_proto+3).indexOf("/");
657
658             page = (transp_type == "websocketsec" ? "wss://" : "ws://")
659                 + newpage.substring(end_proto+3, end_proto+3 + first_slash) + ":"
660                 + transp_port + newpage.substring(end_proto+3 + first_slash);
661             // this.log("MOP WS: " + page);
662         }
663         else {
664             page = this.page;
665         }
666         // stat, subst, this.gst.st
667
668         page = url_append_args(page, "sess", this.sess, "stat", stat, "subst", subst, "step", this.gst.st, "from", this.from);
669         // this.log("the page:");
670         // this.log(page);
671
672         try {
673             // transport instantiation
674             if (transp_type == "websocketsec") {
675                 page = url_append_args(page, "transp", "websocketsec");
676                 this.transp = new transport_ws(this.doc, this, page, true);
677             }
678             else if (transp_type == "websocket") {
679                 page = url_append_args(page, "transp", "websocket");
680                 this.transp = new transport_ws(this.doc, this, page);
681             }
682             else if (transp_type == "xhr") {
683                 page = url_append_args(page, "transp", "xhr");
684                 this.transp = new transport_xhr(this.doc, this, page);
685             }
686             else if (transp_type == "iframe") {
687                 page = url_append_args(page, "transp", "iframe");
688                 this.transp = new transport_iframe(this.doc, this, page);
689             }
690             else if (transp_type == "htmlfile") {
691                 page = url_append_args(page, "transp", "htmlfile");
692                 this.transp = new transport_htmlfile(this.doc, this, page);
693             }
694             else
695                 return;
696         }
697         catch (err) {
698             if (this.transp_fback > 0) {
699                 this.transp_fback--;
700                 this.start();
701                 return;
702             }
703         }
704
705         // watchdog setting
706         this.watchdog_ct  = 0;
707         if (!this.the_end) {
708             this.watchdog_hdl = setTimeout(function(obj) { obj.log("tout1"); obj.watchdog(); }, this.watchdog_timeout, this);
709         }
710
711         var date = new Date();
712         this.start_time = date.getTime();
713     },
714
715     stop: function() {
716         this.the_end = true;
717         this.abort();
718     },
719
720     hbit_set: function (hbit) {
721         this.hbit = hbit;
722     },
723
724
725     hbit_status: function () {
726         var ret;
727
728         ret = this.mon_status();
729         // console.log("mon_status: "+ret+" 0: "+this.mon_time);
730         switch (ret) {
731         case 0:
732             mon_stat = "b";
733             break;
734         case 1:
735             mon_stat = "g";
736             break;
737         case 2:
738             mon_stat = "y";
739             break;
740         case 3:
741             mon_stat = "r";
742             break;
743         }
744
745         if (this.mon_stat_old != mon_stat) {
746             this.hbit(mon_stat);
747             this.mon_stat_old = mon_stat;
748         }
749     },
750
751
752     watchdog: function () {
753         // alert("watchdog");
754         var i, again;
755         var comm_newpart, comm_len, comm_arr;
756         var ctx_new_len;
757
758         if (this.sandbox != null) {
759             var zug = "WATCHDOG  sess = ["+this.sess+"]  step = "+this.gst.st+" step_loc = "+this.gst.st_loc+" step_loc_new = "+this.gst.st_loc_new+"Transport: "+this.transp.name;
760             if (zug != this.sandbox.innerHTML)
761                 this.sandbox.innerHTML = zug;
762         }
763
764         // WATCHDOGING THE CONNECTION
765         this.log("hs::watchdog: start, cur equal times: "+this.keepalives_equal);
766         if (!this.watchable) {
767             do {
768                 try{
769                     // if (typeof(this.ifra.contentWindow.xynt_streaming) == 'undefined')
770                     if (!this.transp.xstr_is_init()) {
771                         this.log("hs::watchdog: xstr_is_init = false");
772                         break;
773                     }
774                 }
775                 catch(b) {
776                     this.log("hs::watchdog: exception");
777                     break;
778                 }
779
780                 /*
781                   on IE7 the the window frame scope is cleaned after the href is set, so we wait
782                   for a well know variable value before assign this object value to it (OO is a passion)
783                 */
784                 // if (this.ifra.contentWindow.xynt_streaming == "ready") {
785                 if (this.transp.xstr_set()) {
786                     // this.ifra.contentWindow.xynt_streaming = this;
787                     this.watchable = true;
788                     this.watchdog_ct = 0;
789                     this.log("hs::watchdog: watchable = yes");
790                 }
791             } while (false);
792         }
793         if ( (this.watchdog_ct % this.watchdog_checktm) == 0) {
794             this.log("hs::watchdog: this.keepalive_old: "+this.keepalive_old+" this.keepalive_new: "+this.keepalive_new);
795             if (this.keepalive_old == this.keepalive_new) {
796                 this.keepalives_equal++;
797             }
798             else {
799                 this.keepalive_old = this.keepalive_new;
800                 this.keepalives_equal = 0;
801             }
802
803             if (this.keepalives_equal >= this.keepalives_eq_max) {
804                 this.log("hs::watchdog: MAX ACHIEVED "+this.keepalives_equal);
805                 this.reload();
806                 // alert("watchdog return reload");
807                 this.hbit_status();
808                 return;
809             }
810         }
811
812         // PICK COMMANDS FROM STREAM
813         do {
814             // alert("do--while begin ["+again+"]");
815             // CHECK: maybe again here isn't needed
816             again = 0;
817             try {
818                 /* if (typeof(this.ifra.contentWindow.ctx_new)     == 'undefined' ||
819                    typeof(this.ifra.contentWindow.ctx_old_len) == 'undefined') */
820                 if (!this.transp.ctx_new_is_set() || !this.transp.ctx_old_len_is_set())
821                     break;
822             }
823             catch(b) {
824                 break;
825             }
826
827             // ctx_new_len = this.ifra.contentWindow.ctx_new.length;
828             ctx_new_len = this.transp.ctx_new_curlen_get();
829             // if (ctx_new_len <= this.ifra.contentWindow.ctx_old_len) {
830             if (ctx_new_len <= this.transp.ctx_old_len_get()) {
831                 break;
832             }
833             this.log("new: "+ ctx_new_len + "  old: "+this.transp.ctx_old_len_get());
834             this.keepalive_new++;
835             // alert("pre-loop 1");
836             for (i = this.transp.ctx_old_len_get() ; i < ctx_new_len ; i++) {
837                 // if (this.ifra.contentWindow.ctx_new.charAt(i) != '_') {
838                 if (this.transp.ctx_new_getchar(i) != '_') {
839                     // this.log("ctx_new.char(i) != '_' ["+this.ifra.contentWindow.ctx_new.charAt(i)+"]");
840                     break;
841                 }
842                 this.mon_update();
843                 this.hbit_status();
844
845                 // else {
846                 //     this.log("ctx_new.charAt(i) == '_'");
847                 // }
848             }
849             // this.ifra.contentWindow.ctx_old_len = i;
850             this.transp.ctx_old_len_set(i);
851             if (i == ctx_new_len) {
852                 this.log("old_len == i");
853                 break;
854             }
855             else {
856                 this.log("old_len != i: "+i);
857             }
858             // alert("do--while middle ["+this.ifra.contentWindow.ctx_old_len+"]");
859
860             comm_newpart = this.transp.new_part();
861             this.log("COM_NEWPART: ["+comm_newpart+"]");
862             comm_len = 0;
863             comm_arr = comm_newpart.match(this.comm_match);
864
865             // alert("do--while middle2 ["+again+"]");
866             if (comm_arr) {
867                 var comm_arr_len = comm_arr.length;
868                 for (i = 0 ; i < comm_arr_len ; i++) {
869                     var temp = comm_arr[i].replace(this.comm_clean,"$1").split("|");
870                     this.gst.comms = this.gst.comms.concat(temp);
871                     comm_len += comm_arr[i].length;
872                 }
873                 again = 1;
874                 this.mon_update();
875                 this.hbit_status();
876             }
877             // this.ifra.contentWindow.ctx_old_len += comm_len;
878             this.transp.ctx_old_len_add(comm_len);
879             // this.ifra.contentWindow.script_clean = this.gst.st;
880             this.transp.scrcls_set(this.gst.st);
881             // alert("do--while end ["+again+"]");
882         } while (again);
883
884         // alert("post while");
885         // EXECUTION OF STREAM COMMANDS
886         do {
887             again = 0;
888             //MOP ?? xhrrestart = 0;
889             if (this.gst.st_loc < this.gst.st_loc_new) {
890                 // there is some slow actions running
891                 break;
892             }
893             else if (this.gst.comms.length > 0) {
894                 var singlecomm;
895
896                 singlecomm = this.gst.comms.shift();
897                 // alert("EXE"+gugu);
898                 // $("xhrdeltalog").innerHTML = "EVALL: "+singlecomm.replace("<", "&lt;", "g"); +"<br>";
899                 //xx this.hbit("+");
900
901                 // alert("SINGLE: ["+singlecomm+"]");
902                 // window.console.log("["+singlecomm+"]");
903                 this.cmdproc(singlecomm);
904                 again = 1;
905             }
906         } while (again);
907         this.watchdog_ct++;
908         if (!this.the_end) {
909             var date = new Date();
910             if (date.getTime() > (this.start_time + this.restart_wait)) {
911                 this.transp.postproc();
912             }
913             this.watchdog_hdl = setTimeout(function(obj) { /* obj.log("tout2"); */ obj.watchdog(); }, this.watchdog_timeout, this);
914             this.hbit_status();
915         }
916         // alert("watchdog return normal");
917
918         return;
919     },
920
921     //
922     // moved to xynt-streaming-ifra as push()
923     //
924     // keepalive: function (s) {
925     //     this.log("hs::keepalive");
926     //     if (s != null) {
927     //         this.log(s);
928     //         this.ifra.contentWindow.ctx_new += "@BEGIN@"+s+"@END@";
929     //     }
930     //     else {
931     //         this.ifra.contentWindow.ctx_new += "_";
932     //     }
933     //     // this.keepalive_new++;
934     // },
935
936     abort: function () { /* public */
937         // this.log("PATH: "+this.ifra.contentWindow.location.protocol + "://" + this.ifra.contentWindow.location.host + "/" + this.ifra.contentWindow.location.pathname);
938
939         this.gst.abort();
940         if (this.watchdog_hdl != null) {
941             clearTimeout(this.watchdog_hdl);
942             this.watchdog_hdl = null;
943         }
944
945         this.restart_n++;
946         this.log("hs::reload");
947         this.watchable = false;
948         if (this.transp != null) {
949             this.transp.destroy();
950             delete this.transp;
951             this.transp = null;
952         }
953     },
954
955     reload: function () {
956         this.abort();
957         this.start(null);
958     },
959
960     log: function (s) {
961         if (this.console != null) {
962             return (this.console.log(s));
963         }
964     }
965 }