1// LICENSE_CODE ZON ISC 2'use strict'; /*jslint browser:true, es6:true*/ 3define(['/util/csrf.js', '/util/storage.js', '/util/etask.js', '/util/url.js', 4 '/util/zerr.js'], 5 function(csrf, storage, etask, zurl, zerr){ 6var E = {}; 7 8E.is_silent = true; 9try { 10 E.is_silent = !storage.get('fetch_logs', false); 11} catch(e){} 12 13function build_params(prefix, obj, add){ 14 var name; 15 if (Array.isArray(obj)) 16 { 17 obj.forEach((el, i)=>{ 18 build_params(prefix + '[' + (typeof el=='object' && el != null 19 ? i : '') + ']', el, add); 20 }); 21 } 22 else if (typeof obj=='object' && obj!=null) 23 { 24 for (name in obj) 25 build_params(prefix + '[' + name + ']', obj[name], add); 26 } 27 else 28 add(prefix, obj); 29} 30 31const r20 = /%20/g; 32const param_to_staring = a=>{ 33 let prefix, 34 s = [], 35 add = (key, value)=>{ 36 const is_fn = typeof value=='function'; 37 value = is_fn ? value() : value == null ? '' : value; 38 s[s.length] = encodeURIComponent(key) + '=' 39 + encodeURIComponent(value); 40 }; 41 if (Array.isArray(a)) 42 a.forEach((el, i)=>add(i, el)); 43 else 44 { 45 for (prefix in a) 46 build_params(prefix, a[prefix], add); 47 } 48 return s.join('&').replace(r20, '+'); 49}; 50 51E.fetch = function(url, params){ 52 if (!E._fetch) 53 throw new Error('Call fetch, before initialization'); 54 return E._fetch(url, params); 55}; 56 57const with_slow = (et, args, opt)=>{ 58 opt = opt||{}; 59 const timeout = opt.timeout||3000; 60 const start = Date.now(); 61 let is_slow = false; 62 const timer = setTimeout(()=>{ 63 is_slow = true; 64 zerr.warn('SLOW-progress fetch '+args.join(' ')); 65 }, timeout); 66 et.finally(()=>{ 67 clearTimeout(timer); 68 if (is_slow) 69 { 70 zerr.warn(Date.now()-start+'ms SLOW-finished fetch '+ 71 args.join(' ')); 72 } 73 }); 74 return et; 75}; 76 77E.init = function(custom_fetch){ 78 if (E.patch_done) 79 return; 80 E.patch_done = true; 81 const fetch_origin = custom_fetch ? custom_fetch : self.fetch; 82 const call_origin = (url, params)=>with_slow(etask(function*(){ 83 const res = yield fetch_origin(url, params); 84 let text; 85 try { 86 text = yield res.text(); 87 } catch(e){ 88 if (!E.is_silent) 89 zerr.err(e.message); 90 e.hola_info = {url, method: params.method, 91 status: res.status, status_text: res.statusText}; 92 return e; 93 } 94 if (!res.ok) 95 { 96 const err = new Error(); 97 err.hola_info = {url, method: params.method, 98 status: res.status, response_text: text, 99 status_text: res.statusText}; 100 err.x_error = res.headers.get('X-Luminati-Error') || 101 res.headers.get('X-Hola-Error'); 102 return err; 103 } 104 let result_data = text; 105 try { 106 result_data = JSON.parse(text); 107 } catch(e){} 108 return result_data; 109 }), [params.method||'GET', url], {timeout: 3000}); 110 111 // XXX dmitriiz: path fetch with etask 112 E._fetch = function(url, params){ 113 if (!params) 114 params = {}; 115 if (!params.headers) 116 params.headers = {}; 117 if (params.method=='POST' 118 || params.method=='PUT' 119 || params.method=='PATCH' 120 || params.method=='DELETE') 121 { 122 const current = zurl.parse(location.href, true); 123 const target = zurl.parse(url, true); 124 if (!target.host || target.protocol==current.protocol 125 && target.host==current.host) 126 { 127 params.headers['X-XSRF-Token'] = csrf.get(url); 128 } 129 if (!params.auto_content_type) 130 { 131 params.headers['Content-Type'] = params.contentType || 132 params.json ? 'application/json; charset=UTF-8' : 133 'application/x-www-form-urlencoded; charset=UTF-8'; 134 } 135 } 136 if (params.xhrFields && params.xhrFields.withCredentials) 137 params.credentials = 'include'; 138 params.headers.Accept = '*/*'; 139 if (params.cache===false) 140 params.cache = 'no-cache'; 141 let controller;
142 // XXX dmitriiz: check implementation for Node 143 if (!params.signal && self && self.AbortController) 144 { 145 controller = new self.AbortController(); 146 const signal = controller.signal; 147 params.signal = signal; 148 } 149 if (!params.contentType && params.body && 150 !(params.body instanceof FormData) && typeof params.body=='object') 151 { 152 params.body = params.json ? JSON.stringify(params.body) : 153 param_to_staring(params.body); 154 } 155 const id = params.timeout && setTimeout(()=>{ 156 if (!E.is_silent) 157 zerr.err('Timeout: %s', url); 158 if (controller) 159 controller.abort(); 160 }, params.timeout); 161 return params.et = etask([function*(){ 162 this.finally(()=>clearTimeout(id)); 163 let res; 164 try { 165 res = yield call_origin(url, params); 166 } catch(e){ 167 res = e; 168 } 169 if (res instanceof Error) 170 { 171 const hola_info = res.hola_info || {}; 172 if (params.no_throw) 173 { 174 return { 175 err: res, 176 error: res, 177 url: hola_info.url || url, 178 method: hola_info.method || params.method, 179 status: hola_info.status || 0, 180 data: hola_info.response_text, 181 }; 182 } 183 throw res; 184 } 185 return res; 186 }, function cancel$(){ 187 if (controller) 188 controller.abort(); 189 }]); 190 }; 191 if (typeof self!='undefined') 192 self.hola_fetch = E._fetch; 193}; 194 195return E; 196});
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.