pass by reference fixed [3]
[brisk.git] / web / http_streaming.js
1 /*
2  *  brisk - http_streaming.js
3  *
4  *  Copyright (C) 2006-2012 Matteo Nastasi
5  *                          mailto: nastasi@alternativeoutput.it 
6  *                                  matteo.nastasi@milug.org
7  *                          web: http://www.alternativeoutput.it
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * General Public License for more details. You should have received a
18  * copy of the GNU General Public License along with this program; if
19  * not, write to the Free Software Foundation, Inc, 59 Temple Place -
20  * Suite 330, Boston, MA 02111-1307, USA.
21  *
22  * TODO:
23  *
24  *   MANDATORY
25  *
26  *   NOT MANDATORY
27  *   - type of streaming into the constructor
28  *   - all iframe related streaming add
29  *
30  *   DONE - substitute fixed "eval" with a generic command hunks processor
31  *   DONE - myfrom (now from) into the constructor
32  *   DONE - target page into the constructor
33  *   DONE - gst management
34  *   DONE - xhr_rd prefix remove from inner class attrs
35  *   DONE - move hbit implementation to external file
36  *   DONE - sandbox management
37  *
38  */
39
40 function http_streaming(gst, from, cookiename, sandbox, targetpage, cmdproc)
41 {
42     this.xhr = createXMLHttpRequest();
43     // this.xhr.setRequestHeader("Content-type", "text/html; charset=utf-8");
44
45     this.gst = gst;
46     this.from = from;
47     this.cookiename = cookiename;
48     this.sandbox = sandbox;
49     this.targetpage = targetpage;
50     this.cmdproc = cmdproc;
51 }
52
53 http_streaming.prototype = {
54     gst: null,
55     from: null,
56     cookiename: null,
57     sandbox: null,
58     targetpage: null,
59     cmdproc: null,
60
61     /* cookiepath is automatically customized in installation phase */
62     cookiepath: "/brisk/",
63     xhr: null,
64     watchdog: null,
65     delay: 0,
66     delayed: null,
67     stopped: true,
68     the_end: false,
69     oldctx: "",
70     newctx: "",
71     cur_n: -1,
72     old_n: -1,
73     checkedlen: 0,
74     /* watchdog_old: 0, */
75     ct: 0,
76
77     hbit: function () {
78     },
79
80     hbit_set: function (hbit) {
81         this.hbit = hbit;
82     },
83
84     xhr_cb: function () {
85         var ret;
86         
87         if (this.xhr.readyState == 4) {
88             if (this.watchdog != null) {
89                 this.hbit('C');
90                 clearTimeout(this.watchdog);
91                 this.watchdog = null;
92             }
93             
94             // console.log("SS: "+safestatus(xhr));
95             
96             try {
97                 if ((ret = safestatus(this.xhr)) == 200) {
98                     this.delay = 0;
99                     // console.log("del a null "+this.delayed);
100                 } else if (ret != -1) {
101                     this.delay = 5000;
102                     this.hbit('X');
103                     // alert('There was a problem with the request.' + ret);
104                 }
105             } catch(b) {};
106             
107             this.delayed = null;
108             this.stopped = true;
109         }
110     },
111
112     xhr_abort: function()
113     {
114         this.hbit('A');
115         if (this.xhr != null)
116             this.xhr.abort();
117         // alert("de che");
118     },
119
120     run: function(sess, stat, subst, step) 
121     {
122         if (this.the_end) {
123             //x alert("the_end1");
124             if (this.watchdog != null) {
125                 this.hbit('C');
126                 clearTimeout(this.watchdog);
127                 this.watchdog = null;
128             }
129             return;
130         }
131         createCookie(this.cookiename, sess, 24*365, this.cookiepath);
132         
133         // NOTE: *ctx = "" to prevent konqueror stream commands duplication.
134         this.oldctx = "";
135         this.newctx = "";
136         
137         /* NOTE document.uniqueID exists only under IE  */
138         // if (g_is_spawn == 1)
139         // alert("di qui3: "+(g_is_spawn == 1 ? "&table_idx="+g_table_idx : ""));
140         this.xhr.open('GET', this.targetpage+'?'+this.cookie_name+'='+sess+"&stat="+stat+"&subst="+subst+"&step="+step+"&onlyone="+(document.uniqueID ? "TRUE" : "FALSE")+"&from="+this.from, true);
141         //    try { 
142
143         var self = this;
144         this.xhr.onreadystatechange = function () { self.xhr_cb(); };
145         this.xhr.send(null);
146         // 
147         // TODO: qui avvio del timer per riavviare xhr
148         // 
149         this.watchdog = setTimeout(function(obj){ obj.xhr_abort(); }, 60000, this);
150         this.cur_n++;
151         this.stopped = false;
152         // } catch (e) {}
153     },
154     
155     /* WORK HERE TO RUN WIN OR LIN STREAM */
156     
157     start: function(sess)
158     {
159         this.poll(sess);
160     },
161
162     stop: function()
163     {
164         this.the_end = true;
165     },
166
167     poll: function(sess)
168     {
169         var tout = 100;
170         var again;
171         var xhrrestart;
172         
173         this.ct++;
174         
175         /*
176           if (this.watchdog_old >= 50) {
177           this.watchdog_old = 0;
178           // alert("ABORT XHR");
179           this.stopped = true;
180           this.xhr.abort();     
181           }
182         */
183         if (this.sandbox != null) {
184             var zug = "POLL sess = "+sess+" stat = "+stat+" subst = "+subst+" step = "+this.gst.st+" step_loc = "+this.gst.st_loc+" step_loc_new = "+this.gst.st_loc_new+" STOP: "+this.stopped;
185             
186             if (zug != this.sandbox.innerHTML)
187                 this.sandbox.innerHTML = zug;
188         }
189         /* heartbit log */
190         this.hbit("_");
191         do {
192             again = 0;
193             xhrrestart = 0;
194             if (this.gst.st_loc < this.gst.st_loc_new) {
195                 // there is some slow actions running
196                 break;
197             }
198             else if (this.gst.comms.length > 0) {
199                 var singlecomm;
200                 
201                 singlecomm = this.gst.comms.shift();
202                 // alert("EXE"+gugu);
203                 // $("xhrdeltalog").innerHTML = "EVALL: "+singlecomm.replace("<", "&lt;", "g"); +"<br>";
204                 this.hbit("+");
205                 
206                 this.cmdproc(singlecomm);
207                 again = 1;
208             }
209             else {
210                 xhrrestart = 1;
211                 try { 
212                     if (this.xhr == null)
213                         throw "restart";
214                     if (this.xhr.responseText != null)
215                         this.newctx = this.xhr.responseText;
216                 }
217                 catch (e) {
218                     if (this.stopped == true) {
219                         this.stopped = false;
220                         // XX $("xhrstart").innerHTML += "XHRSTART: da catch<br>";
221                         if (this.delay > 0) {
222                             if (this.delayed == null) {
223                                 // console.log("XXX DI QUI "+this.delay);
224
225                                 this.delayed = setTimeout(
226                                     function(f_obj, f_sess, f_stat, f_subst, f_step){ f_obj.run(f_sess, f_stat, f_subst, f_step); },
227                                     this.delay, this, sess, stat, subst, this.gst.st);
228                                 // console.log("XXX DI QUI post"+this.delayed);
229                             }
230                         }
231                         else {
232                             // console.log("yyy DI QUI "+this.delay);
233                             this.run(sess, stat, subst, this.gst.st);
234                         }
235                     }
236                     
237                     
238                     // $("sandbox").innerHTML += "return 1<br>";
239                     if (this.the_end != true) {
240                         /* this.watchdog_old = 0; */
241                         setTimeout(function(obj, sess){ obj.poll(sess); }, tout, this, sess);
242                         
243                         // this.hbit(".");
244                         
245                     }
246                     else {
247                         //x alert("the_end2");
248                         if (this.watchdog != null) {
249                             clearTimeout(this.watchdog);
250                             this.watchdog = null;
251                         }
252                     }    
253                     return;
254                 }
255                 
256                 
257                 // no new char from the last loop, break
258                 if (this.old_n == this.cur_n && 
259                     this.newctx.length == this.checkedlen) {
260                     /* this.watchdog++; */
261                     break;
262                 }
263                 else {
264                     // $("sandbox").innerHTML += "BIG IF<br>";
265                     var comm_match;
266                     var comm_clean;
267                     var comm_len;
268                     var comm_newpart;
269                     var comm_arr;
270                     var i;
271                     var delta = 0;
272                     var match_lines = /^_*$/;
273                     
274                     /* this.watchdog = 0; */
275                     this.hbit("/\\");
276                     
277                     // check for the same command group
278                     if (this.old_n != this.cur_n) {
279                         this.old_n = this.cur_n;
280                         this.checkedlen = 0;
281                         this.oldctx = "";
282                     }
283                     else
284                         delta = this.oldctx.length;
285                     
286                     // $("xhrlog").innerHTML += "EVERY SEC<br>";                
287                     for (i = delta ; i < this.newctx.length ; i++) {
288                         if (this.newctx[i] != '_') 
289                             break;
290                     }
291                     if (i == this.newctx.length) {
292                         this.checkedlen = i;
293                         break;
294                     }
295                     
296                     // $("xhrlog").innerHTML += "CHECK COM<br>";                
297                     // extracts the new part of the command string
298                     comm_newpart = this.newctx.substr(delta);
299                     
300                     // XX $("xhrlog").innerHTML = newctx.replace("<", "&lt;", "g");
301                     
302                     // $("response").innerHTML = comm_newpart;
303                     comm_match = /_*@BEGIN@(.*?)@END@/g;
304                     comm_clean = /_*@BEGIN@(.*?)@END@/;
305                     comm_len = 0;
306                     comm_arr = comm_newpart.match(comm_match);
307                     
308                     // $("sandbox").innerHTML += "PRE COMMARR<br>";
309                     if (comm_arr) {
310                         // XX $("xhrdeltalog").innerHTML += "DELTA: "+delta +"<br>";
311                         // XX alert("newctx: "+this.newctx);
312                         // $("sandbox").innerHTML += "POST COMMARR<br>";
313                         for (i = 0 ; i < comm_arr.length ; i++) {
314                             var temp = comm_arr[i].replace(comm_clean,"$1").split("|");
315                             this.gst.comms = this.gst.comms.concat(temp);
316                             // XX alert("COMM_ARR["+i+"]: "+comm_arr[i]+"  LEN:"+comm_arr[i].length);
317                             comm_len += comm_arr[i].length;
318                         }
319                         tout = 0;
320                         this.oldctx += comm_newpart.substr(0,comm_len);
321                         // XX alert("OLDCTX: "+this.oldctx);
322                         again = 1;
323                     }
324                     this.checkedlen = this.oldctx.length;
325                 }
326             }
327         } while (again);
328
329         if (xhrrestart == 1 && this.stopped == true) {
330             // $("sandbox").innerHTML += "LITTLE IF<br>";
331             // alert("di qui");
332             // XX $("xhrstart").innerHTML += "XHRSTART: da end poll<br>";
333             if (this.delay > 0) {
334                 if (this.delayed == null) {
335                     // console.log("XXX DI QUO "+this.delay);
336                     
337                     this.delayed = setTimeout(
338                         function(obj, sess, stat, subst, step){ obj.run(sess, stat, subst, step); },
339                         this.delay, this, sess, stat, subst, this.gst.st);
340                     // console.log("XXX DI QUO post"+this.delayed);
341                 }
342             }
343             else {
344                 // console.log("yyy DI QUO "+this.delay);
345                 this.run(sess, stat, subst, this.gst.st);
346             }
347             
348         }
349         
350         if (this.the_end != true) {
351             setTimeout(function(obj, sess){ obj.poll(sess); }, tout, this, sess);
352         }
353         else {
354             //x alert("the_end3");
355             if (this.watchdog != null) {
356                 clearTimeout(this.watchdog);
357                 this.watchdog = null;
358             }
359         }
360         return;
361     }
362 }
363     
364 /*
365   window.onload = function () {
366   xhr = createXMLHttpRequest();
367
368   sess = $("user").value;
369   window.setTimeout(poll, 0, sess);
370   };
371 */