1// LICENSE_CODE ZON ISC 2'use strict'; /*zlint node, br*/ 3(function(){ 4var define; 5var is_node = typeof module=='object' && module.exports && module.children; 6if (!is_node) 7 define = self.define; 8else 9 define = require('./require_node.js').define(module, '../'); 10define(['jquery', '/util/etask.js', '/util/date.js', '/util/escape.js', 11 '/util/zerr.js', 'events'], 12 function($, etask, date, zescape, zerr, events){ 13var E = ajax; 14var assign = Object.assign; 15E.events = new events.EventEmitter(); 16E.json = function(opt){ return ajax(assign({}, opt, {json: 1})); }; 17E.abort = function(aj){ aj.goto('abort'); }; 18// XXX arik: need test 19function ajax(opt){ 20 var timeout = opt.timeout||20*date.ms.SEC, slow = opt.slow||2*date.ms.SEC; 21 var retry = opt.retry, data = opt.data, qs = zescape.qs(opt.qs); 22 var url = zescape.uri(opt.url, qs), perr = opt.perr; 23 var response_etag, response_status; 24 // opt.type is deprecated 25 var method = opt.method||opt.type||'GET'; 26 var data_type = opt.json ? 'json' : 'text'; 27 var t0 = Date.now(); 28 var xhr; 29 zerr.debug('ajax('+data_type+') url '+url+' retry '+retry); 30 return etask([function(){ 31 var ajopt = {dataType: data_type, type: method, url: url, 32 data: data, timeout: timeout, xhrFields: {}, 33 no_throw: opt.no_throw}; 34 if (opt.headers) 35 ajopt.headers = opt.headers; 36 if (opt.content_type) 37 ajopt.contentType = opt.content_type; 38 if (opt.with_credentials) 39 ajopt.xhrFields.withCredentials = true; 40 if (opt.onprogress) 41 ajopt.xhrFields.onprogress = opt.onprogress; 42 if (opt.onuploadprogress) 43 { 44 ajopt.xhr = function(){ 45 var _xhr = $.ajaxSettings.xhr(); 46 _xhr.upload.onprogress = opt.onuploadprogress; 47 return _xhr; 48 }; 49 } 50 if (opt.multipart) 51 { 52 ajopt.contentType = false;
53 ajopt.processData = false; 54 delete ajopt.dataType; 55 } 56 if (opt.async!==undefined) 57 ajopt.async = opt.async; 58 xhr = $.ajax(ajopt); 59 var _this = this; 60 if (xhr instanceof etask) 61 return xhr; 62 xhr.done(function(v, status_text, _xhr){ 63 response_etag = _xhr.getResponseHeader('etag'); 64 response_status = _xhr.status; 65 var server_ts = +_xhr.getResponseHeader('x-hola-ts'); 66 if (server_ts) 67 E.events.emit('server_ts', server_ts); 68 var conf_ver = +_xhr.getResponseHeader('x-hola-conf-ver'); 69 if (conf_ver) 70 E.events.emit('conf_ver', conf_ver); 71 _this.continue(v); 72 }); 73 xhr.fail(function(_xhr, status_text, err){ 74 if (data_type=='json' && _xhr && _xhr.status==200 && 75 ['', 'ok', 'OK'].includes(_xhr.responseText)) 76 { 77 _this.continue(null); 78 return; 79 } 80 if (!err && data_type=='text' && _xhr && _xhr.responseText) 81 err = _xhr.responseText; 82 _this.throw(err instanceof Error ? err : new Error(''+err)); 83 }); 84 return this.wait(); 85 }, function catch$(err){ 86 xhr = xhr||{}; 87 var status = xhr.status; 88 var status_text = xhr.statusText; 89 var response_text = xhr.responseText; 90 if (xhr instanceof etask) 91 { 92 var hola_info = err.hola_info || {}; 93 status = hola_info.status; 94 status_text = hola_info.status_text; 95 response_text = hola_info.response_text; 96 } 97 zerr('ajax('+data_type+') failed url '+url+' data '+ 98 zerr.json(data).substr(0, 200)+' status: '+status+' '+ 99 status_text+'\nresponseText: '+ 100 (response_text||'').substr(0, 200)); 101 if (retry && (!opt.should_retry||opt.should_retry(err, 102 {status: status}))) 103 { 104 return this.return(ajax(assign({}, opt, {retry: retry-1}))); 105 } 106 if (err instanceof Error && err.hola_info) 107 throw err; 108 if (status_text=='timeout') 109 E.events.emit('timeout', this); 110 if (xhr instanceof etask) 111 { 112 if (xhr.headers && xhr.headers.get('x-hola-ts')) 113 E.events.emit('server_ts', +xhr.headers.get('x-hola-ts')); 114 } 115 else if (xhr.getResponseHeader('x-hola-ts')) 116 E.events.emit('server_ts', +xhr.getResponseHeader('x-hola-ts')); 117 if (opt.no_throw) 118 { 119 return { 120 err: err, 121 url: url, 122 method: method, 123 status: +status || 0, 124 data: get_res_data(xhr), 125 xhr: xhr, 126 // legacy 127 error: status_text||'no_status', message: response_text, 128 }; 129 } 130 err.hola_info = {url: url, method: method, status: status, 131 data: get_res_data(xhr), response_text: response_text}; 132 if (xhr instanceof etask && xhr.headers) 133 err.x_error = xhr.headers.get('X-Hola-Error'); 134 else 135 err.x_error = xhr.getResponseHeader('X-Hola-Error'); 136 throw err; 137 }, function(data){ 138 if (xhr instanceof etask && xhr.headers) 139 { 140 var server_ts = +xhr.headers.get('x-hola-ts'); 141 if (server_ts) 142 E.events.emit('server_ts', server_ts); 143 var conf_ver = +xhr.headers.get('x-hola-conf-ver'); 144 if (conf_ver) 145 E.events.emit('conf_ver', conf_ver); 146 } 147 var t = Date.now()-t0; 148 zerr[t>slow ? 'err' : 'debug']( 149 'ajax('+data_type+') '+(t>slow ? 'SLOW ' : 'ok ')+t+'ms url '+url); 150 if (t>slow && perr && !url.includes('client_cgi/perr')) 151 { 152 perr({id: 'be_ajax_slow', info: t+'ms '+url, 153 rate_limit: {count: 1}}); 154 } 155 if (E.do_op) 156 E.do_op(data&&data.do_op); 157 if (opt.full_response) 158 { 159 return this.return({data: data, etag: response_etag, 160 status: response_status}); 161 } 162 return this.return(data); 163 }, function abort(){ 164 // reachable only via E.abort 165 xhr.abort(); 166 }]); 167} 168
169['GET', 'POST', 'PUT', 'DELETE'].forEach(function(m){ 170 E[m.toLowerCase()] = function(url, opt){ 171 url = typeof url=='string' ? {url: url} : url; 172 opt = assign({method: m, json: 1}, url, opt); 173 if (!{get: 1, delete: 1}[opt.method.toLowerCase()] 174 && opt.data!=null && typeof opt.data!='string') 175 { 176 opt.content_type = opt.content_type||'application/json'; 177 if (opt.content_type.startsWith('application/json')) 178 opt.data = JSON.stringify(opt.data); 179 } 180 return ajax(opt); 181 }; 182}); 183 184function get_res_data(xhr){ 185 if (xhr.responseJSON!=null && xhr.responseJSON!=='') 186 return xhr.responseJSON; 187 var content_type = xhr.getResponseHeader('content-type')||''; 188 if (xhr.responseText && content_type.includes('application/json')) 189 { 190 try { return JSON.parse(xhr.responseText); } 191 catch(e){ } 192 } 193 return xhr.responseText||''; 194} 195 196return E; }); }());
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.