802981272534637f5d44fa9855f110bd04c5fb42
[brisk.git] / web / http_streaming.js
1 /*
2  *  brisk - http_streaming.js
3  *
4  *  Copyright (C) 2006-2011 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  *   - substitute fixed "eval" with a generic command hunks processor
30  *
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)
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 }
51
52 http_streaming.prototype = {
53     gst: null,
54     from: null,
55     cookiename: null,
56     sandbox: null,
57     targetpage: null,
58
59     /* cookiepath is automatically customized in installation phase */
60     cookiepath: "/brisk/",
61     xhr: null,
62     watchdog: null,
63     delay: 0,
64     delayed: null,
65     stopped: true,
66     the_end: false,
67     oldctx: "",
68     newctx: "",
69     cur_n: -1,
70     old_n: -1,
71     checkedlen: 0,
72     /* watchdog_old: 0, */
73     ct: 0,
74
75     hbit: function () {
76     },
77
78     hbit_set: function (hbit) {
79         this.hbit = hbit;
80     },
81
82     xhr_cb: function () {
83         var ret;
84         
85         if (this.xhr.readyState == 4) {
86             if (this.watchdog != null) {
87                 this.hbit('C');
88                 clearTimeout(this.watchdog);
89                 this.watchdog = null;
90             }
91             
92             // console.log("SS: "+safestatus(xhr));
93             
94             try {
95                 if ((ret = safestatus(this.xhr)) == 200) {
96                     this.delay = 0;
97                     // console.log("del a null "+this.delayed);
98                 } else if (ret != -1) {
99                     this.delay = 5000;
100                     this.hbit('X');
101                     // alert('There was a problem with the request.' + ret);
102                 }
103             } catch(b) {};
104             
105             this.delayed = null;
106             this.stopped = true;
107         }
108     },
109
110     xhr_abort: function()
111     {
112         this.hbit('A');
113         if (this.xhr != null)
114             this.xhr.abort();
115         // alert("de che");
116     },
117
118     run: function(sess, stat, subst, step) 
119     {
120         if (this.the_end) {
121             //x alert("the_end1");
122             if (this.watchdog != null) {
123                 this.hbit('C');
124                 clearTimeout(this.watchdog);
125                 this.watchdog = null;
126             }
127             return;
128         }
129         createCookie(this.cookiename, sess, 24*365, this.cookiepath);
130         
131         // NOTE: *ctx = "" to prevent konqueror stream commands duplication.
132         this.oldctx = "";
133         this.newctx = "";
134         
135         /* NOTE document.uniqueID exists only under IE  */
136         // if (g_is_spawn == 1)
137         // alert("di qui3: "+(g_is_spawn == 1 ? "&table_idx="+g_table_idx : ""));
138         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);
139         //    try { 
140
141         var self = this;
142         this.xhr.onreadystatechange = function () { self.xhr_cb(); };
143         this.xhr.send(null);
144         // 
145         // TODO: qui avvio del timer per riavviare xhr
146         // 
147         this.watchdog = setTimeout(function(obj){ obj.xhr_abort(); }, 60000, this);
148         this.cur_n++;
149         this.stopped = false;
150         // } catch (e) {}
151     },
152     
153     /* WORK HERE TO RUN WIN OR LIN STREAM */
154     
155     start: function(sess)
156     {
157         this.poll(sess);
158     },
159
160     stop: function()
161     {
162         this.the_end = true;
163     },
164
165     poll: function(sess)
166     {
167         var tout = 100;
168         var again;
169         var xhrrestart;
170         
171         this.ct++;
172         
173         /*
174           if (this.watchdog_old >= 50) {
175           this.watchdog_old = 0;
176           // alert("ABORT XHR");
177           this.stopped = true;
178           this.xhr.abort();     
179           }
180         */
181         if (this.sandbox != null) {
182             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;
183             
184             if (zug != this.sandbox.innerHTML)
185                 this.sandbox.innerHTML = zug;
186         }
187         /* heartbit log */
188         this.hbit("_");
189         do {
190             again = 0;
191             xhrrestart = 0;
192             if (this.gst.st_loc < this.gst.st_loc_new) {
193                 // there is some slow actions running
194                 break;
195             }
196             else if (this.gst.comms.length > 0) {
197                 var singlecomm;
198                 
199                 singlecomm = this.gst.comms.shift();
200                 // alert("EXE"+gugu);
201                 // $("xhrdeltalog").innerHTML = "EVALL: "+singlecomm.replace("<", "&lt;", "g"); +"<br>";
202                 this.hbit("+");
203                 
204                 eval(singlecomm);
205                 again = 1;
206             }
207             else {
208                 xhrrestart = 1;
209                 try { 
210                     if (this.xhr == null)
211                         throw "restart";
212                     if (this.xhr.responseText != null)
213                         this.newctx = this.xhr.responseText;
214                 }
215                 catch (e) {
216                     if (this.stopped == true) {
217                         this.stopped = false;
218                         // XX $("xhrstart").innerHTML += "XHRSTART: da catch<br>";
219                         if (this.delay > 0) {
220                             if (this.delayed == null) {
221                                 // console.log("XXX DI QUI "+this.delay);
222
223                                 this.delayed = setTimeout(
224                                     function(f_obj, f_sess, f_stat, f_subst, f_step){ f_obj.run(f_sess, f_stat, f_subst, f_step); },
225                                     this.delay, this, sess, stat, subst, this.gst.st);
226                                 // console.log("XXX DI QUI post"+this.delayed);
227                             }
228                         }
229                         else {
230                             // console.log("yyy DI QUI "+this.delay);
231                             this.run(sess, stat, subst, this.gst.st);
232                         }
233                     }
234                     
235                     
236                     // $("sandbox").innerHTML += "return 1<br>";
237                     if (this.the_end != true) {
238                         /* this.watchdog_old = 0; */
239                         setTimeout(function(obj, sess){ obj.poll(sess); }, tout, this, sess);
240                         
241                         // this.hbit(".");
242                         
243                     }
244                     else {
245                         //x alert("the_end2");
246                         if (this.watchdog != null) {
247                             clearTimeout(this.watchdog);
248                             this.watchdog = null;
249                         }
250                     }    
251                     return;
252                 }
253                 
254                 
255                 // no new char from the last loop, break
256                 if (this.old_n == this.cur_n && 
257                     this.newctx.length == this.checkedlen) {
258                     /* this.watchdog++; */
259                     break;
260                 }
261                 else {
262                     // $("sandbox").innerHTML += "BIG IF<br>";
263                     var comm_match;
264                     var comm_clean;
265                     var comm_len;
266                     var comm_newpart;
267                     var comm_arr;
268                     var i;
269                     var delta = 0;
270                     var match_lines = /^_*$/;
271                     
272                     /* this.watchdog = 0; */
273                     this.hbit("/\\");
274                     
275                     // check for the same command group
276                     if (this.old_n != this.cur_n) {
277                         this.old_n = this.cur_n;
278                         this.checkedlen = 0;
279                         this.oldctx = "";
280                     }
281                     else
282                         delta = this.oldctx.length;
283                     
284                     // $("xhrlog").innerHTML += "EVERY SEC<br>";                
285                     for (i = delta ; i < this.newctx.length ; i++) {
286                         if (this.newctx[i] != '_') 
287                             break;
288                     }
289                     if (i == this.newctx.length) {
290                         this.checkedlen = i;
291                         break;
292                     }
293                     
294                     // $("xhrlog").innerHTML += "CHECK COM<br>";                
295                     // extracts the new part of the command string
296                     comm_newpart = this.newctx.substr(delta);
297                     
298                     // XX $("xhrlog").innerHTML = newctx.replace("<", "&lt;", "g");
299                     
300                     // $("response").innerHTML = comm_newpart;
301                     comm_match = /_*@BEGIN@(.*?)@END@/g;
302                     comm_clean = /_*@BEGIN@(.*?)@END@/;
303                     comm_len = 0;
304                     comm_arr = comm_newpart.match(comm_match);
305                     
306                     // $("sandbox").innerHTML += "PRE COMMARR<br>";
307                     if (comm_arr) {
308                         // XX $("xhrdeltalog").innerHTML += "DELTA: "+delta +"<br>";
309                         // XX alert("newctx: "+this.newctx);
310                         // $("sandbox").innerHTML += "POST COMMARR<br>";
311                         for (i = 0 ; i < comm_arr.length ; i++) {
312                             var temp = comm_arr[i].replace(comm_clean,"$1").split("|");
313                             this.gst.comms = this.gst.comms.concat(temp);
314                             // XX alert("COMM_ARR["+i+"]: "+comm_arr[i]+"  LEN:"+comm_arr[i].length);
315                             comm_len += comm_arr[i].length;
316                         }
317                         tout = 0;
318                         this.oldctx += comm_newpart.substr(0,comm_len);
319                         // XX alert("OLDCTX: "+this.oldctx);
320                         again = 1;
321                     }
322                     this.checkedlen = this.oldctx.length;
323                 }
324             }
325         } while (again);
326
327         if (xhrrestart == 1 && this.stopped == true) {
328             // $("sandbox").innerHTML += "LITTLE IF<br>";
329             // alert("di qui");
330             // XX $("xhrstart").innerHTML += "XHRSTART: da end poll<br>";
331             if (this.delay > 0) {
332                 if (this.delayed == null) {
333                     // console.log("XXX DI QUO "+this.delay);
334                     
335                     this.delayed = setTimeout(
336                         function(obj, sess, stat, subst, step){ obj.run(sess, stat, subst, step); },
337                         this.delay, this, sess, stat, subst, this.gst.st);
338                     // console.log("XXX DI QUO post"+this.delayed);
339                 }
340             }
341             else {
342                 // console.log("yyy DI QUO "+this.delay);
343                 this.run(sess, stat, subst, this.gst.st);
344             }
345             
346         }
347         
348         if (this.the_end != true) {
349             setTimeout(function(obj, sess){ obj.poll(sess); }, tout, this, sess);
350         }
351         else {
352             //x alert("the_end3");
353             if (this.watchdog != null) {
354                 clearTimeout(this.watchdog);
355                 this.watchdog = null;
356             }
357         }
358         return;
359     }
360 }
361     
362 /*
363   window.onload = function () {
364   xhr = createXMLHttpRequest();
365
366   sess = $("user").value;
367   window.setTimeout(poll, 0, sess);
368   };
369 */