UNPKG

total4

Version:
1,738 lines (1,423 loc) 173 kB
'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 = { '&lt': '<', '&gt': '>', '&quot': '"', '&apos': '\'', '&amp': '&', '&lt;': '<', '&gt;': '>', '&quot;': '"', '&apos;': '\'', '&amp;': '&' }; 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 === '/' ||