UNPKG

catproxy

Version:

a node proxy or host change tools

172 lines (164 loc) 4.97 kB
import zlib from 'zlib'; import log from './log'; import {Buffer} from 'buffer'; import mime from 'mime'; import iconv from 'iconv-lite'; import isbinaryfile from 'isbinaryfile'; import path from 'path'; import betuify from 'js-beautify'; import Promise from 'promise'; // <meta charset="gb2312"> // <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> var checkMetaCharset = /<meta(?:\s)+.*charset(?:\s)*=(?:[\s'"])*([^"']+)/i; export const isJSONStr = /(^(?:\s*\[)[\s\S]*(?:\]\s*)$|(^(?:\s*\{)[\s\S]*(?:\}\s*)$))/; export const isFont = /(^font\/.+)|(^application\/x-font.+)|(^application\/font.+)/; export const isXml =/^\s*\<\?xml.*/; export const isDataUrl = /^data:.+/; export const isImage = /^image\/.+/; export const isMedia = /(^video\/.+)|(^audio\/.+)/; // 这么判断并不准确,最好是用ast,语法树,但是怕性能有问题,就用这个了 // ()中间的参数并不匹配?? export const isJSONP = /^\s*[a-zA-Z$_]+[\w$]*\s*\(([\s\S]*)(\)|(?:\)[\s;]*))$/; // 解压数据 export const decodeCompress = (bodyData, encode) =>{ if (!Buffer.isBuffer(bodyData) || !encode) { return Promise.reject(bodyData); } return new Promise(function(resolve, reject) { // 成功的取到bodyData let isZip = /gzip/i.test(encode); let isDeflate = /deflate/i.test(encode); if (isZip) { zlib.gunzip(bodyData, function(err, buff) { if (err) { log.error(err); reject('decompress err: ', err.message); } else { resolve(buff); } }); } else if(isDeflate) { zlib.inflateRaw(bodyData, function(err, buff) { if (err) { log.error(err); reject('decompress err: ', err.message); } else { resolve(buff); } }); } else { reject("未知的编码"); } }); }; export const isBinary = (buffer) => { let data; if (Buffer.isBuffer(buffer)) { let l = Math.min(512, buffer.length); data = new Buffer(l); buffer.copy(data, 0, 0, l); return isbinaryfile.sync(data, l); } else if (typeof buffer === 'string') { // 通过文件名称判断是否是buffer return false; } return false; }; export const getCharset = (resInfo) => { let charset = 'UTF-8'; let contentType = resInfo.headers['content-type'] || ""; let ext = resInfo.ext; // 在取一次编码 if(contentType) { // 如果contenttype上又编码,则重新设置编码 let tmp = contentType.match(/charset=([^;]+)/); if (tmp && tmp.length > 0) { charset = tmp[1].toUpperCase(); return charset; } } // gbk gb2312文件编码怎么解析?? return charset; }; // 根据请求获取请求的类型主要类型在 config/configProps 下地 monitorType export const getReqType = (result) => { let contentType = result.resHeaders['content-type'] || ""; let type = "other"; let headers = result.reqHeaders; let ext = result.ext; if(headers['x-requested-with']) { type = 'xhr'; } else if (isImage.test(contentType)) { type = 'img'; } else if (contentType === 'text/cache-manifest') { type = "mainifest"; } else if (result.protocol === "ws" || result.protocol == "wss") { type = "ws"; } else if (isFont.test(contentType) || ext === 'ttf' || ext ==='woff' ) { // svg不能算是字体文件,因为svg可能是别的文件 // font/woff2 application/x-font-ttf 2种都是font type = "font"; } else if (ext === 'js' || ext === 'jsx' || ext === 'es6'|| ext === 'json' || ext === 'map') { type = "js"; } else if (ext === 'css' || ext === 'less' || ext === "sass") { type = "css"; } else if (isMedia.test(contentType)) { // 视频 ,音频 type = "media"; } else if (ext === "xhtml" || ext === "html" || ext === "hltm") { type = "doc"; } return type; }; const supportEncode = ["UTF-8", "GBK", "GB2312", "UTF8"]; const supportBetuifyType = { js: ["javascript", "js", "es6", "jsx", "json", "jsonp"], css: ["css", "less", "scass"], html: ["html", 'htm', "ejs"] }; /** * 按照指定格式美化代码 js-betuify */ export let betuifyCode = function(code, ext) { let some = current => ext === current; let is = ""; for (let type in supportBetuifyType) { if (supportBetuifyType[type].some(some)) { is = type; break; } } if (is === 'js') { return betuify(code); } else if (is === 'css') { return betuify.css(code); } else if (is === 'html') { return betuify.html(code); } else { return code; } }; export let updateExt = function(ext, contentType, data = "") { if (isJSONStr.test(data)) { return "json"; } else if (isJSONP.test(data)) { return "jsonp"; } else if (isXml.test(data)) { return 'xml'; } return ext; }; /** * 按照指定编码解码文件 * */ export let decodeData = (data, charset = "utf8") => { return new Promise(function(resolve, reject) { let is = supportEncode.some(cur => charset.toUpperCase() === cur); if (!is) { reject("不支持当前的编码方式:" + charset); } try { resolve(iconv.decode(data, charset)); } catch(e) { reject("解码数据出错"); } }); };