total4
Version:
Total.js framework v4
1,738 lines (1,423 loc) • 173 kB
JavaScript
'use strict';
const Dns = require('dns');
const Url = require('url');
const Http = require('http');
const Https = require('https');
const Path = require('path');
const Fs = require('fs');
const Crypto = require('crypto');
const Zlib = require('zlib');
const Tls = require('tls');
const Net = require('net');
const KeepAlive = new Http.Agent({ keepAlive: true, timeout: 60000 });
const KeepAliveHttps = new Https.Agent({ keepAlive: true, timeout: 60000 });
const SKIPBODYENCRYPTOR = { ':': 1, '"': 1, '[': 1, ']': 1, '\'': 1, '_': 1, '{': 1, '}': 1, '&': 1, '=': 1, '+': 1, '-': 1, '\\': 1, '/': 1, ',': 1 };
const REG_EMPTYBUFFER = /\0|%00|\\u0000/g;
const REG_EMPTYBUFFER_TEST = /\0|%00|\\u0000/;
const REG_XSS = /<.*>/;
const REG_SQLINJECTION = /'(''|[^'])*'|\b(ALTER|CREATE|DELETE|DROP|EXEC(UTE){0,1}|INSERT( +INTO){0,1}|MERGE|SELECT|UPDATE|UNION( +ALL){0,1})\b/;
const REG_GUID = (/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i);
const CT_OCTET = 'application/octet-stream';
const COMPRESS = { gzip: 1, deflate: 1 };
const CONCAT = [null, null];
const SKIPPORTS = { '80': 1, '443': 1 };
const REGISARR = /\[\d+\]|\[\]$/;
const REGREPLACEARR = /\[\]/g;
const REG_JPG = /jfif|exif/;
const REG_WEBP = /jfif|webp|exif/;
const REG_SVG = /xml|svg/i;
const REG_WIN = /\\/g;
const COMPARER = function(a, b) {
if (!a && b)
return -1;
if (a && !b)
return 1;
if (a === b)
return 0;
return global.Intl.Collator().compare(a, b);
};
const COMPARER_DESC = function(a, b) {
if (!a && b)
return 1;
if (a && !b)
return -1;
if (a === b)
return 0;
var val = global.Intl.Collator().compare(a, b);
return val ? val * -1 : 0;
};
if (!global.framework_utils)
global.framework_utils = exports;
const Internal = require('./internal');
var regexpSTATIC = /\.\w{2,8}($|\?)+/;
const regexpTRIM = /^[\s]+|[\s]+$/g;
const regexpDATE = /(\d{1,2}\.\d{1,2}\.\d{4})|(\d{4}-\d{1,2}-\d{1,2})|(\d{1,2}:\d{1,2}(:\d{1,2})?)/g;
const regexpDATEFORMAT = /YYYY|yyyy|YY|yy|MMMM|MMM|MM|M|dddd|DDDD|DDD|ddd|DD|dd|D|d|HH|H|hh|h|mm|m|ss|s|a|ww|w/g;
const regexpSTRINGFORMAT = /\{\d+\}/g;
const regexpPATH = /\\/g;
const regexpTags = /<\/?[^>]+(>|$)/g;
const regexpDiacritics = /[^\u0000-\u007e]/g;
const regexpUA = /[a-z]+/gi;
const regexpXML = /\w+=".*?"/g;
const regexpDECODE = /&#?[a-z0-9]+;/g;
const regexpARG = /\{{1,2}[a-z0-9_$.-\s]+\}{1,2}/gi;
const regexpINTEGER = /(^-|\s-)?[0-9]+/g;
const regexpFLOAT = /(^-|\s-)?[0-9.,]+/g;
const regexpSEARCH = /[^a-zA-Zá-žÁ-Ž\d\s:]/g;
const regexpTERMINAL = /[\w\S]+/g;
const regexpCONFIGURE = /\[\w+\]/g;
const regexpY = /y/g;
const regexpN = /\n/g;
const regexpCHARS = /\W|_/g;
const regexpCHINA = /[\u3400-\u9FBF]/;
const regexpLINES = /\n|\r|\r\n/;
const regexpBASE64 = /^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$/;
const regexpBASE64_2 = /^|,([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$/;
const ENCODING = 'utf8';
const NEWLINE = '\r\n';
const isWindows = require('os').platform().substring(0, 3).toLowerCase() === 'win';
const DIACRITICSMAP = {};
const ALPHA_INDEX = { '<': '<', '>': '>', '"': '"', '&apos': '\'', '&': '&', '<': '<', '>': '>', '"': '"', ''': '\'', '&': '&' };
const STREAMPIPE = { end: false };
const CT = 'Content-Type';
const CRC32TABLE = '00000000,77073096,EE0E612C,990951BA,076DC419,706AF48F,E963A535,9E6495A3,0EDB8832,79DCB8A4,E0D5E91E,97D2D988,09B64C2B,7EB17CBD,E7B82D07,90BF1D91,1DB71064,6AB020F2,F3B97148,84BE41DE,1ADAD47D,6DDDE4EB,F4D4B551,83D385C7,136C9856,646BA8C0,FD62F97A,8A65C9EC,14015C4F,63066CD9,FA0F3D63,8D080DF5,3B6E20C8,4C69105E,D56041E4,A2677172,3C03E4D1,4B04D447,D20D85FD,A50AB56B,35B5A8FA,42B2986C,DBBBC9D6,ACBCF940,32D86CE3,45DF5C75,DCD60DCF,ABD13D59,26D930AC,51DE003A,C8D75180,BFD06116,21B4F4B5,56B3C423,CFBA9599,B8BDA50F,2802B89E,5F058808,C60CD9B2,B10BE924,2F6F7C87,58684C11,C1611DAB,B6662D3D,76DC4190,01DB7106,98D220BC,EFD5102A,71B18589,06B6B51F,9FBFE4A5,E8B8D433,7807C9A2,0F00F934,9609A88E,E10E9818,7F6A0DBB,086D3D2D,91646C97,E6635C01,6B6B51F4,1C6C6162,856530D8,F262004E,6C0695ED,1B01A57B,8208F4C1,F50FC457,65B0D9C6,12B7E950,8BBEB8EA,FCB9887C,62DD1DDF,15DA2D49,8CD37CF3,FBD44C65,4DB26158,3AB551CE,A3BC0074,D4BB30E2,4ADFA541,3DD895D7,A4D1C46D,D3D6F4FB,4369E96A,346ED9FC,AD678846,DA60B8D0,44042D73,33031DE5,AA0A4C5F,DD0D7CC9,5005713C,270241AA,BE0B1010,C90C2086,5768B525,206F85B3,B966D409,CE61E49F,5EDEF90E,29D9C998,B0D09822,C7D7A8B4,59B33D17,2EB40D81,B7BD5C3B,C0BA6CAD,EDB88320,9ABFB3B6,03B6E20C,74B1D29A,EAD54739,9DD277AF,04DB2615,73DC1683,E3630B12,94643B84,0D6D6A3E,7A6A5AA8,E40ECF0B,9309FF9D,0A00AE27,7D079EB1,F00F9344,8708A3D2,1E01F268,6906C2FE,F762575D,806567CB,196C3671,6E6B06E7,FED41B76,89D32BE0,10DA7A5A,67DD4ACC,F9B9DF6F,8EBEEFF9,17B7BE43,60B08ED5,D6D6A3E8,A1D1937E,38D8C2C4,4FDFF252,D1BB67F1,A6BC5767,3FB506DD,48B2364B,D80D2BDA,AF0A1B4C,36034AF6,41047A60,DF60EFC3,A867DF55,316E8EEF,4669BE79,CB61B38C,BC66831A,256FD2A0,5268E236,CC0C7795,BB0B4703,220216B9,5505262F,C5BA3BBE,B2BD0B28,2BB45A92,5CB36A04,C2D7FFA7,B5D0CF31,2CD99E8B,5BDEAE1D,9B64C2B0,EC63F226,756AA39C,026D930A,9C0906A9,EB0E363F,72076785,05005713,95BF4A82,E2B87A14,7BB12BAE,0CB61B38,92D28E9B,E5D5BE0D,7CDCEFB7,0BDBDF21,86D3D2D4,F1D4E242,68DDB3F8,1FDA836E,81BE16CD,F6B9265B,6FB077E1,18B74777,88085AE6,FF0F6A70,66063BCA,11010B5C,8F659EFF,F862AE69,616BFFD3,166CCF45,A00AE278,D70DD2EE,4E048354,3903B3C2,A7672661,D06016F7,4969474D,3E6E77DB,AED16A4A,D9D65ADC,40DF0B66,37D83BF0,A9BCAE53,DEBB9EC5,47B2CF7F,30B5FFE9,BDBDF21C,CABAC28A,53B39330,24B4A3A6,BAD03605,CDD70693,54DE5729,23D967BF,B3667A2E,C4614AB8,5D681B02,2A6F2B94,B40BBE37,C30C8EA1,5A05DF1B,2D02EF8D'.split(',').map(s => parseInt(s, 16));
const PROXYBLACKLIST = { 'localhost': 1, '127.0.0.1': 1, '0.0.0.0': 1 };
const PROXYOPTIONS = { headers: {}, method: 'CONNECT', agent: false };
const PROXYTLS = { headers: {}};
const PROXYOPTIONSHTTP = {};
const REG_ROOT = /@\{#\}(\/)?/g;
const REG_NOREMAP = /@\{noremap\}(\n)?/g;
const REG_REMAP = /\shref=".*?"|src=".*?"/gi;
const REG_AJAX = /('|")+(!)?(GET|POST|PUT|DELETE|PATCH)\s(\(.*?\)\s)?\//g;
const REG_URLEXT = /^(https|http|wss|ws|file):\/\/|\/\/[a-z0-9]|[a-z]:|javascript:|#|@\{|'|"|\(/i;
const REG_TEXTAPPLICATION = /text|application/i;
const REG_TIME = /am|pm/i;
const REG_XMLKEY = /\[|\]|:|\.|_/g;
const REG_HEADERPARSER = /(name|filename)=".*?"|content-type:\s[a-z0-9-./+]+/ig;
const HEADEREND = Buffer.from('\r\n\r\n', 'ascii');
exports.MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
exports.DAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
var DIACRITICS=[{b:' ',c:'\u00a0'},{b:'0',c:'\u07c0'},{b:'A',c:'\u24b6\uff21\u00c0\u00c1\u00c2\u1ea6\u1ea4\u1eaa\u1ea8\u00c3\u0100\u0102\u1eb0\u1eae\u1eb4\u1eb2\u0226\u01e0\u00c4\u01de\u1ea2\u00c5\u01fa\u01cd\u0200\u0202\u1ea0\u1eac\u1eb6\u1e00\u0104\u023a\u2c6f'},{b:'AA',c:'\ua732'},{b:'AE',c:'\u00c6\u01fc\u01e2'},{b:'AO',c:'\ua734'},{b:'AU',c:'\ua736'},{b:'AV',c:'\ua738\ua73a'},{b:'AY',c:'\ua73c'},{b:'B',c:'\u24b7\uff22\u1e02\u1e04\u1e06\u0243\u0181'},{b:'C',c:'\u24b8\uff23\ua73e\u1e08\u0106C\u0108\u010a\u010c\u00c7\u0187\u023b'},{b:'D',c:'\u24b9\uff24\u1e0a\u010e\u1e0c\u1e10\u1e12\u1e0e\u0110\u018a\u0189\u1d05\ua779'},{b:'Dh',c:'\u00d0'},{b:'DZ',c:'\u01f1\u01c4'},{b:'Dz',c:'\u01f2\u01c5'},{b:'E',c:'\u025b\u24ba\uff25\u00c8\u00c9\u00ca\u1ec0\u1ebe\u1ec4\u1ec2\u1ebc\u0112\u1e14\u1e16\u0114\u0116\u00cb\u1eba\u011a\u0204\u0206\u1eb8\u1ec6\u0228\u1e1c\u0118\u1e18\u1e1a\u0190\u018e\u1d07'},{b:'F',c:'\ua77c\u24bb\uff26\u1e1e\u0191\ua77b'}, {b:'G',c:'\u24bc\uff27\u01f4\u011c\u1e20\u011e\u0120\u01e6\u0122\u01e4\u0193\ua7a0\ua77d\ua77e\u0262'},{b:'H',c:'\u24bd\uff28\u0124\u1e22\u1e26\u021e\u1e24\u1e28\u1e2a\u0126\u2c67\u2c75\ua78d'},{b:'I',c:'\u24be\uff29\u00cc\u00cd\u00ce\u0128\u012a\u012c\u0130\u00cf\u1e2e\u1ec8\u01cf\u0208\u020a\u1eca\u012e\u1e2c\u0197'},{b:'J',c:'\u24bf\uff2a\u0134\u0248\u0237'},{b:'K',c:'\u24c0\uff2b\u1e30\u01e8\u1e32\u0136\u1e34\u0198\u2c69\ua740\ua742\ua744\ua7a2'},{b:'L',c:'\u24c1\uff2c\u013f\u0139\u013d\u1e36\u1e38\u013b\u1e3c\u1e3a\u0141\u023d\u2c62\u2c60\ua748\ua746\ua780'}, {b:'LJ',c:'\u01c7'},{b:'Lj',c:'\u01c8'},{b:'M',c:'\u24c2\uff2d\u1e3e\u1e40\u1e42\u2c6e\u019c\u03fb'},{b:'N',c:'\ua7a4\u0220\u24c3\uff2e\u01f8\u0143\u00d1\u1e44\u0147\u1e46\u0145\u1e4a\u1e48\u019d\ua790\u1d0e'},{b:'NJ',c:'\u01ca'},{b:'Nj',c:'\u01cb'},{b:'O',c:'\u24c4\uff2f\u00d2\u00d3\u00d4\u1ed2\u1ed0\u1ed6\u1ed4\u00d5\u1e4c\u022c\u1e4e\u014c\u1e50\u1e52\u014e\u022e\u0230\u00d6\u022a\u1ece\u0150\u01d1\u020c\u020e\u01a0\u1edc\u1eda\u1ee0\u1ede\u1ee2\u1ecc\u1ed8\u01ea\u01ec\u00d8\u01fe\u0186\u019f\ua74a\ua74c'}, {b:'OE',c:'\u0152'},{b:'OI',c:'\u01a2'},{b:'OO',c:'\ua74e'},{b:'OU',c:'\u0222'},{b:'P',c:'\u24c5\uff30\u1e54\u1e56\u01a4\u2c63\ua750\ua752\ua754'},{b:'Q',c:'\u24c6\uff31\ua756\ua758\u024a'},{b:'R',c:'\u24c7\uff32\u0154\u1e58\u0158\u0210\u0212\u1e5a\u1e5c\u0156\u1e5e\u024c\u2c64\ua75a\ua7a6\ua782'},{b:'S',c:'\u24c8\uff33\u1e9e\u015a\u1e64\u015c\u1e60\u0160\u1e66\u1e62\u1e68\u0218\u015e\u2c7e\ua7a8\ua784'},{b:'T',c:'\u24c9\uff34\u1e6a\u0164\u1e6c\u021a\u0162\u1e70\u1e6e\u0166\u01ac\u01ae\u023e\ua786'}, {b:'Th',c:'\u00de'},{b:'TZ',c:'\ua728'},{b:'U',c:'\u24ca\uff35\u00d9\u00da\u00db\u0168\u1e78\u016a\u1e7a\u016c\u00dc\u01db\u01d7\u01d5\u01d9\u1ee6\u016e\u0170\u01d3\u0214\u0216\u01af\u1eea\u1ee8\u1eee\u1eec\u1ef0\u1ee4\u1e72\u0172\u1e76\u1e74\u0244'},{b:'V',c:'\u24cb\uff36\u1e7c\u1e7e\u01b2\ua75e\u0245'},{b:'VY',c:'\ua760'},{b:'W',c:'\u24cc\uff37\u1e80\u1e82\u0174\u1e86\u1e84\u1e88\u2c72'},{b:'X',c:'\u24cd\uff38\u1e8a\u1e8c'},{b:'Y',c:'\u24ce\uff39\u1ef2\u00dd\u0176\u1ef8\u0232\u1e8e\u0178\u1ef6\u1ef4\u01b3\u024e\u1efe'}, {b:'Z',c:'\u24cf\uff3a\u0179\u1e90\u017b\u017d\u1e92\u1e94\u01b5\u0224\u2c7f\u2c6b\ua762'},{b:'a',c:'\u24d0\uff41\u1e9a\u00e0\u00e1\u00e2\u1ea7\u1ea5\u1eab\u1ea9\u00e3\u0101\u0103\u1eb1\u1eaf\u1eb5\u1eb3\u0227\u01e1\u00e4\u01df\u1ea3\u00e5\u01fb\u01ce\u0201\u0203\u1ea1\u1ead\u1eb7\u1e01\u0105\u2c65\u0250\u0251'},{b:'aa',c:'\ua733'},{b:'ae',c:'\u00e6\u01fd\u01e3'},{b:'ao',c:'\ua735'},{b:'au',c:'\ua737'},{b:'av',c:'\ua739\ua73b'},{b:'ay',c:'\ua73d'}, {b:'b',c:'\u24d1\uff42\u1e03\u1e05\u1e07\u0180\u0183\u0253\u0182'},{b:'c',c:'\uff43\u24d2\u0107\u0109\u010b\u010d\u00e7\u1e09\u0188\u023c\ua73f\u2184'},{b:'d',c:'\u24d3\uff44\u1e0b\u010f\u1e0d\u1e11\u1e13\u1e0f\u0111\u018c\u0256\u0257\u018b\u13e7\u0501\ua7aa'},{b:'dh',c:'\u00f0'},{b:'dz',c:'\u01f3\u01c6'},{b:'e',c:'\u24d4\uff45\u00e8\u00e9\u00ea\u1ec1\u1ebf\u1ec5\u1ec3\u1ebd\u0113\u1e15\u1e17\u0115\u0117\u00eb\u1ebb\u011b\u0205\u0207\u1eb9\u1ec7\u0229\u1e1d\u0119\u1e19\u1e1b\u0247\u01dd'}, {b:'f',c:'\u24d5\uff46\u1e1f\u0192'},{b:'ff',c:'\ufb00'},{b:'fi',c:'\ufb01'},{b:'fl',c:'\ufb02'},{b:'ffi',c:'\ufb03'},{b:'ffl',c:'\ufb04'},{b:'g',c:'\u24d6\uff47\u01f5\u011d\u1e21\u011f\u0121\u01e7\u0123\u01e5\u0260\ua7a1\ua77f\u1d79'},{b:'h',c:'\u24d7\uff48\u0125\u1e23\u1e27\u021f\u1e25\u1e29\u1e2b\u1e96\u0127\u2c68\u2c76\u0265'},{b:'hv',c:'\u0195'},{b:'i',c:'\u24d8\uff49\u00ec\u00ed\u00ee\u0129\u012b\u012d\u00ef\u1e2f\u1ec9\u01d0\u0209\u020b\u1ecb\u012f\u1e2d\u0268\u0131'}, {b:'j',c:'\u24d9\uff4a\u0135\u01f0\u0249'},{b:'k',c:'\u24da\uff4b\u1e31\u01e9\u1e33\u0137\u1e35\u0199\u2c6a\ua741\ua743\ua745\ua7a3'},{b:'l',c:'\u24db\uff4c\u0140\u013a\u013e\u1e37\u1e39\u013c\u1e3d\u1e3b\u017f\u0142\u019a\u026b\u2c61\ua749\ua781\ua747\u026d'},{b:'lj',c:'\u01c9'},{b:'m',c:'\u24dc\uff4d\u1e3f\u1e41\u1e43\u0271\u026f'},{b:'n',c:'\u24dd\uff4e\u01f9\u0144\u00f1\u1e45\u0148\u1e47\u0146\u1e4b\u1e49\u019e\u0272\u0149\ua791\ua7a5\u043b\u0509'},{b:'nj', c:'\u01cc'},{b:'o',c:'\u24de\uff4f\u00f2\u00f3\u00f4\u1ed3\u1ed1\u1ed7\u1ed5\u00f5\u1e4d\u022d\u1e4f\u014d\u1e51\u1e53\u014f\u022f\u0231\u00f6\u022b\u1ecf\u0151\u01d2\u020d\u020f\u01a1\u1edd\u1edb\u1ee1\u1edf\u1ee3\u1ecd\u1ed9\u01eb\u01ed\u00f8\u01ff\ua74b\ua74d\u0275\u0254\u1d11'},{b:'oe',c:'\u0153'},{b:'oi',c:'\u01a3'},{b:'oo',c:'\ua74f'},{b:'ou',c:'\u0223'},{b:'p',c:'\u24df\uff50\u1e55\u1e57\u01a5\u1d7d\ua751\ua753\ua755\u03c1'},{b:'q',c:'\u24e0\uff51\u024b\ua757\ua759'}, {b:'r',c:'\u24e1\uff52\u0155\u1e59\u0159\u0211\u0213\u1e5b\u1e5d\u0157\u1e5f\u024d\u027d\ua75b\ua7a7\ua783'},{b:'s',c:'\u24e2\uff53\u015b\u1e65\u015d\u1e61\u0161\u1e67\u1e63\u1e69\u0219\u015f\u023f\ua7a9\ua785\u1e9b\u0282'},{b:'ss',c:'\u00df'},{b:'t',c:'\u24e3\uff54\u1e6b\u1e97\u0165\u1e6d\u021b\u0163\u1e71\u1e6f\u0167\u01ad\u0288\u2c66\ua787'},{b:'th',c:'\u00fe'},{b:'tz',c:'\ua729'},{b:'u',c:'\u24e4\uff55\u00f9\u00fa\u00fb\u0169\u1e79\u016b\u1e7b\u016d\u00fc\u01dc\u01d8\u01d6\u01da\u1ee7\u016f\u0171\u01d4\u0215\u0217\u01b0\u1eeb\u1ee9\u1eef\u1eed\u1ef1\u1ee5\u1e73\u0173\u1e77\u1e75\u0289'}, {b:'v',c:'\u24e5\uff56\u1e7d\u1e7f\u028b\ua75f\u028c'},{b:'vy',c:'\ua761'},{b:'w',c:'\u24e6\uff57\u1e81\u1e83\u0175\u1e87\u1e85\u1e98\u1e89\u2c73'},{b:'x',c:'\u24e7\uff58\u1e8b\u1e8d'},{b:'y',c:'\u24e8\uff59\u1ef3\u00fd\u0177\u1ef9\u0233\u1e8f\u00ff\u1ef7\u1e99\u1ef5\u01b4\u024f\u1eff'},{b:'z',c:'\u24e9\uff5a\u017a\u1e91\u017c\u017e\u1e93\u1e95\u01b6\u0225\u0240\u2c6c\ua763'}];
var UPLOADINDEXER = 1;
for (var i=0; i <DIACRITICS.length; i+=1)
for (var chars=DIACRITICS[i].c,j=0;j<chars.length;j+=1)
DIACRITICSMAP[chars[j]]=DIACRITICS[i].b;
const DP = Date.prototype;
const SP = String.prototype;
const NP = Number.prototype;
DIACRITICS = null;
var CONTENTTYPES = {
aac: 'audio/aac',
ai: 'application/postscript',
appcache: 'text/cache-manifest',
avi: 'video/avi',
bin: CT_OCTET,
bmp: 'image/bmp',
coffee: 'text/coffeescript',
css: 'text/css',
csv: 'text/csv',
doc: 'application/msword',
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
dtd: 'application/xml-dtd',
eps: 'application/postscript',
exe: CT_OCTET,
flac: 'audio/x-flac',
geojson: 'application/json',
gif: 'image/gif',
gzip: 'application/x-gzip',
heic: 'image/heic',
heif: 'image/heif',
htm: 'text/html',
html: 'text/html',
ico: 'image/x-icon',
ics: 'text/calendar',
ifb: 'text/calendar',
jpe: 'image/jpeg',
jpeg: 'image/jpeg',
jpg: 'image/jpeg',
js: 'text/javascript',
json: 'application/json',
ui: 'application/json', // UI builder
jsx: 'text/jsx',
less: 'text/css',
m3u8: 'application/x-mpegURL',
m4a: 'audio/mp4a-latm',
m4v: 'video/x-m4v',
manifest: 'text/cache-manifest',
md: 'text/x-markdown',
mid: 'audio/midi',
midi: 'audio/midi',
mjs: 'text/javascript',
mov: 'video/quicktime',
mp3: 'audio/mpeg',
mp4: 'video/mp4',
mpe: 'video/mpeg',
mpeg: 'video/mpeg',
mpg: 'video/mpeg',
mpga: 'audio/mpeg',
mtl: 'text/plain',
mv4: 'video/mv4',
obj: 'text/plain',
ogg: 'application/ogg',
ogv: 'video/ogg',
package: 'text/plain',
pdf: 'application/pdf',
png: 'image/png',
psd: 'image/vnd.adobe.photoshop',
ppt: 'application/vnd.ms-powerpoint',
pptx: 'application/vnd.ms-powerpoint',
ps: 'application/postscript',
rar: 'application/x-rar-compressed',
rtf: 'text/rtf',
sass: 'text/css',
scss: 'text/css',
sh: 'application/x-sh',
stl: 'application/sla',
svg: 'image/svg+xml',
swf: 'application/x-shockwave-flash',
tar: 'application/x-tar',
ts: 'video/mp2t',
tif: 'image/tiff',
tiff: 'image/tiff',
txt: 'text/plain',
sql: 'text/plain',
wav: 'audio/wav',
wasm: 'application/wasm',
webm: 'video/webm',
webp: 'image/webp',
woff: 'application/font-woff',
woff2: 'application/font-woff2',
xht: 'application/xhtml+xml',
xhtml: 'application/xhtml+xml',
xls: 'application/vnd.ms-excel',
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
xml: 'application/xml',
xpm: 'image/x-xpixmap',
xsl: 'application/xml',
xsd: 'application/xml',
xslt: 'application/xslt+xml',
zip: 'application/zip',
'7zip': 'application/x-7z-compressed'
};
var dnscache = {};
var datetimeformat = {};
global.DIFFARR = exports.diffarr = function(prop, db, form) {
var an = [];
var au = [];
var ar = [];
var is, oa, ob;
for (var i = 0; i < db.length; i++) {
oa = db[i];
is = false;
for (var j = 0; j < form.length; j++) {
ob = form[j];
if (oa[prop] == ob[prop]) {
au.push({ db: oa, form: ob });
is = true;
break;
}
}
if (!is)
ar.push(oa[prop]);
}
for (var i = 0; i < form.length; i++) {
ob = form[i];
is = false;
for (var j = 0; j < db.length; j++) {
oa = db[j];
if (ob[prop] == oa[prop]) {
is = true;
break;
}
}
if (!is)
an.push(ob);
}
var obj = {};
obj.add = an;
obj.upd = au;
obj.rem = ar;
return obj;
};
exports.groupify = function(id, count) {
var number = 1;
if (!count)
count = 4;
for (var i = 0; i < count; i++)
number *= 10;
var val = (HASH(id, true) % number) + '';
var diff = count - val.length;
if (diff > 0) {
for (var i = 0; i < diff; i++)
val = '0' + val;
}
if (diff.length > 4)
val = val.substring(0, 4);
return val;
};
exports.toURLEncode = function(value) {
var builder = [];
for (var key in value) {
var val = value[key];
if (val == null || val === '')
continue;
var type = typeof(val);
switch (type) {
case 'string':
builder.push(key + '=' + encodeURIComponent(val));
break;
case 'date':
builder.push(key + '=' + encodeURIComponent(val.format('utc')));
break;
case 'boolean':
case 'number':
builder.push(key + '=' + val);
break;
case 'object':
if (val instanceof Array)
builder.push(key + '=' + encodeURIComponent(val.join(',')));
break;
}
}
return builder.length ? builder.join('&') : '';
};
exports.resolve = function(url, callback, param) {
var uri;
try {
uri = Url.parse(url);
} catch (e) {
callback(e);
return;
}
var cache = dnscache[uri.host];
if (!callback)
return cache;
if (cache) {
uri.host = cache[0];
callback(null, uri, param, cache);
return;
}
Dns.resolve4(uri.hostname, function(e, addresses) {
if (e)
setImmediate(dnsresolve_callback, uri, callback, param);
else {
dnscache[uri.host] = addresses;
uri.host = addresses[0];
callback(null, uri, param, addresses);
}
});
};
function dnsresolve_callback(uri, callback, param) {
Dns.resolve4(uri.hostname, function(e, addresses) {
if (addresses && addresses.length) {
dnscache[uri.host] = addresses;
uri.host = addresses[0];
}
callback(e, uri, param, addresses);
});
}
setImmediate(function() {
global.F && NEWCOMMAND('clear_dnscache', function() {
dnscache = {};
});
});
exports.keywords = function(content, forSearch, alternative, max_count, max_length, min_length) {
if (forSearch === undefined)
forSearch = true;
min_length = min_length || 2;
max_count = max_count || 200;
max_length = max_length || 20;
var words = [];
if (content instanceof Array) {
for (var i = 0, length = content.length; i < length; i++) {
if (!content[i])
continue;
var tmp = (forSearch ? content[i].toASCII().toLowerCase().replace(regexpY, 'i') : content[i].toLowerCase()).replace(regexpN, ' ').split(' ');
if (!tmp || !tmp.length)
continue;
for (var j = 0, jl = tmp.length; j < jl; j++)
words.push(tmp[j]);
}
} else
words = (forSearch ? content.toASCII().toLowerCase().replace(regexpY, 'i') : content.toLowerCase()).replace(regexpN, ' ').split(' ');
if (!words)
words = [];
var dic = {};
var counter = 0;
for (var i = 0, length = words.length; i < length; i++) {
var word = words[i].trim().replace(regexpCHARS, keywordscleaner);
if (regexpCHINA.test(word)) {
var tmpw = word.split('', max_count);
for (var j = 0; j < tmpw.length; j++) {
word = tmpw[j];
if (dic[word])
dic[word]++;
else
dic[word] = 1;
counter++;
}
if (counter >= max_count)
break;
continue;
}
if (word.length < min_length)
continue;
if (counter >= max_count)
break;
// Gets 80% length of word
if (alternative) {
var size = (word.length / 100) * 80;
if (size > min_length + 1)
word = word.substring(0, size);
}
if (word.length < min_length || word.length > max_length)
continue;
if (dic[word])
dic[word]++;
else
dic[word] = 1;
counter++;
}
var keys = Object.keys(dic);
keys.sort(function(a, b) {
var countA = dic[a];
var countB = dic[b];
return countA > countB ? -1 : countA < countB ? 1 : 0;
});
return keys;
};
function keywordscleaner(c) {
return c.charCodeAt(0) < 200 ? '' : c;
}
function parseProxy(p) {
var key = 'proxy_' + p;
if (F.temporary.other[key])
return F.temporary.other[key];
if (p.indexOf('://') === -1)
p = 'http://' + p;
var obj = Url.parse(p);
if (obj.auth)
obj._auth = 'Basic ' + Buffer.from(obj.auth).toString('base64');
obj.port = +obj.port;
if (p.indexOf('https:') !== -1) {
obj.rejectUnauthorized = false;
obj.requestCert = true;
}
return F.temporary.other[key] = obj;
}
function _request(opt, callback) {
var options = { length: 0, timeout: opt.timeout != false && opt.timeout != 0 ? (opt.timeout || CONF.default_restbuilder_timeout) : 0, encoding: opt.encoding || ENCODING, callback: callback || opt.callback || NOOP, post: true, redirect: 0 };
var proxy;
if (global.F)
global.F.stats.performance.external++;
if (opt.headers)
opt.headers = exports.extend({}, opt.headers);
else
opt.headers = {};
if (!opt.method)
opt.method = 'GET';
options.$totalinit = opt;
// opt.encrypt {String}
// opt.limit in kB
// opt.key {Buffer}
// opt.cert {Buffer}
// opt.onprogress(percentage)
// opt.ondata(chunk, percentage)
if (opt.ondata)
options.ondata = opt.ondata;
if (opt.onprogress)
options.onprogress = opt.onprogress;
if (opt.proxy)
proxy = parseProxy(opt.proxy);
if (opt.xhr)
opt.headers['X-Requested-With'] = 'XMLHttpRequest';
options.response = opt.response ? opt.response : {};
options.response.body = '';
options.iserror = false;
if (opt.resolve || opt.dnscache)
options.resolve = true;
if (opt.custom)
options.custom = true;
if (opt.noredirect)
options.noredirect = true;
if (opt.keepalive)
options.keepalive = true;
if (opt.type) {
switch (opt.type) {
case 'plain':
opt.headers[CT] = 'text/plain';
break;
case 'html':
opt.headers[CT] = 'text/html';
break;
case 'raw':
opt.headers[CT] = CT_OCTET;
break;
case 'json':
opt.headers[CT] = 'application/json; charset=utf-8';
break;
case 'urlencoded':
opt.headers[CT] = 'application/x-www-form-urlencoded';
break;
case 'xml':
opt.headers[CT] = 'text/xml';
break;
}
}
if (opt.compress)
opt.headers['Content-Encoding'] = opt.compress;
if (opt.files) {
options.boundary = '----TOTALFILE_' + Math.random().toString(36).substring(3);
opt.headers[CT] = 'multipart/form-data; boundary=' + options.boundary;
options.files = opt.files;
options.upload = true;
// Must be object { key: value }
if (opt.body)
options.body = opt.body;
} else {
if (opt.body) {
if (!(opt.body instanceof Buffer)) {
if (opt.encrypt) {
opt.body = exports.encrypt_data(opt.body, opt.encrypt);
opt.headers['X-Encryption'] = 'a';
}
opt.body = Buffer.from(opt.body, ENCODING);
}
if (!opt.compress || !COMPRESS[opt.compress])
opt.headers['Content-Length'] = opt.body.length;
}
options.body = opt.body;
}
if (opt.cookies) {
var builder = '';
for (var m in opt.cookies)
builder += (builder ? '; ' : '') + m + '=' + opt.cookies[m];
if (builder)
opt.headers.Cookie = builder;
}
if (opt.query) {
if (typeof(opt.query) !== 'string')
opt.query = U.toURLEncode(opt.query);
if (opt.url) {
if (opt.url.lastIndexOf('?') === -1)
opt.url += '?' + opt.query;
else
opt.url += '&' + opt.query;
} else if (opt.unixsocket.path) {
if (opt.unixsocket.path.lastIndexOf('?') === -1)
opt.unixsocket.path += '?' + opt.query;
else
opt.unixsocket.path += '&' + opt.query;
}
}
var uri = opt.unixsocket ? { socketPath: opt.unixsocket.socket, path: opt.unixsocket.path } : Url.parse(opt.url);
if ((opt.unixsocket && !uri.socketPath) || (!opt.unixsocket && (!uri.hostname || !uri.host))) {
options.response.canceled = true;
opt.callback && opt.callback('Invalid hostname', options.response);
return;
}
uri.method = opt.method;
uri.headers = opt.headers;
if (opt.insecure) {
uri.rejectUnauthorized = false;
uri.requestCert = true;
}
options.uri = uri;
options.opt = opt;
if (opt.key)
uri.key = opt.key;
if (opt.cert)
uri.cert = opt.cert;
if (opt.dhparam)
uri.dhparam = opt.dhparam;
if (options.resolve && (opt.unixsocket || (uri.hostname === 'localhost' || uri.hostname.charCodeAt(0) < 64)))
options.resolve = false;
if (!opt.unixsocket && CONF.default_proxy && !proxy && !PROXYBLACKLIST[uri.hostname])
proxy = parseProxy(CONF.default_proxy);
if (!opt.unixsocket && proxy && (uri.hostname === 'localhost' || uri.hostname === '127.0.0.1'))
proxy = null;
options.proxy = proxy;
if (proxy && uri.protocol === 'https:') {
proxy.tls = true;
uri.agent = new ProxyAgent(options);
uri.agent.request = Http.request;
uri.agent.createSocket = createSecureSocket;
uri.agent.defaultPort = 443;
}
if (options.keepalive && !options.proxy) {
if (uri.protocol === 'https:') {
if (!uri.port)
uri.port = 443;
uri.agent = KeepAliveHttps;
} else
uri.agent = KeepAlive;
} else
uri.agent = null;
if (proxy)
request_call(uri, options);
else if (options.resolve)
exports.resolve(opt.url, request_resolve, options);
else
request_call(uri, options);
}
global.REQUEST = function(opt, callback) {
if (callback)
opt.callback = callback;
if (opt.callback)
_request(opt);
else
return new Promise((resolve, reject) => _request(opt, (err, res) => err ? reject(err) : resolve(res)));
};
function request_resolve(err, uri, options, origin) {
if (!err) {
options.uri.host = uri.host;
options.origin = origin;
}
request_call(options.uri, options);
}
function ProxyAgent(options) {
var self = this;
self.options = options;
self.maxSockets = Http.Agent.defaultMaxSockets;
self.requests = [];
}
const PAP = ProxyAgent.prototype;
PAP.createConnection = function(pending) {
var self = this;
self.createSocket(pending, function(socket) {
pending.request.onSocket(socket);
});
};
PAP.createSocket = function(options, callback) {
var self = this;
var proxy = self.options.proxy;
var uri = self.options.uri;
PROXYOPTIONS.host = proxy.hostname;
PROXYOPTIONS.port = proxy.port;
PROXYOPTIONS.path = PROXYOPTIONS.headers.host = uri.hostname + ':' + (uri.port || '443');
if (proxy._auth)
PROXYOPTIONS.headers['Proxy-Authorization'] = proxy._auth;
var req = self.request(PROXYOPTIONS);
req.setTimeout(10000);
req.on('response', proxyagent_response);
req.on('connect', function(res, socket) {
if (res.statusCode === 200) {
socket.$req = req;
callback(socket);
} else {
var err = new Error('Proxy could not be established (maybe a problem in auth), code: ' + res.statusCode);
err.code = 'ECONNRESET';
req.destroy && req.destroy();
req = null;
self.requests = null;
self.options = null;
}
});
req.on('error', function(err) {
var e = new Error('Request Proxy "proxy {0} --> target {1}": {2}'.format(PROXYOPTIONS.host + ':' + proxy.port, PROXYOPTIONS.path, err.toString()));
e.code = err.code;
req.destroy && req.destroy();
req = null;
self.requests = null;
self.options = null;
});
req.end();
};
function proxyagent_response(res) {
res.upgrade = true;
}
PAP.addRequest = function(req, options) {
this.createConnection({ host: options.host, port: options.port, request: req });
};
function createSecureSocket(options, callback) {
var self = this;
PAP.createSocket.call(self, options, function(socket) {
PROXYTLS.servername = self.options.uri.hostname;
PROXYTLS.headers = self.options.uri.headers;
PROXYTLS.socket = socket;
var tls = Tls.connect(0, PROXYTLS);
callback(tls);
});
}
function request_call(uri, options) {
var opt;
if (options.proxy && !options.proxy.tls) {
opt = PROXYOPTIONSHTTP;
opt.port = options.proxy.port;
opt.host = options.proxy.hostname;
opt.path = uri.href;
opt.headers = uri.headers;
opt.method = uri.method;
opt.headers.host = uri.host;
if (options.proxy._auth)
opt.headers['Proxy-Authorization'] = options.proxy._auth;
} else
opt = uri;
var connection = uri.protocol === 'https:' ? Https : Http;
var req = opt.method === 'GET' ? connection.get(opt, request_response) : connection.request(opt, request_response);
req.$options = options;
req.$uri = uri;
if (!options.callback) {
req.on('error', NOOP);
return;
}
req.on('error', request_process_error);
if (options.timeoutid) {
clearTimeout(options.timeoutid);
options.timeoutid = null;
}
if (options.timeout)
options.timeoutid = setTimeout(request_process_timeout, options.timeout, req);
req.on('response', request_assign_res);
if (options.upload) {
options.first = true;
options.files.wait(function(file, next) {
request_writefile(req, options, file, next);
}, function() {
if (options.iserror)
return;
if (options.body) {
for (var key in options.body) {
var value = options.body[key];
if (value != null) {
try {
req.write((options.first ? '' : NEWLINE) + '--' + options.boundary + NEWLINE + 'Content-Disposition: form-data; name="' + key + '"' + NEWLINE + NEWLINE + value);
} catch (e) {
request_process_error.apply(req, e);
break;
}
if (options.first)
options.first = false;
}
}
}
req.end(NEWLINE + '--' + options.boundary + '--');
});
} else {
if (options.opt.compress) {
Zlib[options.opt.compress](options.body, function(err, buffer) {
req.end(buffer);
});
} else
req.end(options.body);
}
}
function request_process_error(err) {
var options = this.$options;
options.iserror = true;
if (options.callback && !options.done) {
if (options.timeoutid) {
clearTimeout(options.timeoutid);
options.timeoutid = null;
}
options.canceled = true;
options.response.status = 0;
options.response.host = this.$uri.host;
options.callback(err, options.response);
options.callback = null;
}
}
function request_process_timeout(req) {
var options = req.$options;
options.iserror = true;
if (options.callback) {
if (options.timeoutid) {
clearTimeout(options.timeoutid);
options.timeoutid = null;
}
req.socket.destroy();
req.socket.end();
req.destroy();
options.response.status = 408;
options.response.host = req.$uri.host;
options.canceled = true;
options.callback(exports.httpstatus(408), options.response);
options.callback = null;
}
}
function request_process_ok() {
var options = this.req.$options;
if (options.timeoutid) {
clearTimeout(options.timeoutid);
options.timeoutid = null;
}
}
function request_assign_res(response) {
response.req = this;
}
function request_writefile(req, options, file, next) {
if (options.iserror) {
next();
return;
}
var filedata = file.buffer || file.url;
var isbuffer = filedata instanceof Buffer;
var isurl = isbuffer ? false : typeof(filedata) === 'string' && filedata;
var filename = (isbuffer || isurl ? file.filename : exports.getName(file.filename));
req.write((options.first ? '' : NEWLINE) + '--' + options.boundary + NEWLINE + 'Content-Disposition: form-data; name="' + file.name + '"; filename="' + filename + '"' + NEWLINE + 'Content-Type: ' + exports.getContentType(exports.getExtension(filename)) + NEWLINE + NEWLINE);
if (options.first)
options.first = false;
if (isbuffer) {
try {
req.write(filedata);
} catch (e) {
request_process_error.apply(req, e);
}
next();
} else if (isurl) {
// Download
var opt = {};
opt.method = 'GET';
opt.custom = true;
opt.url = filedata;
opt.callback = function(err, response) {
if (response && response.stream) {
response.stream.on('close', next);
response.stream.pipe(req, STREAMPIPE);
} else {
err && request_process_error.apply(req, err);
next();
}
};
REQUEST(opt);
} else {
var stream = Fs.createReadStream(file.path || file.filename);
stream.once('close', next);
stream.pipe(req, STREAMPIPE);
}
}
function request_response(res) {
var options = this.$options;
var uri = this.$uri;
res._buffer = null;
res._bufferlength = 0;
// We have redirect
if (res.statusCode === 301 || res.statusCode === 302) {
if (options.noredirect) {
options.timeoutid && clearTimeout(options.timeoutid);
options.canceled = true;
if (options.callback) {
options.response.origin = options.origin;
options.response.status = res.statusCode;
options.response.headers = res.headers;
if (options.custom) {
options.response.stream = res;
options.callback(null, options.response);
} else {
options.response.host = uri.host;
options.response.headers = res.headers;
options.callback(null, options.response);
}
options.callback = null;
}
res.req.removeAllListeners();
res.removeAllListeners();
res.req = null;
res = null;
return;
}
if (options.redirect > (options.redirects || 3)) {
options.timeoutid && clearTimeout(options.timeoutid);
options.canceled = true;
options.response.origin = options.origin;
options.response.headers = res.headers;
if (options.callback) {
if (options.custom) {
options.response.status = res.statusCode;
options.response.stream = res;
options.callback('Too many redirects', options.response);
} else {
options.response.status = 0;
options.response.host = uri.host;
options.callback('Too many redirects', options.response);
}
options.callback = null;
}
res.req.removeAllListeners();
res.removeAllListeners();
res.req = null;
res = null;
return;
}
options.redirect++;
var loc = res.headers.location;
var proto = loc.substring(0, 6);
if (proto !== 'http:/' && proto !== 'https:')
loc = uri.protocol + '//' + uri.hostname + (uri.port && !SKIPPORTS[uri.port] ? (':' + uri.port) : '') + loc;
var tmp = Url.parse(loc);
tmp.headers = uri.headers;
// Transfers cookies
if (!options.nocookies) {
var cookies = res.headers['set-cookie'];
if (cookies) {
if (options.$totalinit.cook && !options.$totalinit.cookies)
options.$totalinit.cookies = {};
if (!options.cookies)
options.cookies = {};
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i];
var index = cookie.indexOf(';');
if (index !== -1){
cookie = cookie.substring(0, index);
index = cookie.indexOf('=');
if (index !== -1) {
var key = decodeURIComponent(cookie.substring(0, index));
options.cookies[key] = decodeURIComponent(cookie.substring(index + 1));
if (options.$totalinit.cookies)
options.$totalinit.cookies[key] = options.cookies[key];
}
}
}
var builder = '';
for (var m in options.cookies)
builder += (builder ? '; ' : '') + encodeURIComponent(m) + '=' + encodeURIComponent(options.cookies[m]);
if (tmp.headers.cookie)
tmp.headers.cookie = builder;
else
tmp.headers.Cookie = builder;
}
}
// tmp.agent = false;
tmp.method = uri.method;
res.req.socket.destroy();
res.req.socket.end();
res.req.destroy();
res.removeAllListeners();
res.req.removeAllListeners();
res.req = null;
if (options.proxy && tmp.protocol === 'https:') {
// TLS?
options.proxy.tls = true;
options.uri = tmp;
options.uri.agent = new ProxyAgent(options);
options.uri.agent.request = Http.request;
options.uri.agent.createSocket = createSecureSocket;
options.uri.agent.defaultPort = 443;
}
if (!options.resolve) {
res.removeAllListeners();
res = null;
return request_call(tmp, options);
}
exports.resolve(tmp, function(err, u, param, origin) {
if (!err) {
tmp.host = u.host;
options.origin = origin;
}
res.removeAllListeners();
res = null;
request_call(tmp, options);
});
return;
}
options.length = +res.headers['content-length'] || 0;
// Shared cookies
if (options.$totalinit.cook) {
if (!options.$totalinit.cookies)
options.$totalinit.cookies = {};
var arr = (res.headers['set-cookie'] || '');
// Only the one value
if (arr && !(arr instanceof Array))
arr = [arr];
if (arr instanceof Array) {
for (var i = 0; i < arr.length; i++) {
var line = arr[i];
var end = line.indexOf(';');
if (end === -1)
end = line.length;
line = line.substring(0, end);
var index = line.indexOf('=');
if (index !== -1)
options.$totalinit.cookies[line.substring(0, index)] = decodeURIComponent(line.substring(index + 1));
}
}
}
if (res.statusCode === 204) {
options.done = true;
if (options.custom) {
options.timeoutid && clearTimeout(options.timeoutid);
options.response.origin = options.origin;
options.response.status = res.statusCode;
options.response.headers = res.headers;
options.response.stream = res;
options.callback(null, options.response);
options.callback = null;
} else
request_process_end.call(res);
return;
}
options.timeoutid && res.once('data', request_process_ok);
var encoding = res.headers['content-encoding'] || '';
if (encoding)
encoding = encoding.split(',')[0];
if (options.custom) {
options.timeoutid && clearTimeout(options.timeoutid);
options.response.origin = options.origin;
options.response.status = res.statusCode;
options.response.headers = res.headers;
options.response.stream = res;
options.callback && options.callback(null, options.response);
options.callback = null;
} else {
if (COMPRESS[encoding]) {
var zlib = encoding === 'gzip' ? Zlib.createGunzip() : Zlib.createInflate();
zlib._buffer = res.buffer;
zlib.headers = res.headers;
zlib.statusCode = res.statusCode;
zlib.res = res;
zlib.on('data', request_process_data);
zlib.on('end', request_process_end);
res.pipe(zlib);
} else {
res.on('data', request_process_data);
res.on('end', request_process_end);
}
res.resume();
}
}
function request_process_data(chunk) {
var self = this;
// Is Zlib
if (!self.req)
self = self.res;
var options = self.req.$options;
if (options.canceled || (options.limit && self._bufferlength > options.limit))
return;
if (self._buffer) {
CONCAT[0] = self._buffer;
CONCAT[1] = chunk;
self._buffer = Buffer.concat(CONCAT);
} else
self._buffer = chunk;
self._bufferlength += chunk.length;
options.ondata && options.ondata(chunk, options.length ? (self._bufferlength / options.length) * 100 : 0);
options.onprogress && options.onprogress(options.length ? (self._bufferlength / options.length) * 100 : 0);
}
function request_process_end() {
var res = this;
// Is Zlib
if (!res.req)
res = res.res;
var self = res;
var options = self.req.$options;
var uri = self.req.$uri;
var data;
options.socket && options.uri.agent.destroy();
options.timeoutid && clearTimeout(options.timeoutid);
if (options.canceled)
return;
var ct = self.headers['content-type'];
if (!ct || REG_TEXTAPPLICATION.test(ct)) {
data = self._buffer ? options.encoding === 'binary' ? self._buffer : self._buffer.toString(options.encoding) : '';
if (options.opt.encrypt && typeof(data) === 'string')
data = exports.decrypt_data(data, options.opt.encrypt);
} else
data = self._buffer;
options.canceled = true;
self._buffer = undefined;
if (options.callback) {
options.response.origin = options.origin;
options.response.headers = self.headers;
options.response.body = data;
options.response.status = self.statusCode;
options.response.host = uri.host || uri.socketPath;
options.response.cookies = options.cookies;
options.callback(null, options.response);
options.callback = null;
}
if (res.statusCode !== 204) {
res.req && res.req.removeAllListeners();
res.removeAllListeners();
}
}
exports.btoa = function(str) {
return (str instanceof Buffer) ? str.toString('base64') : Buffer.from(str.toString(), 'utf8').toString('base64');
};
exports.atob = function(str) {
return Buffer.from(str, 'base64').toString('utf8');
};
/**
* Trim string properties
* @param {Object} obj
* @return {Object}
*/
exports.trim = function(obj, clean) {
if (!obj)
return obj;
var type = typeof(obj);
if (type === 'string') {
obj = obj.trim();
return clean && !obj ? undefined : obj;
}
if (obj instanceof Array) {
for (var i = 0, length = obj.length; i < length; i++) {
var item = obj[i];
type = typeof(item);
if (type === 'object') {
exports.trim(item, clean);
continue;
}
if (type !== 'string')
continue;
obj[i] = item.trim();
if (clean && !obj[i])
obj[i] = undefined;
}
return obj;
}
if (type !== 'object')
return obj;
for (var key in obj) {
var val = obj[key];
var type = typeof(val);
if (type === 'object') {
exports.trim(val, clean);
continue;
} else if (type !== 'string')
continue;
obj[key] = val.trim();
if (clean && !obj[key])
obj[key] = undefined;
}
return obj;
};
/**
* Noop function
* @return {Function} Empty function.
*/
global.NOOP = function() {};
/**
* Read HTTP status
* @param {Number} code HTTP code status.
* @param {Boolean} addCode Add code number to HTTP status.
* @return {String}
*/
exports.httpstatus = function(code, addCode) {
if (addCode === undefined)
addCode = true;
return (addCode ? code + ': ' : '') + Http.STATUS_CODES[code];
};
/**
* Extend object
* @param {Object} target Target object.
* @param {Object} source Source object.
* @param {Boolean} rewrite Rewrite exists values (optional, default true).
* @return {Object} Modified object.
*/
exports.extend = function(target, source, rewrite) {
if (!target || !source)
return target;
if (typeof(target) !== 'object' || typeof(source) !== 'object')
return target;
if (rewrite === undefined)
rewrite = true;
var keys = Object.keys(source);
var i = keys.length;
while (i--) {
var key = keys[i];
if (rewrite || target[key] === undefined)
target[key] = exports.clone(source[key]);
}
return target;
};
exports.extend_headers = function(first, second) {
var headers = {};
for (let key in first)
headers[key] = first[key];
for (let key in second)
headers[key] = second[key];
return headers;
};
exports.extend_headers2 = function(first, second) {
for (let key in second)
first[key] = second[key];
return first;
};
/**
* Clones object
* @param {Object} obj
* @param {Object} skip Optional, can be only object e.g. { name: true, age: true }.
* @param {Boolean} skipFunctions It doesn't clone functions, optional --> default false.
* @return {Object}
*/
global.CLONE = exports.clone = function(obj, skip, skipFunctions) {
if (!obj)
return obj;
var type = typeof(obj);
if (type !== 'object' || obj instanceof Date || obj instanceof Error)
return obj;
var length;
var o;
if (obj instanceof Array) {
length = obj.length;
o = new Array(length);
for (var i = 0; i < length; i++) {
type = typeof(obj[i]);
if (type !== 'object' || obj[i] instanceof Date || obj[i] instanceof Error) {
if (skipFunctions && type === 'function')
continue;
o[i] = obj[i];
continue;
}
o[i] = exports.clone(obj[i], skip, skipFunctions);
}
return o;
}
o = {};
var keys = Object.keys(obj);
for (var m of keys) {
if (skip && skip[m])
continue;
var val = obj[m];
if (val instanceof Buffer) {
var copy = Buffer.alloc(val.length);
val.copy(copy);
o[m] = copy;
continue;
}
var type = typeof(val);
if (type !== 'object' || val instanceof Date || val instanceof Error) {
if (skipFunctions && type === 'function')
continue;
o[m] = val;
continue;
}
o[m] = exports.clone(obj[m], skip, skipFunctions);
}
return o;
};
global.COPY = function(source, target) {
return exports.copy(source, target, true);
};
/**
* Copy values from object to object
* @param {Object} source Object source
* @param {Object} target Object target (optional)
* @return {Object} Modified object.
*/
exports.copy = function(source, target, all) {
if (target === undefined)
return exports.extend({}, source, true);
if (!target || !source || typeof(target) !== 'object' || typeof(source) !== 'object')
return target;
for (var key in source) {
if (all || target[key] !== undefined)
target[key] = exports.clone(source[key]);
}
return target;
};
/**
* Reduces an object
* @param {Object} source Source object.
* @param {String Array or Object} prop Other properties than these ones will be removed.
* @param {Boolean} reverse Reverse reducing (prop will be removed), default: false.
* @return {Object}
*/
exports.reduce = function(source, prop, reverse) {
if (!(prop instanceof Array)) {
if (typeof(prop) === 'object')
return exports.reduce(source, Object.keys(prop), reverse);
}
if (source instanceof Array) {
var arr = [];
for (var i = 0, length = source.length; i < length; i++)
arr.push(exports.reduce(source[i], prop, reverse));
return arr;
}
var output = {};
for (var o in source) {
if (reverse) {
if (prop.indexOf(o) === -1)
output[o] = source[o];
} else {
if (prop.indexOf(o) !== -1)
output[o] = source[o];
}
}
return output;
};
exports.isrelative = function(url) {
return !(url.substring(0, 2) === '//' || url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1);
};
/**
* Streamer method
* @param {String/Buffer} beg
* @param {String/Buffer} end
* @param {Function(value, index)} callback
*/
exports.streamer = function(beg, end, callback, skip, stream, raw) {
if (typeof(end) === 'function') {
stream = skip;
skip = callback;
callback = end;
end = undefined;
}
if (typeof(skip) === 'object') {
stream = skip;
skip = 0;
}
var indexer = 0;
var buffer = Buffer.alloc(0);
var canceled = false;
var fn;
if (skip === undefined)
skip = 0;
if (!(beg instanceof Buffer))
beg = Buffer.from(beg, 'utf8');
if (end && !(end instanceof Buffer))
end = Buffer.from(end, 'utf8');
if (!end) {
var length = beg.length;
fn = function(chunk) {
if (!chunk || canceled)
return;
CONCAT[0] = buffer;
CONCAT[1] = chunk;
var f = 0;
if (buffer.length) {
f = buffer.length - beg.length;
if (f < 0)
f = 0;
}
buffer = Buffer.concat(CONCAT);
var index = buffer.indexOf(beg, f);
if (index === -1)
return;
while (index !== -1) {
if (skip)
skip--;
else {
if (callback(raw ? buffer.slice(0, index + length) : buffer.toString('utf8', 0, index + length), indexer++) === false)
canceled = true;
}
if (canceled)
return;
buffer = buffer.slice(index + length);
index = buffer.indexOf(beg);
if (index === -1)
return;
}
};
stream && stream.on('end', () => fn(beg));
return fn;
}
var blength = beg.length;
var elength = end.length;
var bi = -1;
var ei = -1;
var is = false;
fn = function(chunk) {
if (!chunk || canceled)
return;
CONCAT[0] = buffer;
CONCAT[1] = chunk;
buffer = Buffer.concat(CONCAT);
if (!is) {
var f = CONCAT[0].length - beg.length;
if (f < 0)
f = 0;
bi = buffer.indexOf(beg, f);
if (bi === -1)
return;
is = true;
}
if (is) {
ei = buffer.indexOf(end, bi + blength);
if (ei === -1)
return;
}
while (bi !== -1) {
if (skip)
skip--;
else {
if (callback(raw ? buffer.slice(bi, ei + elength) : buffer.toString('utf8', bi, ei + elength), indexer++) === false)
canceled = true;
}
if (canceled)
return;
buffer = buffer.slice(ei + elength);
is = false;
bi = buffer.indexOf(beg);
if (bi === -1)
return;
is = true;
ei = buffer.indexOf(end, bi + blength);
if (ei === -1)
return;
}
};
stream && stream.on('end', () => fn(end));
return fn;
};
exports.streamer2 = function(beg, end, callback, skip, stream) {
return exports.streamer(beg, end, callback, skip, stream, true);
};
exports.filestreamer = function(filename) {
var Fs = require('./textdb-stream');
return new Fs(filename);
};
exports.encode = function(str) {
if (str == null)
return '';
var type = typeof(str);
if (type !== 'string')
str = str.toString();
return str.encode();
};
exports.decode = function(str) {
if (str == null)
return '';
var type = typeof(str);
if (type !== 'string')
str = str.toString();
return str.decode();
};
exports.isStaticFile = function(url) {
var index = url.indexOf('.', url.length - 8);
return index !== -1;
};
exports.parseInt = function(obj, def) {
if (obj == null || obj === '')
return def === undefined ? 0 : def;
var type = typeof(obj);
return type === 'number' ? obj : (type !== 'string' ? obj.toString() : obj).parseInt(def);
};
exports.parseBoolean = function(obj, def) {
if (obj == null)
return def === undefined ? false : def;
var type = typeof(obj);
return type === 'boolean' ? obj : type === 'number' ? obj > 0 : (type !== 'string' ? obj.toString() : obj).parseBoolean(def);
};
exports.parseFloat = function(obj, def) {
if (obj == null || obj === '')
return def === undefined ? 0 : def;
var type = typeof(obj);
return type === 'number' ? obj : (type !== 'string' ? obj.toString() : obj).parseFloat(def);
};
exports.isDate = function(obj) {
return obj instanceof Date && !isNaN(obj.getTime()) ? true : false;
};
exports.getContentType = function(ext) {
if (!ext)
return CT_OCTET;
if (ext[0] === '.')
ext = ext.substring(1);
return CONTENTTYPES[ext] || CT_OCTET;
};
exports.getExtensionFromContentType = function(value) {
for (var key in CONTENTTYPES) {
if (CONTENTTYPES[key] === value)
return key;
}
};
exports.getExtension = function(filename, raw) {
var end = filename.length;
for (var i = filename.length - 1; i > 0; i--) {
var c = filename[i];
if (c === ' ' || c === '?')
end = i;
else if (c === '.') {
c = filename.substring(i + 1, end);
return raw ? c : c.toLowerCase();
}
else if (c === '/' ||