]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/chrome/content/util/network.js
more debug info for outbound requests
[working/Evergreen.git] / Open-ILS / xul / staff_client / chrome / content / util / network.js
1 dump('entering util/network.js\n');
2 // vim:noet:sw=4:ts=4:
3
4 var offlineStrings;
5
6 if (typeof util == 'undefined') util = {};
7 util.network = function () {
8
9     try {
10
11         JSAN.use('util.error'); this.error = new util.error();
12         JSAN.use('util.sound'); this.sound = new util.sound();
13
14         offlineStrings = document.getElementById('offlineStrings');
15
16     } catch(E) {
17         alert('error in util.network constructor: ' + E);
18         throw(E);
19     }
20
21     return this;
22 };
23
24 util.network.prototype = {
25
26     'link_id' : 0,
27
28     'network_timeout' : 55, /* seconds */
29
30     'NETWORK_FAILURE' : null,
31
32     'simple_request' : function(method_id,params,f,override_params) {
33         //var obj = this;
34         //var sparams = js2JSON(params);
35         //obj.error.sdump('D_SES','simple_request '+ method_id +' '+obj.error.pretty_print(sparams.slice(1,sparams.length-1))+
36         //    '\noverride_params = ' + override_params + '\n');
37         if (typeof api[method_id] == 'undefined') {
38             throw( offlineStrings.getFormattedString('network.method_not_found.error', [method_id]) );
39         }
40         var secure = true; if (typeof api[method_id].secure != 'undefined') secure = api[method_id].secure;
41         return this.request(api[method_id].app,api[method_id].method,params,f,override_params,{ 'secure' : secure, 'method_id' : method_id });
42     },
43
44     'get_result' : function (req) {
45         var obj = this;
46         var result;
47         var fake_ilsevent_for_network_errors = { 'ilsevent' : -1, 'textcode' : offlineStrings.getString('network.server_or_method.error') }; 
48         try {
49             if (req.cancelled) {
50                 result = fake_ilsevent_for_network_errors;
51             } else {
52                 result = req.getResultObject();    
53             }
54         } catch(E) {
55             try {
56                 if (instanceOf(E, NetworkFailure)) {
57                     obj.NETWORK_FAILURE = E;
58                 } else {
59                     try { obj.NETWORK_FAILURE = js2JSON(E); } catch(F) { dump(F + '\n'); obj.NETWORK_FAILURE = E; };
60                 }
61             } catch(I) { 
62                 obj.NETWORK_FAILURE = offlineStrings.getString('network.unknown_status');
63             }
64             result = fake_ilsevent_for_network_errors;
65         }
66         return result;
67     },
68
69     'request' : function (app,name,params,f,override_params,_params) {
70
71         var obj = this;
72         
73         //var sparams = js2JSON(params);
74         //obj.error.sdump('D_SES','request '+ app + ' ' + name +' '+obj.error.pretty_print(sparams.slice(1,sparams.length-1))+
75         //    '\noverride_params = ' + override_params + '\n_params = ' + _params + '\n');
76
77         try { 
78
79             var request =  this._request(app,name,params,f,override_params,_params);
80             if (request) {
81                 return this.get_result(request);
82             } else {
83                 return null;
84             }
85     
86         } catch(E) {
87             alert('1: ' + E); 
88         }
89     },
90
91     '_request' : function (app,name,params,f,override_params,_params) {
92         var obj = this;
93         try {
94             var sparams = js2JSON(params);
95             obj.error.sdump('D_SES','_request '+app+' '+name+' '+obj.error.pretty_print(sparams.slice(1,sparams.length-1))+
96                 '\noverride_params = ' + override_params + '\n_params = ' + _params +
97                 '\nResult #' + (++obj.link_id) + ( f ? ' asynced' : ' synced' ) +
98                 '\nlocation.href = ' + location.href );
99
100             if (document.getElementById('network_progress')) {
101                 if (g && g.menu && g.menu.network_meter && typeof g.menu.network_meter.inc == 'function') g.menu.network_meter.inc(app,name);
102             } else if (typeof xulG != 'undefined') {
103                 if (xulG && xulG.network_meter && typeof xulG.network_meter.inc == 'function') xulG.network_meter.inc(app,name);
104             }
105
106             var request = new RemoteRequest( app, name );
107             if (_params && _params.secure) {
108                 request.setSecure(true);
109             } else {
110                 request.setSecure(false);
111             }
112             for(var index in params) {
113                 request.addParam(params[index]);
114             }
115
116             var start_timer = (new Date).getTime();    
117             if (f)  {
118                 request.setCompleteCallback(
119                     function(req) {
120                         try {
121                             var duration = ( (new Date).getTime() - start_timer )/1000;
122                             if ( obj.get_result(req) == null && duration > obj.network_timeout ) req.cancelled = true;
123
124                             if (document.getElementById('network_progress')) {
125                                 if (g && g.menu && g.menu.network_meter && typeof g.menu.network_meter.dec == 'function') g.menu.network_meter.dec(app,name);
126                             } else if (typeof xulG != 'undefined') {
127                                 if (xulG && xulG.network_meter && typeof xulG.network_meter.dec == 'function') xulG.network_meter.dec(app,name);
128                             }
129
130                             var json_string = js2JSON(obj.get_result(req));
131                             obj.error.sdump('D_SES_RESULT','asynced result #' 
132                                 + obj.link_id + '\n\n' 
133                                 + (json_string.length > 80 ? obj.error.pretty_print(json_string) : json_string) 
134                                 + '\n\nOriginal Request:\n\n' 
135                                 + 'request '+app+' '+name+' '+ sparams.slice(1,sparams.length-1));
136                             req = obj.rerequest_on_session_timeout(app,name,params,req,override_params,_params);
137                             req = obj.rerequest_on_perm_failure(app,name,params,req,override_params,_params);
138                             if (override_params) {
139                                 req = obj.rerequest_on_override(app,name,params,req,override_params,_params);
140                             }
141                             req = obj.check_for_offline(app,name,params,req,override_params,_params);
142                             f(req);
143                             obj.NETWORK_FAILURE = null;
144                         } catch(E) {
145                             try {
146                                 E.ilsevent = -2;
147                                 E.textcode = offlineStrings.getString('network.server_or_method.error');
148                             } catch(F) {}
149                             f( { 'getResultObject' : function() { return E; } } );
150                         }
151                     }
152                 );
153                 try {
154                     request.send(false);
155                 } catch(E) {
156                     throw(E);
157                 }
158                 return null;
159             } else {
160                 try {
161                     request.send(true);
162                     var duration = ( (new Date).getTime() - start_timer )/1000;
163                     if ( obj.get_result(request) == null && duration > obj.network_timeout ) request.cancelled = true;
164
165                     if (document.getElementById('network_progress')) {
166                         if (g && g.menu && g.menu.network_meter && typeof g.menu.network_meter.dec == 'function') g.menu.network_meter.dec(app,name);
167                     } else if (typeof xulG != 'undefined') {
168                         if (xulG && xulG.network_meter && typeof xulG.network_meter.dec == 'function') xulG.network_meter.dec(app,name);
169                     }
170
171                 } catch(E) {
172                     throw(E);
173                 }
174                 var result = obj.get_result(request);
175                 var json_string = js2JSON(result);
176                 this.error.sdump('D_SES_RESULT','synced result #' 
177                     + obj.link_id + '\n\n' + ( json_string.length > 80 ? obj.error.pretty_print(json_string) : json_string ) 
178                     + '\n\nOriginal Request:\n\n' 
179                     + 'request '+app+' '+name+' '+ sparams.slice(1,sparams.length-1));
180                 request = obj.rerequest_on_session_timeout(app,name,params,request,override_params,_params);
181                 request = obj.rerequest_on_perm_failure(app,name,params,request,override_params,_params);
182                 if (override_params) {
183                     request = obj.rerequest_on_override(app,name,params,request,override_params,_params);
184                 }
185                 request = obj.check_for_offline(app,name,params,request,override_params,_params);
186                 obj.NETWORK_FAILURE = null;
187                 return request;
188             }
189
190         } catch(E) {
191             alert('2: ' + E);
192             if (instanceOf(E,perm_ex)) {
193                 alert('in util.network, _request : permission exception: ' + js2JSON(E));
194             }
195             throw(E);
196         }
197     },
198
199     'check_for_offline' : function (app,name,params,req,override_params,_params) {
200         try {
201             var obj = this;
202             var result = obj.get_result(req);
203             if (result == null) return req;
204             if (typeof result.ilsevent == 'undefined') return req;
205             if (result.ilsevent != -1) return req;
206
207             JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
208             var proceed = true;
209
210             while(proceed) {
211
212                 proceed = false;
213
214                 var r;
215
216                 if (data.proceed_offline) {
217
218                     r = 1;
219
220                 } else {
221
222                     var network_failure_string;
223                     var network_failure_status_string;
224                     var msg;
225
226                     try { network_failure_string = String( obj.NETWORK_FAILURE ); } catch(E) { network_failure_string = E; }
227                     try { network_failure_status_string = typeof obj.NETWORK_FAILURE == 'object' && typeof obj.NETWORK_FAILURE != 'null' && typeof obj.NETWORK_FAILURE.status == 'function' ? obj.NETWORK_FAILURE.status() : ''; } catch(E) { network_failure_status_string = ''; obj.error.sdump('D_ERROR', 'setting network_failure_status_string: ' + E); }
228                     
229                     try { msg = offlineStrings.getFormattedString('network.server.failure.exception', [data.server_unadorned]) + '\n' +
230                                 offlineStrings.getFormattedString('network.server.method', [name]) + '\n' + 
231                                 offlineStrings.getFormattedString('network.server.params', [js2JSON(params)]) + '\n' + 
232                                 offlineStrings.getString('network.server.thrown_label') + '\n' + network_failure_string + '\n' + 
233                                 offlineStrings.getString('network.server.status_label') + '\n' + network_failure_status_string;
234                     } catch(E) { msg = E; }
235
236                     try { obj.error.sdump('D_SES_ERROR',msg); } catch(E) { alert('3: ' + E); }
237
238                     r = obj.error.yns_alert(
239                         msg,
240                         offlineStrings.getString('network.network_failure'),
241                         offlineStrings.getString('network.retry_network'),
242                         offlineStrings.getString('network.ignore_errors'),
243                         null,
244                         offlineStrings.getString('common.confirm')
245                     );
246                     if (r == 1) {
247                         data.proceed_offline = true; data.stash('proceed_offline');
248                         dump('Remembering proceed_offline for 200000 ms.\n');
249                         setTimeout(
250                             function() {
251                                 data.proceed_offline = false; data.stash('proceed_offline');
252                                 dump('Setting proceed_offline back to false.\n');
253                             }, 200000
254                         );
255                     }
256                 }
257
258                 dump( r == 0 ? 'Retry Network\n' : 'Ignore Errors\n' );
259
260                 switch(r) {
261                     case 0: 
262                         req = obj._request(app,name,params,null,override_params,_params);
263                         if (obj.get_result(req)) proceed = true; /* daily WTF, why am I even doing this? :) */
264                         return req;
265                     break;
266
267                     case 1: 
268                         return req;
269                     break;
270                 }
271             }
272         } catch(E) {
273             alert('4: ' + E);
274             throw(E);
275         }
276     },
277
278     'reset_titlebars' : function(data) {
279         var obj = this;
280         data.stash_retrieve();
281         try {
282             JSAN.use('util.window'); var win =  new util.window();
283             var windowManager = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService();
284             var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
285             var enumerator = windowManagerInterface.getEnumerator(null);
286
287             var w; // set title on all appshell windows
288             while ( w = enumerator.getNext() ) {
289                 if (w.document.title.match(/^\d/)) {
290                     w.document.title = 
291                         win.appshell_name_increment() 
292                         + ': ' + data.list.au[0].usrname() 
293                         + '@' + data.ws_name;
294                         + '.' + data.server_unadorned 
295                 }
296             }
297         } catch(E) {
298             obj.error.standard_unexpected_error_alert(offlineStrings.getString('network.window_title.error'),E);
299         }
300     },
301
302     'get_new_session' : function(name,xulG,text) {
303         var obj = this;
304         try {
305
306         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
307         var url = urls.XUL_AUTH_SIMPLE;
308         if (typeof xulG != 'undefined' && typeof xulG.url_prefix == 'function') url = xulG.url_prefix( url );
309         JSAN.use('util.window'); var win = new util.window();
310         var my_xulG = win.open(
311             url,
312             //+ '?login_type=staff'
313             //+ '&desc_brief=' + window.escape( text ? 'Session Expired' : 'Operator Change' )
314             //+ '&desc_full=' + window.escape( text ? 'Please enter the credentials for a new login session.' : 'Please enter the credentials for the new login session.  Note that the previous session is still active.'),
315             //'simple_auth' + (new Date()).toString(),
316             offlineStrings.getString('network.new_session.authorize'),
317             'chrome,resizable,modal,width=700,height=500',
318             {
319                 'login_type' : 'staff',
320                 'desc_brief' : text ? offlineStrings.getString('network.new_session.expired') : offlineStrings.getString('network.new_session.operator_change'),
321                 'desc_full' : text ? offlineStrings.getString('network.new_session.expired.prompt') : offlineStrings.getString('network.new_session.operator_change.prompt')
322                 //'simple_auth' : (new Date()).toString(),
323             }
324         );
325         JSAN.use('OpenILS.data');
326         var data = new OpenILS.data(); data.init({'via':'stash'});
327         if (typeof data.temporary_session != 'undefined' && data.temporary_session != '') {
328             data.session.key = data.temporary_session.key; 
329             data.session.authtime = data.temporary_session.authtime; 
330             data.stash('session');
331             try {
332                 var ios = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
333                 var cookieUri = ios.newURI("http://" + data.server_unadorned, null, null);
334                 var cookieUriSSL = ios.newURI("https://" + data.server_unadorned, null, null);
335                 var cookieSvc = Components.classes["@mozilla.org/cookieService;1"].getService(Components.interfaces.nsICookieService);
336
337                 cookieSvc.setCookieString(cookieUri, null, "ses="+data.session.key, null);
338                 cookieSvc.setCookieString(cookieUriSSL, null, "ses="+data.session.key, null);
339
340             } catch(E) {
341                 alert(offineStrings.getFormattedString('main.session_cookie.error', [E]));
342             }
343             if (! data.list.au ) data.list.au = [];
344             data.list.au[0] = JSON2js( data.temporary_session.usr );
345             data.stash('list');
346             obj.reset_titlebars(data);
347             return true;
348         } else {
349             obj.error.sdump('D_TRACE','No new session key after simple_auth in util/network\n');
350         }
351         return false;
352
353         } catch(E) {
354             obj.error.standard_unexpected_error_alert('util.network.get_new_session',E);
355         }
356     },
357
358     'rerequest_on_session_timeout' : function(app,name,params,req,override_params,_params) {
359         try {
360             var obj = this;
361             var robj = obj.get_result(req);
362             if (robj != null && robj.ilsevent && robj.ilsevent == 1001) {
363
364                 if (obj.get_new_session(name,undefined,true)) {
365                     JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
366                     params[0] = data.session.key;
367                     req = obj._request(app,name,params,null,override_params,_params);
368                 }
369             }
370         } catch(E) {
371             this.error.standard_unexpected_error_alert('rerequest_on_session_timeout',E);
372         }
373         return req;
374     },
375     
376     'rerequest_on_perm_failure' : function(app,name,params,req,override_params,_params) {
377         try {
378             var obj = this;
379             var robj = obj.get_result(req);
380             if (robj != null && robj.ilsevent && robj.ilsevent == 5000) {
381                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
382                 if (location.href.match(/^chrome/)) {
383                     //alert('Permission denied.');
384                 } else {
385                     JSAN.use('util.window'); var win = new util.window();
386                     var my_xulG = win.open(
387                         urls.XUL_AUTH_SIMPLE,
388                         //+ '?login_type=temp'
389                         //+ '&desc_brief=' + window.escape('Permission Denied: ' + robj.ilsperm)
390                         //+ '&desc_full=' + window.escape('Another staff member with the above permission may authorize this specific action.  Please notify your library administrator if you need this permission.  If you feel you have received this exception in error, inform your friendly Evergreen developers of the above permission and this debug information: ' + name),
391                         //'simple_auth' + (new Date()).toString(),
392                         offlineStrings.getFormattedString('network.permission.authorize'),
393                         'chrome,resizable,modal,width=700,height=500',
394                         {
395                             'login_type' : 'temp',
396                             'desc_brief' : offlineStrings.getFormattedString('network.permission.description.brief', [robj.ilsperm]),
397                             'desc_full' : offlineStrings.getFormattedString('network.permission.description.full', [name])
398                             //'simple_auth' : (new Date()).toString(),
399                         }
400                     );
401                     JSAN.use('OpenILS.data');
402                     //var data = new OpenILS.data(); data.init({'via':'stash'});
403                     if (typeof my_xulG.temporary_session != 'undefined' && my_xulG.temporary_session != '') {
404                         params[0] = my_xulG.temporary_session.key;
405                         req = obj._request(app,name,params,null,override_params,_params);
406                     }
407                 }
408             }
409         } catch(E) {
410             this.error.sdump('D_ERROR',E);
411         }
412         return req;
413     },
414
415     'rerequest_on_override' : function (app,name,params,req,override_params,_params) {
416         var obj = this;
417         try {
418             if (!override_params.text) override_params.text = {};
419             function override(r) {
420                 try {
421                     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
422                     obj.sound.bad();
423                     var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">' + 
424                         '<groupbox><caption label="' + offlineStrings.getString('network.override.exceptions') + '"/>' + 
425                         '<grid><columns><column/><column/></columns><rows>';
426                     for (var i = 0; i < r.length; i++) {
427                         var t1 = String(r[i].ilsevent).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
428                         var t2 = String(r[i].textcode).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
429                         var t3 = String((override_params.text[r[i].ilsevent] ? override_params.text[r[i].ilsevent](r[i]) : '')).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
430                         var t4 = String(r[i].desc).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
431                         xml += '<row>' + 
432                             '<description class="oils_event" tooltiptext="' + t1 + '">' + t2 + '</description>' + 
433                             '<description>' + t3 + '</description>' + 
434                             '</row><row>' + '<description>' + t4 + '</description>' + '</row>';
435                     }
436                     xml += '</rows></grid></groupbox><groupbox><caption label="' + offlineStrings.getString('network.override.override') +'"/><hbox>' + 
437                         '<description>' + offlineStrings.getString('network.override.force.prompt') + '</description>' + 
438                         '<button accesskey="' + offlineStrings.getString('common.no.accesskey') + '" label="' + offlineStrings.getString('common.no') + '" name="fancy_cancel"/>' + 
439                         '<button id="override" accesskey="' + offlineStrings.getString('common.yes.accesskey') + '" label="' + offlineStrings.getString('common.yes') + '" name="fancy_submit" value="override"/></hbox></groupbox></vbox>';
440                     //JSAN.use('OpenILS.data');
441                     //var data = new OpenILS.data(); data.init({'via':'stash'});
442                     //data.temp_override_xml = xml; data.stash('temp_override_xml');
443                     JSAN.use('util.window'); var win = new util.window();
444                     var fancy_prompt_data = win.open(
445                         urls.XUL_FANCY_PROMPT,
446                         //+ '?xml_in_stash=temp_override_xml'
447                         //+ '&title=' + window.escape(override_params.title),
448                         'fancy_prompt', 'chrome,resizable,modal,width=700,height=500',
449                         { 'xml' : xml, 'title' : override_params.title }
450                     );
451                     if (fancy_prompt_data.fancy_status == 'complete') {
452                         req = obj._request(app,name + '.override',params);
453                     }
454                     return req;
455                 } catch(E) {
456                     alert('in util.network, rerequest_on_override, override:' + E);
457                 }
458             }
459
460             var result = obj.get_result(req);
461             if (!result) return req;
462
463             if ( 
464                 (typeof result.ilsevent != 'undefined') && 
465                 (
466                     (override_params.overridable_events.indexOf( result.ilsevent == null ? null : Number(result.ilsevent) ) != -1) ||
467                     (override_params.overridable_events.indexOf( result.textcode ) != -1)
468                 )
469             ) {
470                 req = override([result]);
471             } else {
472                 var found_good = false; var found_bad = false;
473                 for (var i = 0; i < result.length; i++) {
474                     if ( 
475                         (result[i].ilsevent != 'undefined') && 
476                         (
477                             (override_params.overridable_events.indexOf( result[i].ilsevent == null ? null : Number(result[i].ilsevent) ) != -1) ||
478                             (override_params.overridable_events.indexOf( result[i].textcode ) != -1) 
479                         )
480                     ) {
481                         found_good = true;
482                     } else {
483                         found_bad = true;
484                     }
485                 }
486                 if (found_good && (!found_bad)) req = override(result);
487             }
488
489             return req;
490         } catch(E) {
491             throw(E);
492         }
493     },
494
495     'ping' : function() {
496         try {
497             JSAN.use('util.file'); JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
498             var file = new util.file('ping.bat');
499             var path = file._file.path;
500             file.write_content('truncate+exec',
501                 '#!/bin/sh\n' +
502                 'ping -n 15 ' + data.server_unadorned + ' > "' + path + '.txt"\n' + /* windows */
503                 'ping -c 15 ' + data.server_unadorned + ' >> "' + path + '.txt"\n'  /* unix */
504             );
505             file.close();
506             file = new util.file('ping.bat');
507
508             var process = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
509             process.init(file._file);
510
511             var args = [];
512
513             dump('process.run = ' + process.run(true, args, args.length) + '\n');
514
515             file.close();
516
517             var file = new util.file('ping.bat.txt');
518             var output = file.get_content();
519             file.close();
520
521             return output;
522         } catch(E) {
523             alert(E);
524         }
525     }
526 }
527
528 /*
529 function sample_callback(request) {
530     var result = request.getResultObject();
531 }
532 */
533
534 dump('exiting util/network.js\n');