PHP Classes

File: src/js/EazyHttp.js

Recommend this page to a friend!
  Classes of Nikos M.   Eazy HTTP   src/js/EazyHttp.js   Download  
File: src/js/EazyHttp.js
Role: Auxiliary data
Content typex: text/plain
Description: Auxiliary data
Class: Eazy HTTP
Send HTTP requests defined with a fluent interface
Author: By
Last change: v.1.2.0

* python socket implementation
* various edits, corrections
Date: 1 month ago
Size: 57,615 bytes
 

Contents

Class file image Download
/** * EazyHttp * easy, simple and fast HTTP requests for PHP, JavaScript, Python * @version: 1.2.0 * * https://github.com/foo123/EazyHttp **/ !function(root, name, factory) { "use strict"; var m; if (('undefined' !== typeof Components) && ('object' === typeof Components.classes) && ('object' === typeof Components.classesByID) && Components.utils && ('function' === typeof Components.utils['import'])) /* XPCOM */ (root.EXPORTED_SYMBOLS = [name]) && (root[name] = factory.call(root)); else if (('object' === typeof module) && module.exports) /* CommonJS */ module.exports = factory.call(root); else if (('function' === typeof(define)) && define.amd && ('function' === typeof(require)) && ('function' === typeof(require.specified)) && require.specified(name)) /* AMD */ define(name,['require','exports','module'], function() {return factory.call(root);}); else if (!(name in root)) /* Browser/WebWorker/.. */ (root[name] = (m=factory.call(root))) && ('function' === typeof(define)) && define.amd && define(function() {return m;}); }(/* current root */ 'undefined' !== typeof self ? self : this, /* module name */ "EazyHttp", /* module factory */ function ModuleFactory__EazyHttp(undef) { "use strict"; var VERSION = '1.2.0', PROTO = 'prototype', HAS = Object[PROTO].hasOwnProperty, toString = Object[PROTO].toString, isNode = ('undefined' !== typeof global) && ('[object global]' === toString.call(global)), isXPCOM = ('undefined' !== typeof Components) && ('object' === typeof Components.classes) && ('object' === typeof Components.classesByID) && Components.utils && ('function' === typeof Components.utils['import']), ID = 0 ; function EazyHttp() { var self = this; self.opts = {}; // some defaults self.option('timeout', 30); // sec, default self.option('follow_redirects', 3); // default self.option('return_type', 'string'); // default self.option('methods', ['http', 'fetch', 'xhr', 'iframe']); // default } EazyHttp[PROTO] = { constructor: EazyHttp, opts: null, option: function(key, val) { var nargs = arguments.length; if (1 == nargs) { return HAS.call(this.opts, key) ? this.opts[key] : undef; } else if (1 < nargs) { this.opts[key] = val; } return this; }, get: function(uri, data, headers, cookies, cb) { var self = this; if ((null == cb) && ('undefined' !== typeof(Promise))) { // promisify return new Promise(function(resolve, reject) { self._do_http('GET', uri, data, headers, cookies, function(error, response) { if (error) reject(error); else resolve(response); }); }); } else { self._do_http('GET', uri, data, headers, cookies, cb); return self; } }, post: function(uri, data, headers, cookies, cb) { var self = this; if ((null == cb) && ('undefined' !== typeof(Promise))) { // promisify return new Promise(function(resolve, reject) { self._do_http('POST', uri, data, headers, cookies, function(error, response) { if (error) reject(error); else resolve(response); }); }); } else { self._do_http('POST', uri, data, headers, cookies, cb); return self; } }, _do_http: function(method, uri, data, headers, cookies, cb) { var self = this, o, name, methods, i, n, send_method, do_http = null, cb_called = false; // for POST files user can pass the multipart encoded data and set Content-Type // binary data are passed as Buffers/Uint8 and set appropriate Content-Type // for PUT, PATCH and DELETE methods code is ready method = String(method).toUpperCase(); if (!('POST' === method || 'PUT' === method || 'PATCH' === method || 'DELETE' === method || 'HEAD' === method)) method = 'GET'; if (!headers || !is_obj(headers)) headers = {}; if (!cookies || !is_obj(cookies)) cookies = {}; o = headers; headers = {'User-Agent': 'EazyHttp', 'Accept': '*/*'}; for (name in o) { if (HAS.call(o, name)) { headers[ucwords(trim(name).toLowerCase())] = o[name]; } } o = cookies; cookies = {}; for (name in o) { if (HAS.call(o, name)) { cookies[name] = is_obj(o[name]) ? o[name] : {'value': o[name]}; cookies[name]['name'] = name; } } if (!('POST' === method || 'PUT' === method || 'PATCH' === method)) { uri += is_obj(data) ? ((-1 === uri.indexOf('?') ? '?' : '&') + http_build_query(data, '&')) : ''; data = null; } methods = self.option('methods'); if (is_array(methods) && methods.length) { for (i=0,n=methods.length; i<n; ++i) { send_method = String(methods[i]).toLowerCase(); if ( ('http' === send_method) && isNode && (https() && http()) ) { do_http = 'node'; break; } else if ( ('fetch' === send_method) && ('undefined' !== typeof(fetch)) ) { do_http = 'fetch'; break; } else if ( ('xhr' === send_method) && !isNode && ( isXPCOM || ('undefined' !== typeof XMLHttpRequest) || ('undefined' !== typeof ActiveXObject) ) ) { do_http = 'xhr'; break; } else if ( ('iframe' === send_method) && !isNode && ( ('undefined' !== typeof(document)) && (document.body) && ('function' === typeof(document.createElement)) ) ) { do_http = 'iframe'; break; } } if (do_http) { self['_do_http_' + do_http]( method, uri, format_data(method, do_http, data, headers), headers, cookies, function(error, response) { if (cb_called) return; cb_called = true; if (is_callable(cb)) cb(error, response); } ); } } if (!do_http && is_callable(cb)) { cb(new EazyHttpException('No request made'), { status : 0, content : false, headers : {}, cookies : {} }); } }, _do_http_node: function(method, uri, data, headers, cookies, cb) { var self = this, do_request, timeout = parseInt(self.option('timeout')), follow_redirects = parseInt(self.option('follow_redirects')), return_type = String(self.option('return_type')).toLowerCase(); if ('bytes' === return_type) return_type = 'buffer'; // alias // node do_request = function(uri, redirect, protocol0, host0, port0, path0, headers0) { var request = null, error = null, opts, parts, protocol, host, port, path; if (redirect > follow_redirects) { cb(new EazyHttpException('Exceeded maximum redirects of ' + follow_redirects), { status : 0, content : false, headers : {}, cookies : {} }); return; } parts = parse_url(uri); host = parts['host']; if (!host || !host.length) { host = host0; } if (!host || !host.length) { cb(new EazyHttpException('No host'), { status : 0, content : false, headers : {}, cookies : {} }); return; } protocol = (null != parts['scheme']) ? parts['scheme'].toLowerCase() : (protocol0 || 'http'); port = (null != parts['port']) ? +parts['port'] : (port0 || ('https' === protocol ? 443 : 80)); path = (null != parts['path']) ? parts['path'] : '/'; if (!path.length) path = '/'; path = path_resolve(path, path0); path0 = path; path += (null != parts['query']) && parts['query'].length ? ('?' + parts['query']) : ''; if (0 < redirect) { method = 'GET'; data = null; if (HAS.call(headers, 'Content-Type')) delete headers['Content-Type']; if (HAS.call(headers, 'Content-Encoding')) delete headers['Content-Encoding']; if (HAS.call(headers, 'Content-Length')) delete headers['Content-Length']; if (!is_same_origin(host, host0, port, port0, protocol, protocol0)) { headers0 = null; cookies = {}; //if (HAS.call(headers, 'Cookie')) delete headers['Cookie']; if (HAS.call(headers, 'Authorization')) delete headers['Authorization']; if (HAS.call(headers, 'Proxy-Authorization')) delete headers['Proxy-Authorization']; } if (HAS.call(headers, 'Referer')) delete headers['Referer']; } if (HAS.call(headers, 'Cookie')) delete headers['Cookie']; headers = format_http_cookies(cookies, headers); opts = { 'method' : method, 'protocol' : protocol + ':', 'host' : host, 'port' : port, 'path' : path, 'headers' : headers, 'timeout' : 1000*timeout // ms }; try { request = ('https' === protocol ? https() : http()).request(opts); } catch (e) { request = null; error = e; } if (request) { request.on('response', function(response) { var m, status = +response.statusCode, body, received_headers, received_cookies; if ((0 < follow_redirects) && (301 <= status && status <= 308) && (response.headers['location']) && (m=response.headers['location'].match(/^\s*(\S+)/i))/* && (uri !== m[1])*/) { request.abort(); request.destroy(); //cookies = merge_cookies(cookies, received_cookies); cookies = {}; // do not send any cookies do_request( m[1], redirect+1, protocol, host, port, path0//, //extend(is_obj(headers0) ? headers0 : {}, parse_http_header(response.headers)) ); } else { received_headers = parse_http_header(response.headers); received_cookies = parse_http_cookies(received_headers['set-cookie']); body = []; response.on('data', function(chunk) { body.push('buffer' === return_type ? Buffer.from(chunk) : chunk); }); response.on('end', function() { cb(null, { status : status, content : 'buffer' === return_type ? (Buffer.concat(body)) : (body.join('')), headers : received_headers, cookies : received_cookies }); }); } }); request.on('timeout', function() { cb(new EazyHttpException('Request timeout after ' + timeout + ' seconds'), { status : 0, content : false, headers : {}, cookies : {} }); }); request.on('error', function(error) { cb(error, { status : 0, content : false, headers : {}, cookies : {} }); }); if ('POST' === method || 'PUT' === method || 'PATCH' === method) request.write(data); request.end(); } else { cb(error || new EazyHttpException('No http request'), { status : 0, content : false, headers : {}, cookies : {} }); } }; do_request(uri, 0); }, _do_http_fetch: function(method, uri, data, headers, cookies, cb) { var self = this, do_request, timeout = parseInt(self.option('timeout')), follow_redirects = parseInt(self.option('follow_redirects')), return_type = String(self.option('return_type')).toLowerCase(); if ('bytes' === return_type) return_type = 'buffer'; // alias // browser and node do_request = function(uri, redirect, protocol0, host0, port0, headers0) { var request = null, error = null, done = false, on_timeout = null, abort_on_timeout = null, parts, protocol, host, port, opts; if (redirect > follow_redirects) { cb(new EazyHttpException('Exceeded maximum redirects of ' + follow_redirects), { status : 0, content : false, headers : {}, cookies : {} }); return; } if (0 < redirect) { parts = parse_url(uri); host = parts['host']; if (!host || !host.length) host = host0; protocol = (null != parts['scheme']) ? parts['scheme'].toLowerCase() : (protocol0 || 'http'); port = (null != parts['port']) ? +parts['port'] : (port0 || ('https' === protocol ? 443 : 80)); method = 'GET'; data = null; if (HAS.call(headers, 'Content-Type')) delete headers['Content-Type']; if (HAS.call(headers, 'Content-Encoding')) delete headers['Content-Encoding']; if (HAS.call(headers, 'Content-Length')) delete headers['Content-Length']; if (!is_same_origin(host, host0, port, port0, protocol, protocol0)) { headers0 = null; cookies = {}; //if (HAS.call(headers, 'Cookie')) delete headers['Cookie']; if (HAS.call(headers, 'Authorization')) delete headers['Authorization']; if (HAS.call(headers, 'Proxy-Authorization')) delete headers['Proxy-Authorization']; } if (HAS.call(headers, 'Referer')) delete headers['Referer']; } if (HAS.call(headers, 'Cookie')) delete headers['Cookie']; headers = format_http_cookies(cookies, headers); opts = { 'method' : method, 'headers' : headers, 'redirect' : 0 < follow_redirects ? 'follow' : 'manual', 'keepalive' : false }; if ('POST' === method || 'PUT' === method || 'PATCH' === method) opts['body'] = data; if ('undefined' !== typeof(AbortController)) { abort_on_timeout = new AbortController(); opts['signal'] = abort_on_timeout.signal; } try { request = fetch(uri, opts); } catch (e) { request = null; error = e; } if (request) { on_timeout = setTimeout(function() { if (!done) { abort_on_timeout.abort(new EazyHttpException('Request timeout after ' + timeout + ' seconds')); } }, 1000*timeout); // ms request.then(function(response) { var m, p, status = +response.status, body, received_headers, received_cookies; done = true; if (on_timeout) clearTimeout(on_timeout); on_timeout = null; /*if ((0 < follow_redirects) && ((0 === status) || (301 <= status && status <= 308)) && response.url/* && (response.headers.get('location')) && (m=response.headers.get('location').match(/^\s*(\S+)/i)) && (uri !== m[1])* /) { // does not work p = parse_url(request.url); //cookies = merge_cookies(cookies, received_cookies); cookies = {}; // do not send any cookies, on browser they are sent do_request( /*m[1]* /response.url, redirect+1, p['scheme'], p['host'], p['port']//, //extend(is_obj(headers0) ? headers0 : {}, parse_http_header(response.headers)) ); } else {*/ received_headers = parse_http_header(response.headers); received_cookies = parse_http_cookies(received_headers['set-cookie']); body = 'buffer' === return_type ? response.arrayBuffer() : response.text(); body.then(function(content) { cb(null, { status : status, content : ('buffer' === return_type) && isNode ? Buffer.from(content) : content, headers : received_headers, cookies : received_cookies }); }).catch(function(error) { cb(error, { status : 0, content : false, headers : {}, cookies : {} }); }); /*}*/ }).catch(function(error) { done = true; if (on_timeout) clearTimeout(on_timeout); on_timeout = null; cb(error, { status : 0, content : false, headers : {}, cookies : {} }); }); } else { cb(error || new EazyHttpException('No fetch request'), { status : 0, content : false, headers : {}, cookies : {} }); } }; do_request(uri, 0); }, _do_http_xhr: function(method, uri, data, headers, cookies, cb) { var self = this, xhr = null, error = null, timeout = parseInt(self.option('timeout')), follow_redirects = parseInt(self.option('follow_redirects')), return_type = String(self.option('return_type')).toLowerCase(), ontimeout, onerror, onload; if ('bytes' === return_type) return_type = 'buffer'; // alias if (isXPCOM) { // Firefox XPCOM try { xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(); } catch (e) { xhr = null; error = e; } } else { // browser try { xhr = 'undefined' !== typeof XMLHttpRequest ? (new XMLHttpRequest()) : (new ActiveXObject('Microsoft.XMLHTTP')); } catch (e) { xhr = null; error = e; } } if (xhr) { //xhr.onreadystatechange // (0 /*UNSENT*/ === xhr.readyState) // (1 /*OPENED*/ === xhr.readyState) // (2 /*HEADERS_RECEIVED*/ === xhr.readyState) // (3 /*LOADING*/ === xhr.readyState) // (4 /*DONE*/ === xhr.readyState) ontimeout = function() { cb(new EazyHttpException('Request timeout after ' + timeout + ' seconds'), { status : 0, content : false, headers : {}, cookies : {} }); }; onerror = function() { cb(new EazyHttpException('Request error'), { status : 0, content : false, headers : {}, cookies : {} }); }; onload = function() { if (4/*DONE*/ === xhr.readyState) { var status = +xhr.status, content = 'buffer' === return_type ? (new Uint8Array(xhr.response)) : xhr.responseText, received_headers = parse_http_header(xhr.getAllResponseHeaders()), received_cookies = parse_http_cookies(received_headers['set-cookie']); cb(null, { status : status, content : content, headers : received_headers, cookies : received_cookies }); } else { cb(new EazyHttpException('Request incomplete'), { status : 0, content : false, headers : {}, cookies : {} }); } }; if ('function' === typeof xhr.addEventListener) { xhr.addEventListener('timeout', ontimeout); xhr.addEventListener('error', onerror); xhr.addEventListener('load', onload); } else { xhr.ontimeout = ontimeout; xhr.onerror = onerror; xhr.onload = onload; } xhr.responseType = 'buffer' === return_type ? 'arraybuffer' : 'text'; xhr.timeout = 1000*timeout; // ms xhr.open(method, uri, true/*, user, pass*/); // 'true' makes the request asynchronous headers = format_http_cookies(cookies, headers); for (var name in headers) { if (HAS.call(headers, name)) { try { xhr.setRequestHeader(name, headers[name]); } catch (e) { /*pass*/ } } } xhr.send(data); } else { cb(error || new EazyHttpException('No XMLHttpRequest request'), { status : 0, content : false, headers : {}, cookies : {} }); } }, _do_http_iframe: function(method, uri, data, headers, cookies, cb) { var self = this, form = null, iframe = null, error = null, uid, timeout = parseInt(self.option('timeout')), follow_redirects = parseInt(self.option('follow_redirects')), return_type = String(self.option('return_type')).toLowerCase(), on_timeout = null, finish = null, done = false; if ('bytes' === return_type) return_type = 'buffer'; // alias // browser try { form = document.createElement('form'); iframe = document.createElement('iframe'); } catch (e) { form = null; iframe = null; error = e; } if (form && iframe) { finish = function() { if (iframe) { iframe.onload = iframe.onerror = null; iframe.remove(); iframe = null; } if (form) { form.remove(); form = null; } }; on_timeout = setTimeout(function() { if (!done) { finish(); cb(new EazyHttpException('Request timeout after ' + timeout + ' seconds'), { status : 0, content : false, headers : {}, cookies : {} }); } }, 1000*timeout); // ms iframe.onerror = function() { done = true; if (on_timeout) clearTimeout(on_timeout); on_timeout = null; cb(new EazyHttpException('Request error'), { status : 0, content : false, headers : {}, cookies : {} }); }; iframe.onload = function() { done = true; if (on_timeout) clearTimeout(on_timeout); on_timeout = null; var doc = iframe.contentDocument || iframe.contentWindow.document, content = (doc && doc.body ? (-1 === doc.contentType.toLowerCase().indexOf('text/html') ? doc.body.innerText : doc.body.innerHTML) : '') || '', received_headers = doc ? {'content-type': doc.contentType + '; charset=' + doc.characterSet, 'last-modified': (new Date(doc.lastModified)).toUTCString()} : {}, received_cookies = doc && doc.cookie && doc.cookie.length ? parse_http_cookies(doc.cookie.split(';'), true) : {}; finish(); cb(null, { status : 200, content : content, headers : received_headers, cookies : received_cookies }); }; uid = String(++ID) + '_' + Date.now(); iframe.id = '_eazy_http_iframe_' + uid; iframe.name = iframe.id; iframe.style.height = '0px'; iframe.style.width = '0px'; iframe.style.overflow = 'hidden'; form.id = '_eazy_http_form_' + uid; form.style.height = '0px'; form.style.width = '0px'; form.style.overflow = 'hidden'; form.action = uri; form.method = method; form.enctype = /*HAS.call(headers, 'Content-Type') ? headers['Content-Type'] : */'application/x-www-form-urlencoded'; form.target = iframe.id; if (is_obj(data)) { data = flatten(data, {}); array_keys(data).forEach(function(key) { var input, value = data[key]; if (('undefined' !== typeof(File)) && (value instanceof File)) { // File if ('undefined' !== typeof(DataTransfer)) { var dt = new DataTransfer(); dt.items.add(value); input = document.createElement('input'); input.type = 'file'; input.name = key; input.files = dt.files; form.enctype = 'multipart/form-data'; } else { // bypass return; } } else { // default input = document.createElement('input'); input.type = 'hidden'; input.name = key; input.value = String(value); } form.appendChild(input); }); } document.body.appendChild(form); document.body.appendChild(iframe); try { form.submit(); } catch (e) { error = e; } if (error) { finish(); cb(error || new EazyHttpException('Form submit failed'), { status : 0, content : false, headers : {}, cookies : {} }); } } else { cb(error || new EazyHttpException('No iframe request'), { status : 0, content : false, headers : {}, cookies : {} }); } } }; function EazyHttpException(message) { Error.call(this, message); this.message = message; this.name = 'EazyHttpException'; } EazyHttpException[PROTO] = Object.create(Error[PROTO]); EazyHttpException[PROTO].constructor = EazyHttpException; EazyHttp.Exception = EazyHttpException; // utils --------------------------------- function http() { if (isNode) { if ('undefined' === typeof(http.module)) { try { http.module = require('node:http'); } catch (e) { http.module = null; } if (null == http.module) { try { http.module = require('http'); } catch (e) { http.module = null; } } } return http.module; } return null; } function https() { if (isNode) { if ('undefined' === typeof(https.module)) { try { https.module = require('node:https'); } catch (e) { https.module = null; } if (null == https.module) { try { https.module = require('https'); } catch (e) { https.module = null; } } } return https.module; } return null; } function is_same_origin(host, host2, port, port2, protocol, protocol2) { if ((port !== port2) || (protocol !== protocol2)) return false; host = host.toLowerCase(); host2 = host2.toLowerCase(); if (host === host2) return true; // same host //if (('.' + host) === host2.slice(-host.length-1)) return true; // host2 is subdomain of host if (('.' + host2) === host.slice(-host2.length-1)) return true; // host is subdomain of host2 return false; } function path_resolve(path, basepath) { if (('/' === path.slice(0, 1)) || !basepath) return path; // absolute if ('/' === basepath) return basepath + path; // from root var p = path, b = basepath, absolute = false, trailing = false, parts, base; if ('/' === b.slice(0, 1)) { absolute = true; b = b.slice(1); } if ('/' === b.slice(-1)) { b = b.slice(0, -1); } if ('/' === p.slice(0, 1)) { p = p.slice(1); } if ('/' === p.slice(-1)) { trailing = true; p = p.slice(0, -1); } //if (!p.length || !b.length) return (absolute ? '/' : '' ) + path; parts = p.split('/'); base = b.split('/'); while (parts.length) { if (!base.length) return path; if ('.' === parts[0]) { parts.shift(); // same dir } else if ('..' === parts[0]) { parts.shift(); base.pop(); // dir up } else { if (parts[0] === base[base.length-1]) base.pop(); // remove duplicate break; // done } } path = (absolute ? '/' : '') + base.join('/') + '/' + parts.join('/'); if (trailing && ('/' !== path.slice(-1))) path += '/'; return path; } function format_data(method, do_http, data, headers) { if ('POST' === method || 'PUT' === method || 'PATCH' === method) { // http data can only be: string, Uint8Array, Buffer // fetch data can only be: string, FormData, URLSearchParams, ArrayBuffer, DataView, TypedArray, Blob, File, ReadableStream // xhr data can only be: string, FormData, URLSearchParams, ArrayBuffer, DataView, TypedArray, Blob // iframe data can only be: Object (serialized into 'application/x-www-form-urlencoded' or 'multipart/form-data' if contains File entries) if (is_string(data)) { // String /*pass*/ } else if (('undefined' !== typeof(FormData)) && (data instanceof FormData)) { // FormData if ('iframe' === do_http) { data = (function(o) { data.keys().forEach(function(key) { var value = data.getAll(key); o[key] = 1 < value.length ? value : (value[0] || null); }); return o; })({}); } /*pass*/ } else if (('undefined' !== typeof(URLSearchParams)) && (data instanceof URLSearchParams)) { // URLSearchParams if ('http' === do_http) { data = data.toString(); } else if ('iframe' === do_http) { data = (function(o) { data.forEach(function(value, key) {o[key] = value;}); return o; })({}); } headers['Content-Type'] = 'application/x-www-form-urlencoded'; /*pass*/ } else if (('undefined' !== typeof(ArrayBuffer)) && (data instanceof ArrayBuffer)) { // ArrayBuffer if (('http' === do_http) && ('undefined' !== typeof(Buffer))) { data = Buffer.from(data); } /*pass*/ } else if (('undefined' !== typeof(DataView)) && (data instanceof DataView)) { // DataView /*pass*/ } else if ( (('undefined' !== typeof(BigInt64Array)) && (data instanceof BigInt64Array)) || (('undefined' !== typeof(BigUint64Array)) && (data instanceof BigUint64Array)) ) { // TypedArray /*pass*/ } else if ( (('undefined' !== typeof(Uint8Array)) && (data instanceof Uint8Array)) || (('undefined' !== typeof(Int8Array)) && (data instanceof Int8Array)) || (('undefined' !== typeof(Uint16Array)) && (data instanceof Uint16Array)) || (('undefined' !== typeof(Int16Array)) && (data instanceof Int16Array)) || (('undefined' !== typeof(Uint32Array)) && (data instanceof Uint32Array)) || (('undefined' !== typeof(Int32Array)) && (data instanceof Int32Array)) || (('undefined' !== typeof(Float16Array)) && (data instanceof Float16Array)) || (('undefined' !== typeof(Float32Array)) && (data instanceof Float32Array)) || (('undefined' !== typeof(Float64Array)) && (data instanceof Float64Array)) ) { // TypedArray if (('http' === do_http) && ('undefined' !== typeof(Uint8Array))) { data = new Uint8Array(data); } /*pass*/ } else if (('undefined' !== typeof(Blob)) && (data instanceof Blob)) { // Blob /*pass*/ } else if (('undefined' !== typeof(File)) && (data instanceof File)) { // File /*pass*/ } else if (('undefined' !== typeof(ReadableStream)) && (data instanceof ReadableStream)) { // ReadableStream /*pass*/ } else if (('undefined' !== typeof(Buffer)) && (data instanceof Buffer)) { // Buffer /*pass*/ } else if (is_obj(data)) { if ('iframe' !== do_http) { data = http_build_query(data, '&'); } headers['Content-Type'] = 'application/x-www-form-urlencoded'; } else { data = ''; } return data; } return null; } function merge_cookies(cookies, setCookies) { // TODO: take care of secure, samesite, .. cookie flags var i, n, names = array_keys(setCookies), setCookie; for (i=0,n=names.length; i<n; ++i) { setCookie = setCookies[names[i]]; if (!HAS.call(cookies, setCookie.name) || (cookies[setCookie.name].value !== setCookie.value)) { cookies[setCookie.name] = setCookie; } } return cookies; } function parse_http_header(responseHeader) { var responseHeaders = {}, name, value, multiple_headers = ['set-cookie'], lines, parts, line, i, n; // return lowercase headers as in spec if (('undefined' !== typeof Headers) && (responseHeader instanceof Headers)) { responseHeader.forEach(function(value, name) { name = /*ucwords(*/trim(name).toLowerCase()/*, '-')*/; value = trim(String(value)); if (-1 !== multiple_headers.indexOf(name)) { if (HAS.call(responseHeaders, name)) responseHeaders[name].push(value); else responseHeaders[name] = [value]; } else { responseHeaders[name] = value; } }); value = responseHeader.getSetCookie(); if (value.length) responseHeaders['set-cookie'] = value; } else if (is_obj(responseHeader)) { for (name in responseHeader) { if (HAS.call(responseHeader, name)) { name = /*ucwords(*/trim(name).toLowerCase()/*, '-')*/; value = trim(String(responseHeader[name])); if (-1 !== multiple_headers.indexOf(name)) { if (HAS.call(responseHeaders, name)) responseHeaders[name].push(value); else responseHeaders[name] = [value]; } else { responseHeaders[name] = value; } } } } else { if (is_string(responseHeader)) responseHeader = responseHeader.split(/[\r\n]+/g); if (is_array(responseHeader) && responseHeader.length) { for (i=0,n=responseHeader.length; i<n; ++i) { line = responseHeader[i]; if (trim(line).length) { parts = line.split(':', 2); if (parts.length > 1) { name = /*ucwords(*/trim(parts[0]).toLowerCase()/*, '-')*/; value = trim(String(parts[1])); if (-1 !== multiple_headers.indexOf(name)) { if (HAS.call(responseHeaders, name)) responseHeaders[name].push(value); else responseHeaders[name] = [value]; } else { responseHeaders[name] = value; } } } } } } return responseHeaders; } function parse_http_cookies(setCookies, onlyNameValue) { var cookies = {}, cookie, setCookies, i, n; if (setCookies && is_array(setCookies) && setCookies.length) { for (i=0,n=setCookies.length; i<n; ++i) { cookie = parse_cookie(setCookies[i], false, onlyNameValue); if (is_obj(cookie)) cookies[cookie.name] = cookie; } } return cookies; } function format_http_cookies(cookies, headers) { var names = is_obj(cookies) ? array_keys(cookies) : []; if (names.length) { for (var i=0,n=names.length,cookie_str,valid_cookies=[]; i<n; ++i) { if (is_obj(cookies[names[i]])) { cookie_str = format_cookie(cookies[names[i]], false); if (cookie_str.length) { valid_cookies.push(cookie_str); } } } if (valid_cookies.length) { headers['Cookie'] = (HAS.call(headers, 'Cookie') ? (String(headers['Cookie']) + '; ') : '') + valid_cookies.join('; '); } } return headers; } function parse_cookie(s, isRaw, onlyNameValue) { var cookie, parts, part, i, n, name, value, expires; cookie = {}; parts = String(s).split(';'); for (i=0,n=parts.length; i<n; ++i) parts[i] = parts[i].split('=', 2); part = parts.shift(); name = !isRaw ? urldecode(trim(part[0])) : trim(part[0]); value = (null != part[1]) ? (!isRaw ? urldecode(trim(part[1])) : trim(part[1])) : null; cookie['name'] = name; cookie['value'] = value; if (onlyNameValue) return cookie; cookie = { 'isRaw' : isRaw, 'name' : cookie['name'], 'value' : cookie['value'], 'expires' : 0, 'path' : '/', 'domain' : null, 'secure' : false, 'httponly' : false, 'samesite' : null, 'partitioned' : false }; for (i=0,n=parts.length; i<n; ++i) { part = parts[i]; name = trim(part[0]).toLowerCase(); value = (null != part[1]) ? trim(part[1]) : true; cookie[name] = value; } expires = new Date(/^[0-9]+$/.test(cookie['expires']) ? (1000*parseInt(cookie['expires'])) : cookie['expires']); cookie['expires'] = expires.toUTCString(); if ((null != cookie['max-age']) && ((+cookie['max-age']) > 0 || expires.getTime() > Date.now())) { cookie['expires'] = (new Date(Date.now() + 1000*parseInt(cookie['max-age']))).toUTCString(); } return cookie; } function format_cookie(cookie, toSet) { var RESERVED_CHARS_LIST = "=,; \t\r\n\v\f", RESERVED_CHARS_FROM = ['=', ',', ';', ' ', "\t", "\r", "\n", "\v", "\f"], RESERVED_CHARS_TO = ['%3D', '%2C', '%3B', '%20', '%09', '%0D', '%0A', '%0B', '%0C'], isRaw, s, expires, maxAge; if ((null == cookie) || !is_obj(cookie)) return ''; if ((null == cookie['name'])) return ''; isRaw = (true === cookie['isRaw']); s = ''; if (isRaw) { s = String(cookie['name']); } else { s = str_replace(RESERVED_CHARS_FROM, RESERVED_CHARS_TO, String(cookie['name'])); } s += '='; if ((null == cookie['value']) || !String(cookie['value']).length) { if (toSet) { s += 'deleted; Expires=' + (new Date(Date.now() - 1000*31536001)).toUTCString() + '; Max-Age=0'; } else { return ''; } } else { s += isRaw ? String(cookie['value']) : rawurlencode(String(cookie['value'])); if (is_number(cookie['expires'])) cookie['expires'] = new Date(1000*cookie['expires']); expires = null != cookie['expires'] ? cookie['expires'] : (new Date(Date.now() + 1000*60)); if (!(expires instanceof Date)) expires = new Date(expires); maxAge = Math.floor(Math.max(0, expires.getTime()-Date.now())/1000); if (toSet) { s += '; Expires=' + expires.toUTCString() + '; Max-Age=' + maxAge; } else if (!maxAge) { return ''; } } if (toSet) { if ((null != cookie['path'])) { s += '; Path=' + cookie['path']; } if ((null != cookie['domain'])) { s += '; Domain=' + cookie['domain']; } if (cookie['secure']) { s += '; Secure'; } if (cookie['httponly']) { s += '; HttpOnly'; } if ((null != cookie['samesite'])) { s += '; SameSite=' + cookie['samesite']; } if (cookie['partitioned']) { s += '; Partitioned'; } } return s; } function is_string(x) { return ('[object String]' === toString.call(x)) || ('string' === typeof(x)); } function is_array(x) { return '[object Array]' === toString.call(x); } function is_obj(x) { return '[object Object]' === toString.call(x); } function is_number(x) { return ('number' === typeof(x)) || (x instanceof Number); } function is_callable(x) { return 'function' === typeof(x); } function array_keys(o) { if ('function' === typeof Object.keys) { return Object.keys(o); } var v, k, l; if (is_array(o)) { v = new Array(l=o.length); for (k=0; k<l; ++k) { v[k] = String(k); } } else { v = []; for (k in o) { if (HAS.call(o, k)) v.push(k); } } return v; } function array_values(o) { if (is_array(o)) return o; if ('function' === typeof Object.values) { return Object.values(o); } var v = [], k; for (k in o) { if (HAS.call(o, k)) v.push(o[k]); } return v; } function is_numeric_array(o) { if (is_array(o)) return true; if (is_obj(o)) { var k = array_keys(o), i, l = k.length; for (i=0; i<l; ++i) { if (i !== +k[i]) return false; } return true; } return false; } function extend(o1, o2, deep) { var k, v; deep = true === deep; if (o2) { for (k in o2) { if (!HAS.call(o2,k)) continue; v = o2[k]; if (is_number(v)) o1[k] = 0+v; else if (is_string(v)) o1[k] = v.slice(); else if (is_array(v)) o1[k] = deep ? extend(v.length ? new Array(v.length) : [], v, deep) : v; else if (is_obj(v)) o1[k] = deep ? extend({}, v, deep) : v; else o1[k] = v; } } return o1; } var trim = String[PROTO].trim ? function(s) {return String(s).trim();} : function(s) {return String(s).replace(/^\s+|\s+$/g, '');}; function ucwords(str, sep) { var words = String(str).split(sep), i, n; str = ''; for (i=0,n=words.length; i<n; ++i) { str += words[i].charAt(0).toUpperCase() + words[i].slice(1); } return str; } function str_replace(from, to, str) { for (var i=0,n=from.length; i<n; ++i) { str = str.split(from[i]).join(to[i]); } return str; } function rawurldecode(str) { return decodeURIComponent(String(str)); } function rawurlencode(str) { return encodeURIComponent(String(str)) .split('!').join('%21') .split("'").join('%27') .split('(').join('%28') .split(')').join('%29') .split('*').join('%2A') //.split('~').join('%7E') ; } function urldecode(str) { return rawurldecode(String(str).split('+').join('%20')); } function urlencode(str) { return rawurlencode(str).split('%20').join('+'); } // adapted from https://github.com/kvz/phpjs var uriParser = { php: /^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/\/?)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // Added one optional slash to post-scheme to catch file:/// (should restrict this) }, uriComponent = ['source', 'scheme', 'authority', 'userInfo', 'user', 'pass', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'fragment'] ; function parse_url(str, component, mode) { var uri = null, m, i; if ('undefined' !== typeof(URL)) { try { m = new URL(str); } catch (e) { m = null; } if (m) { uri = {}; if (m.protocol) uri['scheme'] = m.protocol.slice(0, -1); if (m.username) uri['user'] = m.username; if (m.password) uri['pass'] = m.password; if (m.hostname) uri['host'] = m.hostname; if (m.port && m.port.length) uri['port'] = m.port; if (m.pathname && m.pathname.length) uri['path'] = m.pathname; else uri['path'] = ''; if (m.search && m.search.length) uri['query'] = m.search.slice(1); else uri['query'] = ''; if (m.hash && m.hash.length) uri['fragment'] = m.hash.slice(1); else uri['fragment'] = ''; } } if (!uri) { m = uriParser[mode || 'php'].exec(str); i = uriComponent.length; uri = {}; while (i--) if (i && m[i]) uri[uriComponent[i]] = m[i]; } if (HAS.call(uri, 'port')) uri['port'] = parseInt(uri['port'], 10); if (component) { return uri[component.replace('PHP_URL_', '').toLowerCase()] || null; } return uri; } function parse_str(str) { /*if ('undefined' !== typeof(URLSearchParams)) { // NOTE: nesting is not supported var params; try { params = new URLSearchParams(str); } catch (e) { params = null; } if (params) return params; }*/ var strArr = str.replace(/^&+|&+$/g, '').split('&'), sal = strArr.length, i, j, ct, p, lastObj, obj, chr, tmp, key, value, postLeftBracketPos, keys, keysLen, lastkey, array = {}, possibleLists = [], prevkey, prevobj ; for (i=0; i<sal; ++i) { tmp = strArr[i].split('='); key = rawurldecode(trim(tmp[0])); value = (tmp.length < 2) ? '' : rawurldecode(trim(tmp[1])); j = key.indexOf('\x00'); if (j > -1) key = key.slice(0, j); if (key && ('[' !== key.charAt(0))) { keys = []; postLeftBracketPos = 0; for (j=0; j<key.length; ++j) { if (('[' === key.charAt(j)) && !postLeftBracketPos) { postLeftBracketPos = j + 1; } else if (']' === key.charAt(j)) { if (postLeftBracketPos) { if (!keys.length) { keys.push(key.slice(0, postLeftBracketPos - 1)); } keys.push(key.substr(postLeftBracketPos, j - postLeftBracketPos)); postLeftBracketPos = 0; if ('[' !== key.charAt(j + 1)) break; } } } if (!keys.length) keys = [key]; for (j=0; j<keys[0].length; ++j) { chr = keys[0].charAt(j); if (' ' === chr || '.' === chr || '[' === chr) { keys[0] = keys[0].substr(0, j) + '_' + keys[0].substr(j + 1); } if ('[' === chr) break; } obj = array; key = null; lastObj = obj; lastkey = keys.length ? trim(keys[ keys.length-1 ].replace(/^['"]|['"]$/g, '')) : null; for (j=0, keysLen=keys.length; j<keysLen; ++j) { prevkey = key; key = keys[j].replace(/^['"]|['"]$/g, ''); prevobj = lastObj; lastObj = obj; if ('' !== trim(key) || 0 === j) { if (!HAS.call(obj, key)) obj[key] = (j+1 === keysLen-1) && (''===lastkey) ? [] : {}; obj = obj[key]; } else { // To insert new dimension /*ct = -1; for (p in obj) { if (HAS.call(obj,p)) { if (+p > ct && p.match(/^\d+$/g)) { ct = +p; } } } key = ct + 1;*/ key = true; } } if (true === key) { lastObj.push(value); } else { if (key == +key) possibleLists.push({key:prevkey, obj:prevobj}); lastObj[key] = value; } } } for (i=possibleLists.length-1; i>=0; --i) { // safe to pass multiple times same obj, it is possible obj = possibleLists[i].key ? possibleLists[i].obj[possibleLists[i].key] : possibleLists[i].obj; if (is_numeric_array(obj)) { obj = array_values(obj); if (possibleLists[i].key) possibleLists[i].obj[possibleLists[i].key] = obj; else array = obj; } } return array; } function flatten(input, output, prefix) { if (is_obj(input) || is_array(input)) { for (var k=array_keys(input),i=0,n=k.length; i<n; ++i) { var key = k[i], val = input[key], name = String((null == prefix) ? key : (prefix+'['+key+']')); if (is_obj(val) || is_array(val)) output = flatten(val, output, name); else output[name] = val; } return output; } return input; } function http_build_query_helper(key, val, arg_separator, PHP_QUERY_RFC3986) { var k, tmp, encode = PHP_QUERY_RFC3986 ? rawurlencode : urlencode; if (true === val) val = "1"; else if (false === val) val = "0"; if (null != val) { if ('object' === typeof val) { tmp = []; for (k in val) { if (HAS.call(val, k) && (null != val[k])) { tmp.push(http_build_query_helper(key + "[" + k + "]", val[k], arg_separator, PHP_QUERY_RFC3986)); } } return tmp.join(arg_separator); } else { return encode(key) + "=" + encode(val); } } else { return ''; } } function http_build_query(data, arg_separator, PHP_QUERY_RFC3986) { if ('undefined' !== typeof(URLSearchParams)) { // NOTE: nesting is handled via flatten var params; try { params = new URLSearchParams(flatten(data, {})); } catch (e) { params = null; } if (params) { params = params.toString(); if ('&' !== arg_separator) params = params.split('&').join(arg_separator); return params; } } var value, key, query, tmp = []; if (arguments.length < 2) arg_separator = "&"; if (arguments.length < 3) PHP_QUERY_RFC3986 = false; for (key in data) { if (!HAS.call(data, key)) continue; value = data[key]; query = http_build_query_helper(key, value, arg_separator, PHP_QUERY_RFC3986); if ('' != query) tmp.push(query); } return tmp.join(arg_separator); } // export it EazyHttp.VERSION = VERSION; return EazyHttp; });