1 var XML_HTTP_GATEWAY = "osrf-gateway-v1";
2 var XML_HTTP_SERVER = "";
5 /* This object is thrown when network failures occur */
6 function NetworkFailure(stat, url) {
11 NetworkFailure.prototype.status = function() { return this._status; }
12 NetworkFailure.prototype.url = function() { return this._url; }
13 NetworkFailure.prototype.toString = function() {
14 return "Network Failure: status = " + this.status() +'\n'+this.url();
19 function isXUL() { try { if(IAMXUL) return true;}catch(e){return false;}; }
20 var _allrequests = {};
22 // If the legacy JSON gateway is needed by the staff client, uncomment this
25 XML_HTTP_GATEWAY = 'gateway';
29 function cleanRemoteRequests() {
30 for( var i in _allrequests )
31 destroyRequest(_allrequests[i]);
34 function abortAllRequests() {
35 for( var i in _allrequests ) {
36 var r = _allrequests[i];
44 function destroyRequest(r) {
48 r.xmlhttp.onreadystatechange = function(){};
54 _allrequests[r.id] = null;
57 /* ----------------------------------------------------------------------- */
60 function RemoteRequest( service, method ) {
62 /* dojo is currently only available in the OPAC */
64 /* We want OpenSRF.locale for xx-YY format */
65 this.locale = OpenSRF.locale;
70 this.service = service;
74 this.alertEvent = true; /* only used when isXUL is false */
76 this.type = "POST"; /* default */
78 this.cancelled = false;
80 this.setSecure(false);
81 if(isXUL()) this.setSecure(true);
83 _allrequests[this.id] = this;
88 while(i < arguments.length) {
89 var object = js2JSON(arguments[i++]);
90 this.params += "¶m=" + encodeURIComponent(object);
93 if(!this.params) { this.params = ""; }
95 this.param_string = "service=" + service + "&method=" + method + this.params;
96 if (this.locale != null) {
97 this.param_string = this.param_string + "&locale=" + this.locale;
99 if( this.buildXMLRequest() == null ) alert("Browser is not supported!");
104 RemoteRequest.prototype.timeout = function(t) {
107 req.timeoutFunc = setTimeout(
109 if( req && req.xmlhttp ) {
110 req.cancelled = true;
112 if( req.abtCallback ) {
113 req.abtCallback(req);
121 RemoteRequest.prototype.abortCallback = function(func) {
122 this.abtCallback = func;
125 RemoteRequest.prototype.event = function(evt) {
126 if( arguments.length > 0 )
131 RemoteRequest.prototype.abort = function() {
133 /* this has to come before abort() or IE will puke on you */
134 this.xmlhttp.onreadystatechange = function(){};
135 this.xmlhttp.abort();
139 /* constructs our XMLHTTPRequest object */
140 RemoteRequest.prototype.buildXMLRequest = function() {
141 this.xmlhttp = buildXMLRequest();
146 function buildXMLRequest() {
148 return new XMLHttpRequest();
151 return new ActiveXObject("Msxml2.XMLHTTP");
154 return new ActiveXObject("Microsoft.XMLHTTP");
156 alert("NEEDS NEWER JAVASCRIPT for XMLHTTPRequest()");
164 function _remoteRequestCallback(id) {
166 var object = _allrequests[id];
167 if(object.cancelled) return;
169 if( object.xmlhttp.readyState == 4 ) {
172 object.duration = new Date().getTime() - object.sendTime;
173 dump('request ' + object.id + ': duration = ' + object.duration + ' ms\n');
177 object.callback(object);
181 destroyRequest(object);
188 /* define the callback we use when this request has received
190 RemoteRequest.prototype.setCompleteCallback = function(callback) {
191 if(this.cancelled) return;
192 this.callback = callback;
194 this.xmlhttp.onreadystatechange = function() { _remoteRequestCallback(id); }
198 /* http by default. This makes it https. *ONLY works when
199 embedded in a XUL app. */
200 RemoteRequest.prototype.setSecure = function(bool) {
204 RemoteRequest.prototype.send = function(blocking) {
206 if(this.cancelled) return;
208 /* determine the xmlhttp server dynamically */
209 var url = location.protocol + "//" + location.host + "/" + XML_HTTP_GATEWAY;
212 if( XML_HTTP_SERVER )
213 url = 'http://'+XML_HTTP_SERVER+'/'+XML_HTTP_GATEWAY;
215 if( url.match(/^http:/) &&
216 (this.secure || location.href.match(/^https:/) || location.href.match(/^chrome:/) ) ) {
217 netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
218 url = url.replace(/^http:/, 'https:');
223 if( this.type == 'GET' ) url += "?" + this.param_string;
227 //if( isXUL() ) dump('request URL = ' + url + '?' + this.param_string + '\n');
231 if(blocking) this.xmlhttp.open(this.type, url, false);
232 else this.xmlhttp.open(this.type, url, true);
235 alert("Fatal error opening XMLHTTPRequest for URL:\n" + url + '\n' + E);
239 if( this.type == 'POST' ) {
240 data = this.param_string;
241 this.xmlhttp.setRequestHeader('Content-Type',
242 'application/x-www-form-urlencoded');
247 try { dojo.require('dojo.cookie'); auth = dojo.cookie(COOKIE_SES) } catch(ee) {}
248 if( isXUL() ) auth = fetchXULStash().session.key;
250 this.xmlhttp.setRequestHeader('X-OILS-Authtoken', auth);
254 if(data && data.match(/param=undefined/)) {
255 /* we get a bogus param .. replace with NULL */
256 try{dump('!+! UNDEFINED PARAM IN QUERY: ' + this.service + ' : ' + this.method+'\n');}catch(r){}
257 data = data.replace(/param=undefined/g,'param=null');
261 this.sendTime = new Date().getTime();
262 try{ this.xmlhttp.send( data ); } catch(e){}
267 /* returns the actual response text from the request */
268 RemoteRequest.prototype.getText = function() {
269 return this.xmlhttp.responseText;
272 RemoteRequest.prototype.isReady = function() {
273 return this.xmlhttp.readyState == 4;
277 /* returns the JSON->js result object */
278 RemoteRequest.prototype.getResultObject = function() {
280 if(this.cancelled) return null;
281 if(!this.xmlhttp) return null;
289 dump(this.url + '?' + this.param_string + '\n' +
290 'Returned with \n\tstatus = ' + this.xmlhttp.status +
291 '\n\tpayload= ' + this.xmlhttp.responseText + '\n');
296 status = this.xmlhttp.status;
297 if( status != 200 ) failed = true;
298 } catch(e) { failed = true; }
301 if(!status) status = '<unknown>';
302 try{dump('! NETWORK FAILURE. HTTP STATUS = ' +status+'\n'+this.param_string+'\n');}catch(e){}
304 throw new NetworkFailure(status, this.param_string);
308 var text = this.xmlhttp.responseText;
310 //try{if(getDebug()) _debug('response: ' + text + '\n')}catch(e){}
312 if(text == "" || text == " " || text == null) {
313 try { dump('dbg: Request returned no text!\n'); } catch(E) {}
315 throw new NetworkFailure(status, this.param_string);
319 var obj = JSON2js(text);
320 if(!obj) return null;
322 if( obj.status != 200 ) {
324 var str = 'A server error occurred. Debug information follows: ' +
325 '\ncode = ' + obj.status +
326 '\ndebug: ' + obj.debug +
327 '\npayload: ' + js2JSON(obj.payload);
339 var payload = obj.payload;
340 if(!payload || payload.length == 0) return null;
341 payload = (payload.length == 1) ? payload[0] : payload;
344 if( checkILSEvent(payload) ) {
346 if( this.alertEvent ) {
347 alertILSEvent(payload);
356 /* adds a new parameter to the request */
357 RemoteRequest.prototype.addParam = function(param) {
358 var string = encodeURIComponent(js2JSON(param));
359 this.param_string += "¶m=" + string;
362 function fetchXULStash() {
365 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
366 var __OILS = new Components.Constructor("@mozilla.org/openils_data_cache;1", "nsIOpenILS");
367 var data_cache = new __OILS( );
368 return data_cache.wrappedJSObject.OpenILS.prototype.data;
371 _debug('Error in OpenILS.data._debug_stash(): ' + js2JSON(E) );