From d5e8a41591e8d0fa6042bd10fd7e1f505962ca65 Mon Sep 17 00:00:00 2001 From: RobinzZH Date: Tue, 22 May 2018 18:42:50 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20travis=20=E7=9A=84=20b?= =?UTF-8?q?adge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f2e7cd4d..995d0583 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # [Tencent Server Web](https://tswjs.org) -[![license](https://img.shields.io/github/license/mashape/apistatus.svg)](./LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/TSW/pulls) [![wiki](https://img.shields.io/badge/Wiki-open-brightgreen.svg)](https://tswjs.org/guide/index) ![node](https://img.shields.io/badge/node-%3E%3D8.0.0-green.svg) +[![license](https://img.shields.io/github/license/mashape/apistatus.svg)](./LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/TSW/pulls) [![wiki](https://img.shields.io/badge/Wiki-open-brightgreen.svg)](https://tswjs.org/guide/index) ![node](https://img.shields.io/badge/node-%3E%3D8.0.0-green.svg) [![Build Status](https://travis-ci.org/Tencent/TSW.svg?branch=master)](https://travis-ci.org/Tencent/TSW) --- From 52adffc99f20d8b83809d87e2a94ca0e3a6285c4 Mon Sep 17 00:00:00 2001 From: maplemiao Date: Tue, 22 May 2018 19:23:03 +0800 Subject: [PATCH 2/7] chore: add .editorconfig --- .editorconfig | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..82da0b16 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +# http://editorconfig.org + +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false \ No newline at end of file From f2877f149fe1491a83d8debb0c5ef9e4a97bd835 Mon Sep 17 00:00:00 2001 From: youkunhuang Date: Tue, 22 May 2018 19:31:06 +0800 Subject: [PATCH 3/7] =?UTF-8?q?examples=20=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/framework/config.js | 6 ++++++ examples/framework/helloworld.js | 3 +++ 2 files changed, 9 insertions(+) diff --git a/examples/framework/config.js b/examples/framework/config.js index 6bf5951e..5d268352 100644 --- a/examples/framework/config.js +++ b/examples/framework/config.js @@ -16,3 +16,9 @@ this.logger = { this.wsRouter = require('./wsRouter.js') +this.alphaFile = `${__dirname}/alpha.txt`; + +//this.appid = 'appid'; +//this.appkey = 'appkey'; + +//https://${appid}.tswjs.org/log/view/xxx \ No newline at end of file diff --git a/examples/framework/helloworld.js b/examples/framework/helloworld.js index 18dd1034..ce64ccf9 100644 --- a/examples/framework/helloworld.js +++ b/examples/framework/helloworld.js @@ -1,8 +1,11 @@ +const logger = plug('logger'); module.exports = function(){ var req = window.request; var res = window.response; + logger.setKey('xxx'); + res.end('hello world'); }; From d23c950e5a0eafb0a94e07aea14e314d4d23bb78 Mon Sep 17 00:00:00 2001 From: Maple Miao <522856232@qq.com> Date: Tue, 22 May 2018 19:39:39 +0800 Subject: [PATCH 4/7] Update .editorconfig --- .editorconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.editorconfig b/.editorconfig index 82da0b16..8786e6e2 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,11 +5,11 @@ root = true [*] charset = utf-8 indent_style = space -indent_size = 2 +indent_size = 4 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true [*.md] insert_final_newline = false -trim_trailing_whitespace = false \ No newline at end of file +trim_trailing_whitespace = false From a518df756a8e733d849051cb77a924223be74b8b Mon Sep 17 00:00:00 2001 From: youkunhuang Date: Tue, 22 May 2018 20:12:39 +0800 Subject: [PATCH 5/7] license=mit --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index ab1b7a04..9c7e9653 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "files": [ "bin" ], + "license": "MIT", "engines": { "node": ">= 8.0.0" }, From 37df35bf9d02e9f384704404bd5128210fc42149 Mon Sep 17 00:00:00 2001 From: neilcui Date: Tue, 22 May 2018 21:34:03 +0800 Subject: [PATCH 6/7] eslint --- .eslintignore | 3 + .eslintrc.json | 42 + .gitignore | 2 +- .travis.yml | 7 +- README.md | 164 +- README_en.md | 152 +- bin/lib/api/L5/L5.api.js | 4 - bin/lib/api/cmdb/index.js | 21 +- bin/lib/api/code/watcher.js | 4 +- bin/lib/api/habo/habo.js | 2 +- bin/lib/api/keyman/alphaMap.js | 228 +- bin/lib/api/keyman/blackIpMap.js | 232 +- bin/lib/api/keyman/index.js | 34 +- bin/lib/api/keyman/ipCheck.js | 10 +- bin/lib/api/keyman/runtimeAdd.js | 15 +- bin/lib/api/libdcapi/dcapi.js | 20 +- bin/lib/api/notify/index.js | 113 +- bin/lib/api/tcss/tcss.js | 2 +- bin/lib/api/tnm2/index.js | 10 +- bin/lib/api/xssFilter/index.js | 9 +- bin/lib/data/cmem.tsw.js | 14 +- bin/lib/default/config.default.h5test.js | 4 +- bin/lib/default/config.default.js | 44 +- bin/lib/default/logReport.js | 46 +- bin/lib/loader/extentions.js | 2 +- bin/lib/runtime/md5.check.js | 4 +- bin/lib/util/gzipHttp.js | 117 +- bin/lib/util/http.more.js | 24 +- bin/lib/util/isTST.js | 12 +- bin/lib/util/mail/.eslintrc.json | 11 + bin/lib/util/mail/mail.js | 258 ++- bin/lib/util/mail/src/_config.js | 18 +- bin/lib/util/mail/tmpl.js | 166 +- bin/lib/util/oa-login/index.js | 8 +- bin/lib/webapp/Server.js | 2 +- bin/lib/webapp/utils/format.js | 10 +- bin/proxy/admin.js | 209 +- bin/proxy/check.js | 2 +- bin/proxy/config.js | 92 +- bin/proxy/http.mod.act.js | 4 +- bin/proxy/http.mod.map.js | 4 +- bin/proxy/http.proxy.js | 739 ++++--- bin/proxy/http.route.js | 1576 +++++++------- bin/proxy/index.js | 42 +- bin/proxy/master.js | 785 ++++--- bin/proxy/top100.sh | 2 +- bin/proxy/websocket.js | 411 ++-- bin/proxy/ws.mod.act.js | 2 +- bin/proxy/ws.mod.map.js | 2 +- bin/proxy/ws.route.js | 92 +- bin/tsw/ajax/ajax.js | 1925 ++++++++--------- bin/tsw/ajax/form.js | 78 +- bin/tsw/ajax/http-https.options.js | 15 +- bin/tsw/ajax/index.js | 2 +- bin/tsw/ajax/token.js | 28 +- bin/tsw/api/date.js | 68 +- bin/tsw/api/fileCache/index.js | 329 ++- bin/tsw/api/logman/index.js | 124 +- bin/tsw/config.js | 4 +- bin/tsw/context.js | 86 +- bin/tsw/default/config.default.sky.js | 92 +- bin/tsw/loader/seajs/lib/helper.js | 100 +- bin/tsw/loader/seajs/lib/sea-node.js | 208 +- bin/tsw/logger.js | 2 +- bin/tsw/plug.js | 114 +- bin/tsw/pool/cmem.l5.js | 190 +- bin/tsw/router.js | 54 +- bin/tsw/runtime/CCFinder.js | 324 ++- bin/tsw/runtime/Console.hack.js | 96 +- bin/tsw/runtime/Context.js | 20 +- bin/tsw/runtime/ContextWrap.js | 84 +- bin/tsw/runtime/Dns.hack.js | 10 +- bin/tsw/runtime/JankWatcher.js | 28 +- bin/tsw/runtime/Window.js | 46 +- bin/tsw/runtime/capturer.js | 409 ++-- bin/tsw/runtime/fs.hack.js | 313 ++- bin/tsw/runtime/overloadProtection.js | 58 +- bin/tsw/serverInfo.js | 77 +- bin/tsw/util/CD.js | 437 ++-- bin/tsw/util/Deferred/index.js | 1072 +++++---- bin/tsw/util/Queue/index.js | 74 +- bin/tsw/util/alpha.js | 2 +- bin/tsw/util/auto-report/.eslintrc.json | 11 + bin/tsw/util/auto-report/TEReport.js | 269 ++- bin/tsw/util/auto-report/alpha.js | 9 +- bin/tsw/util/auto-report/download.js | 1253 ++++++----- bin/tsw/util/auto-report/highlight-tsw.js | 2 +- bin/tsw/util/auto-report/logReport.js | 1194 +++++----- bin/tsw/util/auto-report/post.js | 413 ++-- bin/tsw/util/auto-report/post.openapi.js | 4 +- bin/tsw/util/auto-report/src/_config.js | 18 +- .../util/auto-report/src/download.tmpl.html | 194 +- bin/tsw/util/auto-report/src/mail.tmpl.html | 3 +- bin/tsw/util/auto-report/tmpl.js | 728 ++++--- bin/tsw/util/auto-report/view.js | 276 ++- bin/tsw/util/cache.cleaner.js | 42 +- bin/tsw/util/cpu.js | 370 ++-- bin/tsw/util/h5-test/add.js | 186 +- bin/tsw/util/h5-test/del.js | 182 +- bin/tsw/util/h5-test/get.js | 164 +- bin/tsw/util/h5-test/group/.eslintrc.json | 11 + bin/tsw/util/h5-test/group/src/_config.js | 16 +- bin/tsw/util/h5-test/group/src/main.tmpl.html | 9 +- bin/tsw/util/h5-test/group/tmpl.js | 111 +- bin/tsw/util/h5-test/group/view.js | 90 +- bin/tsw/util/h5-test/is-test.js | 719 +++--- bin/tsw/util/h5-test/page/.eslintrc.json | 11 + bin/tsw/util/h5-test/page/src/_config.js | 16 +- bin/tsw/util/h5-test/page/src/main.tmpl.html | 9 +- .../util/h5-test/page/src/new_body.tmpl.html | 16 +- bin/tsw/util/h5-test/page/tmpl.js | 287 +-- bin/tsw/util/h5-test/page/view.js | 102 +- bin/tsw/util/home/.eslintrc.json | 11 + bin/tsw/util/home/navMenus.js | 38 +- bin/tsw/util/home/src/_config.js | 16 +- bin/tsw/util/home/src/main.tmpl.html | 9 +- bin/tsw/util/home/tmpl.js | 89 +- bin/tsw/util/home/view.js | 30 +- bin/tsw/util/html302/index.js | 48 +- bin/tsw/util/html302/src/_config.js | 16 +- bin/tsw/util/html302/tmpl.js | 28 +- bin/tsw/util/http.isInnerIP.js | 118 +- bin/tsw/util/http.js | 659 +++--- bin/tsw/util/http/parseBody.js | 109 +- bin/tsw/util/http/parseGet.js | 299 ++- bin/tsw/util/isWindows.js | 2 +- bin/tsw/util/logger/callInfo.js | 24 +- bin/tsw/util/logger/index.js | 2 +- bin/tsw/util/logger/logger.config.js | 4 +- bin/tsw/util/logger/logger.js | 1014 +++++---- bin/tsw/util/nodeVersion.js | 40 +- bin/tsw/util/openapi.js | 54 +- bin/tsw/util/process.args.js | 44 +- bin/tsw/util/static/mime.js | 46 +- bin/tsw/util/static/static.js | 237 +- bin/tsw/util/v8-profiler.js | 60 +- bin/tsw/util/xss.js | 164 +- bin/wwwroot/.eslintrc.json | 8 + .../static/tsw/highlightjs/highlight-tsw.js | 1444 ++++++------- bin/wwwroot/static/tsw/zepto/zepto.min.js | 4 +- examples/framework/config.js | 2 +- examples/framework/express.js | 8 +- examples/framework/hapi.js | 26 +- examples/framework/helloworld.js | 7 +- examples/framework/koa.js | 8 +- examples/framework/router.js | 24 +- examples/framework/websocket.js | 12 +- examples/framework/wsRouter.js | 16 +- package.json | 15 +- test/.eslintrc | 2 + test/bin/config.js | 28 + test/bin/tsw/runtime/context.js | 21 + test/bin/tsw/util/CD.test.js | 268 +-- test/bin/tsw/util/cpu.test.js | 161 +- test/bin/tsw/util/openapi.js | 91 +- test/bin/tsw/util/xss.test.js | 40 +- 156 files changed, 12081 insertions(+), 12225 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc.json create mode 100644 bin/lib/util/mail/.eslintrc.json create mode 100644 bin/tsw/util/auto-report/.eslintrc.json create mode 100644 bin/tsw/util/h5-test/group/.eslintrc.json create mode 100644 bin/tsw/util/h5-test/page/.eslintrc.json create mode 100644 bin/tsw/util/home/.eslintrc.json create mode 100644 bin/wwwroot/.eslintrc.json create mode 100644 test/.eslintrc create mode 100644 test/bin/config.js create mode 100644 test/bin/tsw/runtime/context.js diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..1e6079d2 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +bin/wwwroot/**/highlight-tsw.js +bin/wwwroot/**/zepto.min.js +bin/lib/api/L5/L5.api.js \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000..1bcea667 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,42 @@ +{ + "env": { + "node": true, + "commonjs": true, + "es6": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "sourceType": "module", + "ecmaVersion": 2017 + }, + "globals": { + "plug": false, + "window": false, + "context": false, + "define": false + }, + "rules": { + "indent": [ + "error", + 4 + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "single" + ], + "semi": [ + "error", + "always" + ], + "no-unused-vars": [ + "error", + { + "args": "none" + } + ] + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 2aaa9f28..267ef05d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -/node_modules +node_modules .vscode .idea .DS_Store diff --git a/.travis.yml b/.travis.yml index 37d5fac8..7c525c7f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,9 @@ +sudo: false language: node_js node_js: - "8" - - "9" \ No newline at end of file + - "9" + +script: + - npm run lint + - npm test && npm run coverage \ No newline at end of file diff --git a/README.md b/README.md index 995d0583..72f3feec 100644 --- a/README.md +++ b/README.md @@ -1,82 +1,84 @@ -# [Tencent Server Web](https://tswjs.org) - - -[![license](https://img.shields.io/github/license/mashape/apistatus.svg)](./LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/TSW/pulls) [![wiki](https://img.shields.io/badge/Wiki-open-brightgreen.svg)](https://tswjs.org/guide/index) ![node](https://img.shields.io/badge/node-%3E%3D8.0.0-green.svg) [![Build Status](https://travis-ci.org/Tencent/TSW.svg?branch=master)](https://travis-ci.org/Tencent/TSW) - ---- - - -[English Version](./README_en.md) - - -## 简介 - -Tencent Server Web(TSW),是一套面向WEB前端开发者,以提升问题定位效率为初衷,提供染色抓包、全息日志和异常发现的Node.js基础设施。TSW关注业务的运维监控能力,适用于http、websocket协议的业务场景,可无缝与即有项目进行整合。支持公有云、私有云和本地部署。 - -![tsw](./static/resource/structure.png) - -#### 染色抓包 - -TSW 支持用户维度的抓包 - -- 对于指定的用户(白名单内) -- 请求生命周期内,对请求本身及衍生请求进行抓包 -- 提供抓包查看、下载等功能 -- 抓包格式支持Fiddler和Charles,以及HAR - -#### 全息日志 - -TSW 提供用户维度的全息日志帮助开发者快速定位问题 - -- 对请求生命周期内的日志,采用全息的方式记录,形成流水 -- 流水按用户维度聚合 -- 提供查看功能,快速定位问题原因 - -#### 异常发现 - -- 内置指标实时监控 -- 代码异常推送告警 - -## 环境要求 - -- 操作系统: Windows/Mac/Linux -- Node.js: 8.0.0+ - -## 开始 - -1. 请先下载安装[Node.js](https://nodejs.org/en/download/),并且Node.js的版本需不低于8.0.0。 -1. 安装 -- `git clone https://github.com/Tencent/TSW.git` -1. 配置 -- 修改 `TSW/conf/config.js`,更多配置项参考 [手册](https://tswjs.org/doc/api/config) - - ```js - this.httpAddress = '0.0.0.0'; - - this.httpPort = 80; - ``` - -1. 启动 -- ``node TSW`` -1. 预览 -- 打开浏览器,访问 ``http://127.0.0.1/`` 即可 - -## 官方网站 - -- 更多教程 [https://tswjs.org/guide/index](https://tswjs.org/guide/index) - -- 使用手册 [https://tswjs.org/doc/api/index](https://tswjs.org/doc/api/index) - -## 配套设施 - -- TSW开放平台 [https://tswjs.org](https://tswjs.org) - -## 贡献代码 - -如果您使用过程中发现Bug,请通过 [https://github.com/Tencent/TSW/issues](https://github.com/Tencent/TSW/issues) 来提交并描述相关的问题,您也可以在这里查看其它的issue,通过解决这些issue来贡献代码。 - -如果您是第一次贡献代码,请阅读 [CONTRIBUTING](./CONTRIBUTING.md) 了解我们的贡献流程,并提交 pull request 给我们。 - -## 许可证 - -Tencent Server Web 的开源协议为 MIT, 详情参见 [LICENSE](./LICENSE) 。 - -## 联系方式 - +# [Tencent Server Web](https://tswjs.org) + + +[![license](https://img.shields.io/github/license/mashape/apistatus.svg)](./LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/TSW/pulls) [![wiki](https://img.shields.io/badge/Wiki-open-brightgreen.svg)](https://tswjs.org/guide/index) ![node](https://img.shields.io/badge/node-%3E%3D8.0.0-green.svg) [![Build Status](https://travis-ci.org/Tencent/TSW.svg?branch=master)](https://travis-ci.org/Tencent/TSW) + +--- + + +[English Version](./README_en.md) + + +## 简介 + +Tencent Server Web(TSW),是一套面向WEB前端开发者,以提升问题定位效率为初衷,提供染色抓包、全息日志和异常发现的Node.js基础设施。TSW关注业务的运维监控能力,适用于http、websocket协议的业务场景,可无缝与即有项目进行整合。支持公有云、私有云和本地部署。 + +![tsw](./static/resource/structure.png) + +#### 染色抓包 + +TSW 支持用户维度的抓包 + +- 对于指定的用户(白名单内) +- 请求生命周期内,对请求本身及衍生请求进行抓包 +- 提供抓包查看、下载等功能 +- 抓包格式支持Fiddler和Charles,以及HAR + +#### 全息日志 + +TSW 提供用户维度的全息日志帮助开发者快速定位问题 + +- 对请求生命周期内的日志,采用全息的方式记录,形成流水 +- 流水按用户维度聚合 +- 提供查看功能,快速定位问题原因 + +#### 异常发现 + +- 内置指标实时监控 +- 代码异常推送告警 + +## 环境要求 + +- 操作系统: Windows/Mac/Linux +- Node.js: 8.0.0+ + +## 开始 + +1. 需先安装[Node.js](https://nodejs.org/en/download/),并且Node.js的版本需不低于8.0.0。 +1. 安装 -- `git clone https://github.com/Tencent/TSW.git` +1. 切换工作目录 -- `cd TSW` +1. 补全依赖 -- `npm install --no-optional` +1. 配置 -- 修改 `TSW/conf/config.js`,更多配置项参考 [手册](https://tswjs.org/doc/api/config) + + ```js + this.httpAddress = '0.0.0.0'; + + this.httpPort = 80; + ``` + +1. 启动 -- `node index.js` +1. 预览 -- 打开浏览器,访问 `http://127.0.0.1/` 即可 + +## 官方网站 + +- 更多教程 [https://tswjs.org/guide/index](https://tswjs.org/guide/index) + +- 使用手册 [https://tswjs.org/doc/api/index](https://tswjs.org/doc/api/index) + +## 配套设施 + +- TSW开放平台 [https://tswjs.org](https://tswjs.org) + +## 贡献代码 + +如果您使用过程中发现Bug,请通过 [https://github.com/Tencent/TSW/issues](https://github.com/Tencent/TSW/issues) 来提交并描述相关的问题,您也可以在这里查看其它的issue,通过解决这些issue来贡献代码。 + +如果您是第一次贡献代码,请阅读 [CONTRIBUTING](./CONTRIBUTING.md) 了解我们的贡献流程,并提交 pull request 给我们。 + +## 许可证 + +Tencent Server Web 的开源协议为 MIT, 详情参见 [LICENSE](./LICENSE) 。 + +## 联系方式 + tsw@tencent.com \ No newline at end of file diff --git a/README_en.md b/README_en.md index e5dd7f99..26186c4d 100644 --- a/README_en.md +++ b/README_en.md @@ -1,74 +1,78 @@ - -## Introduction - -Tencent Server side Web(TSW) is a Node.js infrastructure which is designed for improving the efficiency of locating problems, providing multiple functions for front-end developers: online dyeing/packet capture, holographic logging and abnormity discovery. TSW, focusing on the operation and maintenance of businesses, is suitable for web and mobile applications based on http or websocket protocols. It can be readily integrated with existing systems. - -![tsw](./static/resource/structure_en.png) - -#### Online dyeing/packet capture - -TSW supports packet capture based on user granularity. - -- Dye labelled user by users' feature IDs -- Collect packets within corresponding requests' lifecycles for dyed users. -- Provid functions to view and download captured packets. -- Support Fiddler(windows), Charles(mac) and HAR format. - -#### Holographic logging - -TSW provides powerful logging abilities for developers to locate problems quickly. - -- Record packets within requests' lifecycles holographically in the form of log flow. -- Aggregate log flows based on user granularity. -- View log flows by user features. Help analyzing and solving problems efficiently. - -#### Abnormity discovery - -- Monitor preset indicators in real time -- Push alarms for code exceptions - -## Requirement -- OS: Windows/Mac/Linux -- Node.js: 8.0.0+ - -## Getting started - -- Before installing, [download and install Node.js](https://nodejs.org/en/download/). Node.js 8.0.0 or higher is required. - -- Clone the repo: ``git clone https://github.com/Tencent/TSW.git`` - -- Config ``TSW/conf/config.js`` - ```js - this.httpAddress = '0.0.0.0' - - this.httpPort = 80; - ``` - -- Run ``node TSW`` to start Node.js server - -- Open `http://127.0.0.1/` in your browser. - - -## Documentation - -- More Tutorials [https://tswjs.org/guide/index](https://tswjs.org/guide/index) - -- Manual [https://tswjs.org/doc/api/index](https://tswjs.org/doc/api/index) - -## Supporting facilities - -- TSW Open Platform [https://tswjs.org](https://tswjs.org) - -## Contributing - -Find a bug or have a feature request? Please read the [issues](https://github.com/Tencent/TSW/issues) guidelines and search for existing and closed issues. - -If your problem or idea is not addressed yet, please read through our [contributing guidelines](./CONTRIBUTING.md) and open a new [issues](https://github.com/Tencent/TSW/issues). - -## License - -Tencent Server Web is released under [MIT license](./LICENSE). - -## Contacts - -tsw@tencent.com + +## Introduction + +Tencent Server side Web(TSW) is a Node.js infrastructure which is designed for improving the efficiency of locating problems, providing multiple functions for front-end developers: online dyeing/packet capture, holographic logging and abnormity discovery. TSW, focusing on the operation and maintenance of businesses, is suitable for web and mobile applications based on http or websocket protocols. It can be readily integrated with existing systems. + +![tsw](./static/resource/structure_en.png) + +#### Online dyeing/packet capture + +TSW supports packet capture based on user granularity. + +- Dye labelled user by users' feature IDs +- Collect packets within corresponding requests' lifecycles for dyed users. +- Provid functions to view and download captured packets. +- Support Fiddler(windows), Charles(mac) and HAR format. + +#### Holographic logging + +TSW provides powerful logging abilities for developers to locate problems quickly. + +- Record packets within requests' lifecycles holographically in the form of log flow. +- Aggregate log flows based on user granularity. +- View log flows by user features. Help analyzing and solving problems efficiently. + +#### Abnormity discovery + +- Monitor preset indicators in real time +- Push alarms for code exceptions + +## Requirement +- OS: Windows/Mac/Linux +- Node.js: 8.0.0+ + +## Getting started + +- Before installing, [download and install Node.js](https://nodejs.org/en/download/). Node.js 8.0.0 or higher is required. + +- Clone the repo: `git clone https://github.com/Tencent/TSW.git` + +- Enter the TSW: `cd TSW` + +- NPM : `npm install --no-optional` + +- Config ``TSW/conf/config.js`` + ```js + this.httpAddress = '0.0.0.0' + + this.httpPort = 80; + ``` + +- Run `node index.js` to start Node.js server + +- Open `http://127.0.0.1/` in your browser. + + +## Documentation + +- More Tutorials [https://tswjs.org/guide/index](https://tswjs.org/guide/index) + +- Manual [https://tswjs.org/doc/api/index](https://tswjs.org/doc/api/index) + +## Supporting facilities + +- TSW Open Platform [https://tswjs.org](https://tswjs.org) + +## Contributing + +Find a bug or have a feature request? Please read the [issues](https://github.com/Tencent/TSW/issues) guidelines and search for existing and closed issues. + +If your problem or idea is not addressed yet, please read through our [contributing guidelines](./CONTRIBUTING.md) and open a new [issues](https://github.com/Tencent/TSW/issues). + +## License + +Tencent Server Web is released under [MIT license](./LICENSE). + +## Contacts + +tsw@tencent.com diff --git a/bin/lib/api/L5/L5.api.js b/bin/lib/api/L5/L5.api.js index 6c1a975b..e4107793 100644 --- a/bin/lib/api/L5/L5.api.js +++ b/bin/lib/api/L5/L5.api.js @@ -68,7 +68,3 @@ this.ApiRouteResultUpdateSync = function(options){ //多一组方法 this.updateRoute = this.ApiRouteResultUpdateSync; this.getRouteAsync = this.ApiGetRoute; - - - - diff --git a/bin/lib/api/cmdb/index.js b/bin/lib/api/cmdb/index.js index 7bae6318..bf0966e6 100644 --- a/bin/lib/api/cmdb/index.js +++ b/bin/lib/api/cmdb/index.js @@ -5,29 +5,28 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const Deferred = require('util/Deferred'); this.GetDeviceThisServer = function(){ - var defer = Deferred.create(); + var defer = Deferred.create(); - return defer.resolve(null); -} + return defer.resolve(null); +}; /** * 查询父业务树信息 */ this.GetAllParentBusiness = function(opt){ - var defer = Deferred.create(); + var defer = Deferred.create(); - return defer.resolve(null); -} + return defer.resolve(null); +}; this.GetDeviceByIp = function(opt){ - var defer = Deferred.create(); - - return defer.resolve(null); -} + var defer = Deferred.create(); + return defer.resolve(null); +}; diff --git a/bin/lib/api/code/watcher.js b/bin/lib/api/code/watcher.js index 77ea1e1b..407cd12e 100644 --- a/bin/lib/api/code/watcher.js +++ b/bin/lib/api/code/watcher.js @@ -5,9 +5,9 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; this.watch = function(){ -} +}; diff --git a/bin/lib/api/habo/habo.js b/bin/lib/api/habo/habo.js index dbcd52df..c54c17f2 100644 --- a/bin/lib/api/habo/habo.js +++ b/bin/lib/api/habo/habo.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; module.exports.report = function(obj, rate) { diff --git a/bin/lib/api/keyman/alphaMap.js b/bin/lib/api/keyman/alphaMap.js index 52276afa..6908e270 100644 --- a/bin/lib/api/keyman/alphaMap.js +++ b/bin/lib/api/keyman/alphaMap.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const Deferred = require('util/Deferred'); const logger = require('logger'); @@ -16,176 +16,176 @@ const fileUrl = config.alphaFileUrl; var isFirstLoad = false; var cache = { - timeUpdate: 0, - data: {}, - dataFile: {} + timeUpdate: 0, + data: {}, + dataFile: {} }; if(global[__filename]){ - cache = global[__filename]; + cache = global[__filename]; }else{ - global[__filename] = cache; - isFirstLoad = true; + global[__filename] = cache; + isFirstLoad = true; } if(isFirstLoad){ - if(config.alphaFile){ - - (function(){ - //导入alphaFile - var text = ''; - - try{ - text = fs.readFileSync(config.alphaFile,'UTF-8'); - }catch(e){ - logger.warn(e.stack); - } - - if(!text){ - return; - } - - if(text.length >= 2 * 1024 * 1024){ - logger.error('alpha file limit <=2M'); - return; - } - - cache.dataFile = getMap(text); - updateMap(); - })(); - - }else{ - logger.debug('config.alphaFile is: ' + config.alphaFile); - } + if(config.alphaFile){ + + (function(){ + //导入alphaFile + var text = ''; + + try{ + text = fs.readFileSync(config.alphaFile,'UTF-8'); + }catch(e){ + logger.warn(e.stack); + } + + if(!text){ + return; + } + + if(text.length >= 2 * 1024 * 1024){ + logger.error('alpha file limit <=2M'); + return; + } + + cache.dataFile = getMap(text); + updateMap(); + })(); + + }else{ + logger.debug('config.alphaFile is: ' + config.alphaFile); + } } function getMap(text){ - var map = {}; + var map = {}; - text = text || ''; + text = text || ''; - text.replace(/^([0-9a-zA-Z_\-]+).*$/gm,function($0,key){ - map[key] = 1; - }); + text.replace(/^([0-9a-zA-Z_-]+).*$/gm,function($0,key){ + map[key] = 1; + }); - return map; + return map; } function updateMap(text){ - var map = getMap(text); + var map = getMap(text); - //copy - Object.assign(map,cache.dataFile) + //copy + Object.assign(map,cache.dataFile); - cache.data = map; + cache.data = map; - logger.debug('update ok'); + logger.debug('update ok'); } this.getSync = function(){ - this.get(); + this.get(); - return cache.data; -} + return cache.data; +}; this.get = function(){ - var defer = Deferred.create(); - var delay = (process.serverInfo && process.serverInfo.cpu * 1000) || 0; - var l5api = config.tswL5api['alphaFileUrl']; + var defer = Deferred.create(); + var delay = (process.serverInfo && process.serverInfo.cpu * 1000) || 0; + var l5api = config.tswL5api['alphaFileUrl']; - if(Date.now() - cache.timeUpdate < 60000 + delay){ - return defer.resolve(cache.data); - } + if(Date.now() - cache.timeUpdate < 60000 + delay){ + return defer.resolve(cache.data); + } - cache.timeUpdate = Date.now(); + cache.timeUpdate = Date.now(); - if(!fileUrl){ - return defer.resolve(cache.data); - } + if(!fileUrl){ + return defer.resolve(cache.data); + } - fileCache.getAsync(fileUrl).done(function(d){ + fileCache.getAsync(fileUrl).done(function(d){ - var lastModifyTime = 0; - var text = ''; + var lastModifyTime = 0; + var text = ''; - if(d && d.stats){ - lastModifyTime = d.stats.mtime.getTime(); - } + if(d && d.stats){ + lastModifyTime = d.stats.mtime.getTime(); + } - if(d && d.data){ - text = d.data.toString('utf-8'); - } + if(d && d.data){ + text = d.data.toString('utf-8'); + } - if(Date.now() - lastModifyTime < 60000){ - logger.debug('使用本地文件'); + if(Date.now() - lastModifyTime < 60000){ + logger.debug('使用本地文件'); - updateMap(text); + updateMap(text); - defer.resolve(cache.data); - return; - } + defer.resolve(cache.data); + return; + } - require('ajax').request({ - url: fileUrl, - type: 'get', - autoToken: false, - l5api: l5api, - devIp: config.tswDevIp, - devPort: config.tswDevPort, - retry: 0, - dcapi: { - key: 'EVENT_TSW_ALPHA_FILE_URL' - }, - dataType: 'text' - }).fail(function(d){ - defer.resolve(cache.data); - }).done(function(d){ + require('ajax').request({ + url: fileUrl, + type: 'get', + autoToken: false, + l5api: l5api, + devIp: config.tswDevIp, + devPort: config.tswDevPort, + retry: 0, + dcapi: { + key: 'EVENT_TSW_ALPHA_FILE_URL' + }, + dataType: 'text' + }).fail(function(d){ + defer.resolve(cache.data); + }).done(function(d){ - var text = ''; + var text = ''; - if(d && d.result && typeof d.result === 'string'){ + if(d && d.result && typeof d.result === 'string'){ - text = d.result; - } + text = d.result; + } - if(text.length >= 2 * 1024 * 1024){ - logger.error('alpha file limit <=2M'); - return defer.resolve(cache.data); - } + if(text.length >= 2 * 1024 * 1024){ + logger.error('alpha file limit <=2M'); + return defer.resolve(cache.data); + } - updateMap(text) + updateMap(text); - //保存在本地 - fileCache.set(fileUrl,Buffer.from(text,'UTF-8')); + //保存在本地 + fileCache.set(fileUrl,Buffer.from(text,'UTF-8')); - defer.resolve(cache.data); - }); - }); + defer.resolve(cache.data); + }); + }); - return defer; -} + return defer; +}; function init(){ - var buffer = null; - var text = ''; + var buffer = null; + var text = ''; - if(fileUrl){ - buffer = fileCache.getSync(fileUrl).data; - } + if(fileUrl){ + buffer = fileCache.getSync(fileUrl).data; + } - if(buffer){ - text = buffer.toString('utf-8'); - updateMap(text); - }; + if(buffer){ + text = buffer.toString('utf-8'); + updateMap(text); + } } diff --git a/bin/lib/api/keyman/blackIpMap.js b/bin/lib/api/keyman/blackIpMap.js index 70a1adb0..1ac6f9a1 100644 --- a/bin/lib/api/keyman/blackIpMap.js +++ b/bin/lib/api/keyman/blackIpMap.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const Deferred = require('util/Deferred'); const logger = require('logger'); @@ -16,180 +16,180 @@ const fileUrl = config.blackIpFileUrl; var isFirstLoad = false; var cache = { - timeUpdate: 0, - data: {}, - dataFile: {} + timeUpdate: 0, + data: {}, + dataFile: {} }; if(global[__filename]){ - cache = global[__filename]; + cache = global[__filename]; }else{ - global[__filename] = cache; - isFirstLoad = true; + global[__filename] = cache; + isFirstLoad = true; } if(isFirstLoad){ - if(config.blackIpFile){ - - (function(){ - //导入blackIpFile - var text = ''; - - try{ - text = fs.readFileSync(config.blackIpFile,'UTF-8'); - }catch(e){ - logger.warn(e.stack); - } - - if(!text){ - return; - } - - if(text.length >= 2 * 1024 * 1024){ - logger.error('blackIp file limit <=2M'); - return; - } - - cache.dataFile = getMap(text); - updateMap(); - })(); - - }else{ - logger.debug('config.blackIpFile is: ' + config.blackIpFile); - } + if(config.blackIpFile){ + + (function(){ + //导入blackIpFile + var text = ''; + + try{ + text = fs.readFileSync(config.blackIpFile,'UTF-8'); + }catch(e){ + logger.warn(e.stack); + } + + if(!text){ + return; + } + + if(text.length >= 2 * 1024 * 1024){ + logger.error('blackIp file limit <=2M'); + return; + } + + cache.dataFile = getMap(text); + updateMap(); + })(); + + }else{ + logger.debug('config.blackIpFile is: ' + config.blackIpFile); + } } init(); function init(){ - var buffer = null; - var text = ''; + var buffer = null; + var text = ''; - if(fileUrl){ - buffer = fileCache.getSync(fileUrl).data; - } + if(fileUrl){ + buffer = fileCache.getSync(fileUrl).data; + } - if(buffer){ - text = buffer.toString('utf-8'); - updateMap(text); - }; + if(buffer){ + text = buffer.toString('utf-8'); + updateMap(text); + } } this.getFileMapSync = function(){ - return cache.dataFile; -} + return cache.dataFile; +}; this.getSync = function(){ - this.get(); + this.get(); - return cache.data; -} + return cache.data; +}; function getMap(text){ - var map = {}; + var map = {}; - text = text || ''; + text = text || ''; - text.replace(/^([0-9][0-9\.\*]+).*$/gm,function($0,key){ - map[key] = 1; - }); + text.replace(/^([0-9][0-9.*]+).*$/gm,function($0,key){ + map[key] = 1; + }); - return map; + return map; } function updateMap(text){ - var map = getMap(text); + var map = getMap(text); - //copy - Object.assign(map,cache.dataFile) + //copy + Object.assign(map,cache.dataFile); - cache.data = map; + cache.data = map; - logger.debug('update ok'); + logger.debug('update ok'); } this.get = function(){ - var defer = Deferred.create(); - var delay = ((process.serverInfo && process.serverInfo.cpu) * 1000) || 0; - var l5api = config.tswL5api['blackIpFileUrl']; + var defer = Deferred.create(); + var delay = ((process.serverInfo && process.serverInfo.cpu) * 1000) || 0; + var l5api = config.tswL5api['blackIpFileUrl']; - if(Date.now() - cache.timeUpdate < 300000 + delay){ - return defer.resolve(cache.data); - } + if(Date.now() - cache.timeUpdate < 300000 + delay){ + return defer.resolve(cache.data); + } - cache.timeUpdate = Date.now(); + cache.timeUpdate = Date.now(); - if(!fileUrl){ - return defer.resolve(cache.data); - } + if(!fileUrl){ + return defer.resolve(cache.data); + } - fileCache.getAsync(fileUrl).done(function(d){ + fileCache.getAsync(fileUrl).done(function(d){ - var lastModifyTime = 0; - var text = ''; + var lastModifyTime = 0; + var text = ''; - if(d && d.stats){ - lastModifyTime = d.stats.mtime.getTime(); - } + if(d && d.stats){ + lastModifyTime = d.stats.mtime.getTime(); + } - if(d && d.data){ - text = d.data.toString('utf-8'); - } + if(d && d.data){ + text = d.data.toString('utf-8'); + } - if(Date.now() - lastModifyTime < 300000){ - logger.debug('使用本地文件'); + if(Date.now() - lastModifyTime < 300000){ + logger.debug('使用本地文件'); - updateMap(text); + updateMap(text); - defer.resolve(cache.data); - return; - } + defer.resolve(cache.data); + return; + } - require('ajax').request({ - url: fileUrl, - type: 'get', - autoToken: false, - l5api: l5api, - devIp: config.tswDevIp, - devPort: config.tswDevPort, - retry: 0, - dcapi: { - key: 'EVENT_TSW_BLACKIP_FILE_URL' - }, - dataType: 'text' - }).fail(function(d){ - defer.resolve(cache.data); - }).done(function(d){ + require('ajax').request({ + url: fileUrl, + type: 'get', + autoToken: false, + l5api: l5api, + devIp: config.tswDevIp, + devPort: config.tswDevPort, + retry: 0, + dcapi: { + key: 'EVENT_TSW_BLACKIP_FILE_URL' + }, + dataType: 'text' + }).fail(function(d){ + defer.resolve(cache.data); + }).done(function(d){ - var text = ''; + var text = ''; - if(d && d.result && typeof d.result === 'string'){ + if(d && d.result && typeof d.result === 'string'){ - text = d.result; - } + text = d.result; + } - if(text.length >= 2 * 1024 * 1024){ - logger.error('blackIp file limit <=2M'); - return defer.resolve(cache.data); - } + if(text.length >= 2 * 1024 * 1024){ + logger.error('blackIp file limit <=2M'); + return defer.resolve(cache.data); + } - updateMap(text); + updateMap(text); - //保存在本地 - fileCache.set(fileUrl,Buffer.from(text,'UTF-8')); + //保存在本地 + fileCache.set(fileUrl,Buffer.from(text,'UTF-8')); - defer.resolve(cache.data); - }); - }); + defer.resolve(cache.data); + }); + }); - return defer; -} + return defer; +}; diff --git a/bin/lib/api/keyman/index.js b/bin/lib/api/keyman/index.js index 6b85d1e5..9477d390 100644 --- a/bin/lib/api/keyman/index.js +++ b/bin/lib/api/keyman/index.js @@ -5,36 +5,36 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; this.getBlockIpMapSync = function(){ - return require('./blackIpMap.js').getSync(); -} + return require('./blackIpMap.js').getSync(); +}; this.getBlockIpMap = function(){ - return require('./blackIpMap.js').get(); -} + return require('./blackIpMap.js').get(); +}; this.getAlphaUinMapSync = function(){ - return require('./alphaMap.js').getSync(); -} + return require('./alphaMap.js').getSync(); +}; this.getAlphaUinMap = function(){ - return require('./alphaMap.js').get(); -} + return require('./alphaMap.js').get(); +}; this.getTestIp = function(group){ - return require('util/auto-report/TEReport.js').list(group); -} + return require('util/auto-report/TEReport.js').list(group); +}; this.getAllGroup = function(){ - return require('util/auto-report/TEReport.js').getAllGroup(); -} + return require('util/auto-report/TEReport.js').getAllGroup(); +}; this.ipCheck = function(opt){ - return require('./ipCheck.js').info(opt); -} + return require('./ipCheck.js').info(opt); +}; this.runtimeAdd = function(opt){ - return require('./runtimeAdd.js').add(opt); -} \ No newline at end of file + return require('./runtimeAdd.js').add(opt); +}; \ No newline at end of file diff --git a/bin/lib/api/keyman/ipCheck.js b/bin/lib/api/keyman/ipCheck.js index 5acc54f0..39602cfe 100644 --- a/bin/lib/api/keyman/ipCheck.js +++ b/bin/lib/api/keyman/ipCheck.js @@ -5,15 +5,13 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; -const fs = require('fs'); const Deferred = require('util/Deferred'); -const logger = require('logger'); this.info = function(opt){ - var defer = Deferred.create(); + var defer = Deferred.create(); - return defer.reject(); -} + return defer.reject(); +}; diff --git a/bin/lib/api/keyman/runtimeAdd.js b/bin/lib/api/keyman/runtimeAdd.js index 1d8c4caa..367501a6 100644 --- a/bin/lib/api/keyman/runtimeAdd.js +++ b/bin/lib/api/keyman/runtimeAdd.js @@ -5,19 +5,16 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const Deferred = require('util/Deferred'); -const logger = require('logger'); -const config = require('config'); -const isWindows = require('util/isWindows'); this.add = function(opt){ - var defer = Deferred.create(); + var defer = Deferred.create(); - return defer.resolve(); -} + return defer.resolve(); +}; /** * @@ -25,8 +22,8 @@ this.add = function(opt){ * */ this.hello = function(){ - return; -} + return; +}; diff --git a/bin/lib/api/libdcapi/dcapi.js b/bin/lib/api/libdcapi/dcapi.js index d2842057..ef0d4fad 100644 --- a/bin/lib/api/libdcapi/dcapi.js +++ b/bin/lib/api/libdcapi/dcapi.js @@ -5,26 +5,20 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; - -const logger = require('logger'); -const {isWindows} = require('util/isWindows.js'); -const serverInfo = require('serverInfo.js'); -const config = require('config'); -const dcapiCache = {}; +'use strict'; this.baselog = function(table, param) { - return this.reportLog({ - table : table, - data : param - }); + return this.reportLog({ + table : table, + data : param + }); }; this.reportLog = function(opt){ -} +}; this.report = function(opt) { -} +}; diff --git a/bin/lib/api/notify/index.js b/bin/lib/api/notify/index.js index 0fad6bb4..6183ed33 100644 --- a/bin/lib/api/notify/index.js +++ b/bin/lib/api/notify/index.js @@ -5,85 +5,82 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; -const Deferred = require('util/Deferred'); -const auth = require('./util/auth.js'); -const logger = require('logger'); -const config = require('config'); +const Deferred = require('util/Deferred'); this.DecryptTicketWithClientIP = function(opt){ - var defer = Deferred.create(); + var defer = Deferred.create(); - return defer.resolve(); -} + return defer.resolve(); +}; this.SendRTX = function(opt){ - var defer = Deferred.create(); + var defer = Deferred.create(); - return defer.resolve(); -} + return defer.resolve(); +}; this.SendMail = function(opt){ - - opt = Deferred.extend({ - 'appKey' : '', - 'sysId' : 0, - 'EmailType' : 1, //邮件类型,可选值0(外部邮件),1(内部邮件),2(约会邮件) - 'From' : '', //邮件发送人 - 'To' : '', //邮件接收人 - 'Title' : '', //邮件标题 - 'Content' : '', //邮件内容 - 'Priority' : 0, //邮件优先级,-1低优先级,0普通,1高优先级 - 'BodyFormat' : 0, //邮件格式,0 文本、1 Html - - 'CC' : '', //邮件抄送人 - 'Bcc' : '', //邮件密送人 - 'Location' : '', //当邮件为约会邮件时,约会地点 - 'Organizer' : '', //当邮件为约会邮件时,约会组织者 - 'StartTime' : '', //当邮件为约会邮件时,约会开始时间 - 'EndTime' : '', //当邮件为约会邮件时,约会结束时间 - 'attachment' : '' //邮件附件的文件名以及文件的内容(在发送请求时,文件内容是二进制数据流的形式发送) - },opt); - - var defer = Deferred.create(); - - return defer.resolve(); -} + + opt = Deferred.extend({ + 'appKey' : '', + 'sysId' : 0, + 'EmailType' : 1, //邮件类型,可选值0(外部邮件),1(内部邮件),2(约会邮件) + 'From' : '', //邮件发送人 + 'To' : '', //邮件接收人 + 'Title' : '', //邮件标题 + 'Content' : '', //邮件内容 + 'Priority' : 0, //邮件优先级,-1低优先级,0普通,1高优先级 + 'BodyFormat' : 0, //邮件格式,0 文本、1 Html + + 'CC' : '', //邮件抄送人 + 'Bcc' : '', //邮件密送人 + 'Location' : '', //当邮件为约会邮件时,约会地点 + 'Organizer' : '', //当邮件为约会邮件时,约会组织者 + 'StartTime' : '', //当邮件为约会邮件时,约会开始时间 + 'EndTime' : '', //当邮件为约会邮件时,约会结束时间 + 'attachment' : '' //邮件附件的文件名以及文件的内容(在发送请求时,文件内容是二进制数据流的形式发送) + },opt); + + var defer = Deferred.create(); + + return defer.resolve(); +}; this.SendWeiXin = function(opt){ - opt = Deferred.extend({ - 'appKey' : '', - 'sysId' : 0, - 'MsgInfo' : '', //内容 - 'Priority' : 0, //优先级,-1低优先级,0普通,1高优先级 - 'Receiver' : '', //接收人,英文名,多人用英文分号分隔 - 'Sender' : '' //发送人 - },opt); + opt = Deferred.extend({ + 'appKey' : '', + 'sysId' : 0, + 'MsgInfo' : '', //内容 + 'Priority' : 0, //优先级,-1低优先级,0普通,1高优先级 + 'Receiver' : '', //接收人,英文名,多人用英文分号分隔 + 'Sender' : '' //发送人 + },opt); - var defer = Deferred.create(); + var defer = Deferred.create(); - return defer.resolve(); -} + return defer.resolve(); +}; this.SendSMS = function(opt){ - opt = Deferred.extend({ - 'appKey' : '', - 'sysId' : 0, - 'MsgInfo' : '', //内容 - 'Priority' : 0, //优先级,-1低优先级,0普通,1高优先级 - 'Receiver' : '', //接收人,英文名,多人用英文分号分隔 - 'Sender' : '' //发送人 - },opt); + opt = Deferred.extend({ + 'appKey' : '', + 'sysId' : 0, + 'MsgInfo' : '', //内容 + 'Priority' : 0, //优先级,-1低优先级,0普通,1高优先级 + 'Receiver' : '', //接收人,英文名,多人用英文分号分隔 + 'Sender' : '' //发送人 + },opt); - var defer = Deferred.create(); + var defer = Deferred.create(); - return defer.resolve(); -} + return defer.resolve(); +}; diff --git a/bin/lib/api/tcss/tcss.js b/bin/lib/api/tcss/tcss.js index 96f24841..219ee2ca 100644 --- a/bin/lib/api/tcss/tcss.js +++ b/bin/lib/api/tcss/tcss.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; this.pv = function(dm, url, rate) { diff --git a/bin/lib/api/tnm2/index.js b/bin/lib/api/tnm2/index.js index bed5fd66..6708c4d6 100644 --- a/bin/lib/api/tnm2/index.js +++ b/bin/lib/api/tnm2/index.js @@ -5,10 +5,10 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const serverInfo = require('serverInfo.js'); -const mapping = require("./mapping.json"); +const mapping = require('./mapping.json'); const {isWindows} = require('util/isWindows.js'); const url = require('url'); const Deferred = require('util/Deferred'); @@ -85,12 +85,12 @@ var cacheOrRepoet = function(attr, iValue){ cache.time = now; reportOpenapi(last); -} +}; var reportOpenapi = function(last){ var defer = Deferred.create(); - var ajax = require('ajax'); + var openapi = require('util/openapi'); var logger = require('logger'); var config = require('config'); @@ -173,4 +173,4 @@ var reportOpenapi = function(last){ }); return defer; -} \ No newline at end of file +}; \ No newline at end of file diff --git a/bin/lib/api/xssFilter/index.js b/bin/lib/api/xssFilter/index.js index 9be4d8f7..4791a489 100644 --- a/bin/lib/api/xssFilter/index.js +++ b/bin/lib/api/xssFilter/index.js @@ -5,14 +5,13 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; -const logger = require('logger'); const Deferred = require('util/Deferred'); this.check = function(){ - var defer = Deferred.create(); + var defer = Deferred.create(); - return defer.resolve(); -} + return defer.resolve(); +}; diff --git a/bin/lib/data/cmem.tsw.js b/bin/lib/data/cmem.tsw.js index ac35b0b3..735ad166 100644 --- a/bin/lib/data/cmem.tsw.js +++ b/bin/lib/data/cmem.tsw.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const config = require('config'); const cmem = require('pool/cmem.l5.js'); @@ -21,24 +21,24 @@ this.cmem = function(){ } return this.sz(); -} +}; this.openapi = function(){ return cmem(config.memcached); -} +}; this.h5test = function(){ return cmem(config.memcached); -} +}; this.sz = function(){ return cmem(config.memcached); -} +}; this.sh = function(){ return cmem(config.memcached); -} +}; this.tj = function(){ return cmem(config.memcached); -} +}; diff --git a/bin/lib/default/config.default.h5test.js b/bin/lib/default/config.default.h5test.js index 2350334b..47fe74e8 100644 --- a/bin/lib/default/config.default.h5test.js +++ b/bin/lib/default/config.default.h5test.js @@ -5,13 +5,15 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; this.isTest = true; Object.assign(this,require('./config.default.js')); if(process.mainModule === module){ + /* eslint-disable no-console */ console.log(this); + /* eslint-enable no-console */ } diff --git a/bin/lib/default/config.default.js b/bin/lib/default/config.default.js index ce451034..c428347d 100644 --- a/bin/lib/default/config.default.js +++ b/bin/lib/default/config.default.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; this.defaultConfigLoadFrom = __filename; @@ -71,17 +71,17 @@ this.workerUid = 'nobody'; //mod_act映射 this.modAct = { - getModAct: function(req){ - return null; - } + getModAct: function(req){ + return null; + } }; //路由 this.modMap = { - find: function(mod_act,req,res){ - return null; - } -} + find: function(mod_act,req,res){ + return null; + } +}; this.isCloud = false; @@ -91,7 +91,7 @@ this.page404 = null; //logger this.logger = { - logLevel: 'debug' + logLevel: 'debug' }; //cpu限制 @@ -112,29 +112,29 @@ this.idc = 'sz'; this.l5api = {}; this.timeout = { - socket : 120000, - post : 30000, - get : 10000, - keepAlive : 10000, - dns : 3000 -} + socket : 120000, + post : 30000, + get : 10000, + keepAlive : 10000, + dns : 3000 +}; this.extendMod = { - getUin: req => {} + getUin: req => {} }; //openapi -this.logReportUrl = "https://openapi.tswjs.org/v1/log/report"; -this.h5testSyncUrl = "https://openapi.tswjs.org/v1/h5test/sync"; -this.utilCDUrl = "https://openapi.tswjs.org/v1/util/cd"; -this.appReportUrl = "https://openapi.tswjs.org/v1/app/report"; -this.runtimeReportUrl = "https://openapi.tswjs.org/v1/runtime/report"; +this.logReportUrl = 'https://openapi.tswjs.org/v1/log/report'; +this.h5testSyncUrl = 'https://openapi.tswjs.org/v1/h5test/sync'; +this.utilCDUrl = 'https://openapi.tswjs.org/v1/util/cd'; +this.appReportUrl = 'https://openapi.tswjs.org/v1/app/report'; +this.runtimeReportUrl = 'https://openapi.tswjs.org/v1/runtime/report'; this.ignoreTST = false; this.ajaxDefaultOptions = { - useJsonParseOnly : true + useJsonParseOnly : true }; this.tswL5api = {}; diff --git a/bin/lib/default/logReport.js b/bin/lib/default/logReport.js index 8429f72c..746af273 100644 --- a/bin/lib/default/logReport.js +++ b/bin/lib/default/logReport.js @@ -5,32 +5,32 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const config = require('config'); module.exports.report = function(data){ - var retValue; - var reportData = { - table:"reportData", - data:{ - type : data.type, - log : data.logText, - uin : data.key, - mod_act : data.mod_act, - ua : data.ua, - userip : data.userip, - domain : data.host, - path : data.pathname, - httpCode: data.statusCode - } - }; + var retValue; + var reportData = { + table:'reportData', + data:{ + type : data.type, + log : data.logText, + uin : data.key, + mod_act : data.mod_act, + ua : data.ua, + userip : data.userip, + domain : data.host, + path : data.pathname, + httpCode: data.statusCode + } + }; - if(config.beforeReportLog && typeof config.beforeReportLog === 'function'){ - retValue = config.beforeReportLog(reportData); - } + if(config.beforeReportLog && typeof config.beforeReportLog === 'function'){ + retValue = config.beforeReportLog(reportData); + } - if(retValue === false){ - return; - } -} + if(retValue === false){ + return; + } +}; diff --git a/bin/lib/loader/extentions.js b/bin/lib/loader/extentions.js index 66cdaa9f..bb6991d1 100644 --- a/bin/lib/loader/extentions.js +++ b/bin/lib/loader/extentions.js @@ -5,4 +5,4 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; \ No newline at end of file +'use strict'; \ No newline at end of file diff --git a/bin/lib/runtime/md5.check.js b/bin/lib/runtime/md5.check.js index 3f25ad44..071a604a 100644 --- a/bin/lib/runtime/md5.check.js +++ b/bin/lib/runtime/md5.check.js @@ -5,10 +5,10 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; -this.check = function(root){} +this.check = function(root){}; this.findNodeCpp = function(curr){}; diff --git a/bin/lib/util/gzipHttp.js b/bin/lib/util/gzipHttp.js index c33f1a4d..4ab22c7e 100644 --- a/bin/lib/util/gzipHttp.js +++ b/bin/lib/util/gzipHttp.js @@ -5,101 +5,92 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const zlib = require('zlib'); -const stream = require('stream'); const logger = require('logger'); const crypto = require('crypto'); const httpUtil = require('util/http.js'); -const Deferred = require('util/Deferred'); const defaultChunkSize = 8 * 1024; this.httpUtil = httpUtil; this.create = this.getGzipResponse = function(opt){ - var window = context.window || {}; - var request = opt.request || window.request; - var response = opt.response ||window.response; + var window = context.window || {}; - if(!request || !response || response.headersSent){ - return {write:()=>{},end:()=>{},flush:()=>{}}; - } + opt = opt || {}; - var opt = opt || {}, - code = opt.code || 200, - headers = opt.headers || null, - chunkSize = opt.chunkSize || defaultChunkSize, - etag = opt.etag || null, - contentType = opt.contentType || (headers && headers['content-type']) || 'text/html; charset=UTF-8', - gzipOutputStream, - i; + var request = opt.request || window.request, + response = opt.response ||window.response, + code = opt.code || 200, + headers = opt.headers || null, + chunkSize = opt.chunkSize || defaultChunkSize, + contentType = opt.contentType || (headers && headers['content-type']) || 'text/html; charset=UTF-8', + gzipOutputStream; - if(headers && headers['content-length'] !== undefined){ - response.useChunkedEncodingByDefault = false; - delete headers['transfer-encoding']; - delete headers['content-length']; - delete headers['content-encoding']; - } + if(headers && headers['content-length'] !== undefined){ + response.useChunkedEncodingByDefault = false; + delete headers['transfer-encoding']; + delete headers['content-length']; + delete headers['content-encoding']; + } - response.setHeader('Content-Type', contentType); + response.setHeader('Content-Type', contentType); - var headerAcceptDiff = String(request.headers['accept-diff']); - - if(/\bgzip\b/.test(request.headers['accept-encoding'])){ + if(/\bgzip\b/.test(request.headers['accept-encoding'])){ - response.setHeader('Content-Encoding', 'gzip'); - response.writeHead(code,headers); + response.setHeader('Content-Encoding', 'gzip'); + response.writeHead(code,headers); - response.socket && response.socket.setNoDelay(true); - gzipOutputStream = zlib.createGzip({ - chunkSize: chunkSize - }); + response.socket && response.socket.setNoDelay(true); + gzipOutputStream = zlib.createGzip({ + chunkSize: chunkSize + }); - gzipOutputStream.on('data',function(buffer){ - logger.debug('gzip chunked send ${len}',{ - len: buffer.length - }); + gzipOutputStream.on('data',function(buffer){ + logger.debug('gzip chunked send ${len}',{ + len: buffer.length + }); - if(!response.finished){ - response.write(buffer); - } - }); + if(!response.finished){ + response.write(buffer); + } + }); - gzipOutputStream.once('end',function(){ - response.end(); - }); + gzipOutputStream.once('end',function(){ + response.end(); + }); - return gzipOutputStream; + return gzipOutputStream; - }else{ + }else{ - response.writeHead(code,headers); + response.writeHead(code,headers); - response.on('data',function(buffer){ - logger.debug('chunked send ${len}',{ - len: buffer.length - }); - }); + response.on('data',function(buffer){ + logger.debug('chunked send ${len}',{ + len: buffer.length + }); + }); - if(!response.flush){ - response.flush = function(){return true;}; - } + if(!response.flush){ + response.flush = function(){return true;}; + } - if(response.flush && response.flushHeaders){ - response.flush = function(){return true;}; - } + if(response.flush && response.flushHeaders){ + response.flush = function(){return true;}; + } - return response; - } + return response; + } -} +}; /** 从buffer获取SHA1的方法,独立出来其实是为了方便测试 */ exports.getSHA1 = function(buffer){ - return crypto.createHash('sha1').update(buffer).digest('hex') -} + return crypto.createHash('sha1').update(buffer).digest('hex'); +}; diff --git a/bin/lib/util/http.more.js b/bin/lib/util/http.more.js index 98fc0126..80a44cd2 100644 --- a/bin/lib/util/http.more.js +++ b/bin/lib/util/http.more.js @@ -5,25 +5,19 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; - -const {isWindows} = require('util/isWindows'); -const os = require('os'); -const serverInfo = require('serverInfo.js'); -const logger = require('logger'); -const Deferred = require('util/Deferred'); +'use strict'; this.isFromWns = function(request){ - return false; -} + return false; +}; this.getIpCromQuia = function(qvia){ - return null; -} + return null; +}; this.getBase = function(request){ - return ''; -} + return ''; +}; this.fixPicUrl = function(url){ - return ''; -} + return ''; +}; diff --git a/bin/lib/util/isTST.js b/bin/lib/util/isTST.js index 8f48a9f3..d443929f 100644 --- a/bin/lib/util/isTST.js +++ b/bin/lib/util/isTST.js @@ -5,17 +5,17 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const config = require('config'); //是否安全扫描器请求 this.isTST = function(request){ - if(config.extendMod && typeof config.extendMod.isTST === 'function'){ - return config.extendMod.isTST(request); - } + if(config.extendMod && typeof config.extendMod.isTST === 'function'){ + return config.extendMod.isTST(request); + } - return false; -} + return false; +}; diff --git a/bin/lib/util/mail/.eslintrc.json b/bin/lib/util/mail/.eslintrc.json new file mode 100644 index 00000000..0e4b665b --- /dev/null +++ b/bin/lib/util/mail/.eslintrc.json @@ -0,0 +1,11 @@ +{ + "rules": { + "no-unused-vars": [ + "error", + { + "varsIgnorePattern": "out", + "args": "none" + } + ] + } +} \ No newline at end of file diff --git a/bin/lib/util/mail/mail.js b/bin/lib/util/mail/mail.js index dfcaa567..f5076835 100644 --- a/bin/lib/util/mail/mail.js +++ b/bin/lib/util/mail/mail.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const serverInfo = require('serverInfo.js'); const config = require('config.js'); @@ -14,155 +14,153 @@ const httpUtil = require('util/http'); const logger = require('logger'); const Deferred = require('util/Deferred'); const url = require('url'); -const crypto = require('crypto'); this.SendMail = function(key,group,second,oriOpt){ - var opt = Deferred.extend({},oriOpt); - var data = {}; - var now = new Date(); - var prefix = '[runtime]'; - - if(isWindows.isWindows){ - return; - } - - //晚上不发 - //allDaySend强制全天候24小时发送 - if(!opt.allDaySend && now.getHours() < 8){ - return; - } - - if(context.title){ - opt.Title = `[${context.title}]${opt.Title}`; - } - - if(config.isTest){ - prefix += '[测试环境]'; - }else{ - if(opt.runtimeType){ - prefix += `[${opt.runtimeType}][考核]`; - } - } - - opt.Title = prefix + opt.Title; - - data.Title = opt.Title || ''; - data.isTest = ~~config.isTest; - data.Content = opt.Content || ''; - data.MsgInfo = opt.MsgInfo || ''; - data.intranetIp = serverInfo.intranetIp || ''; - data.second = second || ''; - data.idc = config.idc || ''; - data.logText = logger.getText() || ''; - data.headerText = httpUtil.getRequestHeaderStr() || ''; - data.runtimeType = opt.runtimeType || ''; - data.processTitle = process.title || ''; - data.processPid = process.pid || ''; - - opt.data = data; - - if(isWindows.isWindows){ - key = key + Date.now(); - } - - process.nextTick(function(){ - require('util/CD.js').check(key,1,second).done(function(){ - reportOpenapi(data); - }); - }); -} + var opt = Deferred.extend({},oriOpt); + var data = {}; + var now = new Date(); + var prefix = '[runtime]'; + + if(isWindows.isWindows){ + return; + } + + //晚上不发 + //allDaySend强制全天候24小时发送 + if(!opt.allDaySend && now.getHours() < 8){ + return; + } + + if(context.title){ + opt.Title = `[${context.title}]${opt.Title}`; + } + + if(config.isTest){ + prefix += '[测试环境]'; + }else{ + if(opt.runtimeType){ + prefix += `[${opt.runtimeType}][考核]`; + } + } + + opt.Title = prefix + opt.Title; + + data.Title = opt.Title || ''; + data.isTest = ~~config.isTest; + data.Content = opt.Content || ''; + data.MsgInfo = opt.MsgInfo || ''; + data.intranetIp = serverInfo.intranetIp || ''; + data.second = second || ''; + data.idc = config.idc || ''; + data.logText = logger.getText() || ''; + data.headerText = httpUtil.getRequestHeaderStr() || ''; + data.runtimeType = opt.runtimeType || ''; + data.processTitle = process.title || ''; + data.processPid = process.pid || ''; + + opt.data = data; + + if(isWindows.isWindows){ + key = key + Date.now(); + } + + process.nextTick(function(){ + require('util/CD.js').check(key,1,second).done(function(){ + reportOpenapi(data); + }); + }); +}; var reportOpenapi = function(data){ - var defer = Deferred.create(); - var config = require('config'); - var ajax = require('ajax'); - var openapi = require('util/openapi'); - var logger = require('logger'); - - var retCall; - - if(typeof config.beforeRuntimeReport === 'function'){ - retCall = config.beforeRuntimeReport(data); - } - - //阻止默认上报 - if(retCall === false){ - return defer.resolve(0);; - } - - if(!config.appid || !config.appkey){ - return; - } - - if(!config.runtimeReportUrl){ - return; - } - - var postData = data; - - postData.appid = config.appid; - postData.now = Date.now(); - - var sig = openapi.signature({ - pathname : url.parse(config.runtimeReportUrl).pathname, - method : 'POST', - data : postData, - appkey : config.appkey - }); - - postData.sig = sig; - - require('ajax').request({ - url : config.runtimeReportUrl, - type : 'POST', - l5api : config.tswL5api['openapi.tswjs.org'], - dcapi : { - key: 'EVENT_TSW_OPENAPI_RUNTIME_REPORT' - }, - data : postData, - keepAlive : true, - autoToken : false, - dataType : 'json' - }).fail(function(){ - logger.error('runtime report fail.'); - defer.reject(); - }).done(function(d){ - if(d.result){ - if(d.result.code === 0){ - logger.debug('runtime report success.'); - return defer.resolve(); - }else{ - logger.debug('runtime report fail.'); - return defer.reject(d.result.code); - } - } - - logger.debug('runtime report fail.'); - return defer.reject(); - }); - - return defer; -} + var defer = Deferred.create(); + var config = require('config'); + var openapi = require('util/openapi'); + var logger = require('logger'); + + var retCall; + + if(typeof config.beforeRuntimeReport === 'function'){ + retCall = config.beforeRuntimeReport(data); + } + + //阻止默认上报 + if(retCall === false){ + return defer.resolve(0); + } + + if(!config.appid || !config.appkey){ + return; + } + + if(!config.runtimeReportUrl){ + return; + } + + var postData = data; + + postData.appid = config.appid; + postData.now = Date.now(); + + var sig = openapi.signature({ + pathname : url.parse(config.runtimeReportUrl).pathname, + method : 'POST', + data : postData, + appkey : config.appkey + }); + + postData.sig = sig; + + require('ajax').request({ + url : config.runtimeReportUrl, + type : 'POST', + l5api : config.tswL5api['openapi.tswjs.org'], + dcapi : { + key: 'EVENT_TSW_OPENAPI_RUNTIME_REPORT' + }, + data : postData, + keepAlive : true, + autoToken : false, + dataType : 'json' + }).fail(function(){ + logger.error('runtime report fail.'); + defer.reject(); + }).done(function(d){ + if(d.result){ + if(d.result.code === 0){ + logger.debug('runtime report success.'); + return defer.resolve(); + }else{ + logger.debug('runtime report fail.'); + return defer.reject(d.result.code); + } + } + + logger.debug('runtime report fail.'); + return defer.reject(); + }); + + return defer; +}; //升级周知 this.SendTSWMail = function(opt){ -} +}; //发送周知邮件 this.SendArsMail = function(opt){ -} +}; this.findMailARS = function(file){ - return ''; -} + return ''; +}; diff --git a/bin/lib/util/mail/src/_config.js b/bin/lib/util/mail/src/_config.js index ed4d6036..09597f20 100644 --- a/bin/lib/util/mail/src/_config.js +++ b/bin/lib/util/mail/src/_config.js @@ -5,19 +5,19 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; define(function(require, exports, module){ - return { + return { - tmpl: { - create: true - }, - all: { - create: false - } + tmpl: { + create: true + }, + all: { + create: false + } - }; + }; }); \ No newline at end of file diff --git a/bin/lib/util/mail/tmpl.js b/bin/lib/util/mail/tmpl.js index aad23016..6ec2b32d 100644 --- a/bin/lib/util/mail/tmpl.js +++ b/bin/lib/util/mail/tmpl.js @@ -1,83 +1,83 @@ - -//tmpl file list: -//mail/src/mail.tmpl.html -define(function(require, exports, module){ -var tmpl = { -'encodeHtml': function(s){return (s+'').replace(/[\x26\x3c\x3e\x27\x22\x60]/g,function($0){return '&#'+$0.charCodeAt(0)+';';});}, - -'email': function(data){ - -var __p=[],_p=function(s){__p.push(s)},out=_p; - - -var window = context.window || {}; -__p.push('\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n

'); -_p(data.Content); -__p.push('

\n

服务器IP: '); -_p(data.intranetIp); -__p.push('

\n\n

进程名字: '); -_p(tmpl.encodeHtml(data.processTitle)); -__p.push('

\n

进程ID: '); -_p(data.processPid.pid); -__p.push('

\n

mod_act: '); -_p(context.mod_act || 'null'); -__p.push('

'); -if(window.request){__p.push('

域名: '); -_p(window.request && window.request.headers.host); -__p.push('

\n

path: '); -_p(window.request && window.request.REQUEST.pathname); -__p.push('

'); -}__p.push('

idc: '); -_p(data.idc); -__p.push('

\n

发送间隔: '); -_p(data.second); -__p.push('s

'); -if(data.headerText){__p.push('

请求头:

\n
'); -_p(tmpl.encodeHtml(data.headerText || '').replace(/\r\n|\r|\n/g,'
')); -__p.push('
'); -}__p.push(' '); -if(data.logText){__p.push('

全息日志:

\n
');
-_p(tmpl.encodeHtml(data.logText || '').replace(/\r\n|\r|\n/g,'
')); -__p.push('
'); -}__p.push('\n'); - -return __p.join(""); -}, - -'rtx': function(data){ - -var __p=[],_p=function(s){__p.push(s)},out=_p; - - -var window = context.window || {}; -_p(data.MsgInfo); -_p('\r\n\r\n'); -__p.push('服务器IP:'); -_p(data.intranetIp); -_p('\r\n'); -__p.push('进程名字: '); -_p(tmpl.encodeHtml(process.title)); -_p('\r\n'); -__p.push('进程ID: '); -_p(process.pid); -_p('\r\n'); -__p.push('mod_act: '); -_p(context.mod_act || 'null'); -_p('\r\n'); -__p.push('域名:'); -_p(window.request && window.request.headers.host); -_p('\r\n'); -__p.push('path:'); -_p(window.request && window.request.REQUEST.pathname); -_p('\r\n'); -__p.push('发送间隔: '); -_p(data.second); -__p.push('s'); -_p('\r\n'); -__p.push(''); - -return __p.join(""); -} -}; -return tmpl; -}); + +//tmpl file list: +//mail/src/mail.tmpl.html +define(function(require, exports, module){ + var tmpl = { + 'encodeHtml': function(s){return (s+'').replace(/[\x26\x3c\x3e\x27\x22\x60]/g,function($0){return '&#'+$0.charCodeAt(0)+';';});}, + + 'email': function(data){ + + var __p=[],_p=function(s){__p.push(s);},out=_p; + + + var window = context.window || {}; + __p.push('\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n

'); + _p(data.Content); + __p.push('

\n

服务器IP: '); + _p(data.intranetIp); + __p.push('

\n\n

进程名字: '); + _p(tmpl.encodeHtml(data.processTitle)); + __p.push('

\n

进程ID: '); + _p(data.processPid.pid); + __p.push('

\n

mod_act: '); + _p(context.mod_act || 'null'); + __p.push('

'); + if(window.request){__p.push('

域名: '); + _p(window.request && window.request.headers.host); + __p.push('

\n

path: '); + _p(window.request && window.request.REQUEST.pathname); + __p.push('

'); + }__p.push('

idc: '); + _p(data.idc); + __p.push('

\n

发送间隔: '); + _p(data.second); + __p.push('s

'); + if(data.headerText){__p.push('

请求头:

\n
'); + _p(tmpl.encodeHtml(data.headerText || '').replace(/\r\n|\r|\n/g,'
')); + __p.push('
'); + }__p.push(' '); + if(data.logText){__p.push('

全息日志:

\n
');
+                _p(tmpl.encodeHtml(data.logText || '').replace(/\r\n|\r|\n/g,'
')); + __p.push('
'); + }__p.push('\n'); + + return __p.join(''); + }, + + 'rtx': function(data){ + + var __p=[],_p=function(s){__p.push(s);},out=_p; + + + var window = context.window || {}; + _p(data.MsgInfo); + _p('\r\n\r\n'); + __p.push('服务器IP:'); + _p(data.intranetIp); + _p('\r\n'); + __p.push('进程名字: '); + _p(tmpl.encodeHtml(process.title)); + _p('\r\n'); + __p.push('进程ID: '); + _p(process.pid); + _p('\r\n'); + __p.push('mod_act: '); + _p(context.mod_act || 'null'); + _p('\r\n'); + __p.push('域名:'); + _p(window.request && window.request.headers.host); + _p('\r\n'); + __p.push('path:'); + _p(window.request && window.request.REQUEST.pathname); + _p('\r\n'); + __p.push('发送间隔: '); + _p(data.second); + __p.push('s'); + _p('\r\n'); + __p.push(''); + + return __p.join(''); + } + }; + return tmpl; +}); diff --git a/bin/lib/util/oa-login/index.js b/bin/lib/util/oa-login/index.js index b2d0b537..dc651e93 100644 --- a/bin/lib/util/oa-login/index.js +++ b/bin/lib/util/oa-login/index.js @@ -5,11 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; - -const gzipHttp = plug('util/gzipHttp'); -const httpUtil = plug('util/http'); -const logger = plug('logger') +'use strict'; module.exports = function(request, response, callback, tofCfg){ callback(); @@ -17,4 +13,4 @@ module.exports = function(request, response, callback, tofCfg){ module.exports.checkLoginForTSW = function(request, response, callback){ callback(); -} \ No newline at end of file +}; \ No newline at end of file diff --git a/bin/lib/webapp/Server.js b/bin/lib/webapp/Server.js index 2919248e..305af58a 100644 --- a/bin/lib/webapp/Server.js +++ b/bin/lib/webapp/Server.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; this.startServer = function(){ diff --git a/bin/lib/webapp/utils/format.js b/bin/lib/webapp/utils/format.js index d15cb030..9bbd34b3 100644 --- a/bin/lib/webapp/utils/format.js +++ b/bin/lib/webapp/utils/format.js @@ -5,26 +5,26 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; function formatBuffer(buffer) { - if(!(buffer && buffer.length)){ + if(!(buffer && buffer.length)){ return ''; } - var str = ""; + var str = ''; for (var i = 0, len = buffer.length; i < len; i++) { if(i % 16 === 0){ str += '0x' + ('00000000000' + i.toString(16)).slice(-8) + ': '; } - str += (buffer[i] > 15 ? "" : "0") + buffer[i].toString(16).toUpperCase() + (((i+1) % 16 == 0) ? "\n" : (i % 2 === 0 ? '' : ' ')); + str += (buffer[i] > 15 ? '' : '0') + buffer[i].toString(16).toUpperCase() + (((i+1) % 16 == 0) ? '\n' : (i % 2 === 0 ? '' : ' ')); } return str; } module.exports = { - formatBuffer + formatBuffer }; \ No newline at end of file diff --git a/bin/proxy/admin.js b/bin/proxy/admin.js index 5f6752d2..ab7f065e 100644 --- a/bin/proxy/admin.js +++ b/bin/proxy/admin.js @@ -6,7 +6,7 @@ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const logger = require('logger'); const config = require('./config.js'); @@ -14,129 +14,126 @@ const http = require('http'); const codeWatch = require('api/code/watcher.js'); const parseGet = require('util/http/parseGet.js'); const cp = require('child_process'); -const serverInfo = { - cpu: 'M' -}; const server = http.createServer(function(req, res){ - var action; + var action; - logger.info('admin request by: ${url}',{ - url: req.url - }); + logger.info('admin request by: ${url}',{ + url: req.url + }); - //解析get参数 - parseGet(req); + //解析get参数 + parseGet(req); - action = methodMap[req.REQUEST.pathname] || methodMap['default']; + action = methodMap[req.REQUEST.pathname] || methodMap['default']; - action.apply(methodMap,arguments); + action.apply(methodMap,arguments); }); logger.info('start admin'); server.listen(config.httpAdminPort,'127.0.0.1',function(err){ - if(err){ - logger.info('admin listen error ${address}:${port}',{ - address: '127.0.0.1', - port: config.httpAdminPort - }); - }else{ - logger.info('admin listen ok ${address}:${port}',{ - address: '127.0.0.1', - port: config.httpAdminPort - }); - } + if(err){ + logger.info('admin listen error ${address}:${port}',{ + address: '127.0.0.1', + port: config.httpAdminPort + }); + }else{ + logger.info('admin listen ok ${address}:${port}',{ + address: '127.0.0.1', + port: config.httpAdminPort + }); + } }); const methodMap = { - 'default' : function(req, res){ - res.writeHead(200, {'Content-Type': 'text/plain; charset=UTF-8'}); - res.end('no such command!'); - }, - - '/globaldump' : function(req, res){ - process.emit('sendCmd2workerOnce',{ - CMD: 'globaldump', - GET: req.GET - }); - res.writeHead(200, {'Content-Type': 'text/plain; charset=UTF-8'}); - res.end('done!\r\n'); - }, - - '/heapdump' : function(req, res){ - process.emit('sendCmd2workerOnce',{ - CMD: 'heapdump', - GET: req.GET - }); - res.writeHead(200, {'Content-Type': 'text/plain; charset=UTF-8'}); - res.end('done!\r\n'); - }, - - '/profiler' : function(req, res){ - process.emit('sendCmd2workerOnce',{ - CMD: 'profiler', - GET: req.GET - }); - res.writeHead(200, {'Content-Type': 'text/plain; charset=UTF-8'}); - res.end('done!\r\n'); - }, - - '/top100' : function(req, res){ - process.emit('sendCmd2workerOnce',{ - CMD: 'top100', - GET: req.GET - }); - res.writeHead(200, {'Content-Type': 'text/plain; charset=UTF-8'}); - res.end('done!\r\n'); - }, - - '/reload' : function(req, res){ - - cp.exec('./check.js',{ - timeout: 5000, - cwd: __dirname - },function(err, stdout, stderr){ - if(err){ - logger.error(err.stack); - res.writeHead(200, {'Content-Type': 'text/plain; charset=UTF-8'}); - res.write(err.stack); - res.socket && res.socket.end(); - - return; - } - - if(stderr && stderr.length > 0){ - - logger.error(stderr.toString('UTF-8')); - res.writeHead(200, {'Content-Type': 'text/plain; charset=UTF-8'}); - res.write(stderr.toString('UTF-8')); - - res.socket && res.socket.end(); - return; - } - - if(stdout && stdout.length > 0){ - logger.info(stdout.toString('UTF-8')); - - process.emit('reload',req.GET); - - res.writeHead(200, {'Content-Type': 'text/plain; charset=UTF-8'}); - res.write(stderr.toString('UTF-8')); - res.end('\r\ndone!\r\n'); - - return; - } - - }); - - } - -} + 'default' : function(req, res){ + res.writeHead(200, {'Content-Type': 'text/plain; charset=UTF-8'}); + res.end('no such command!'); + }, + + '/globaldump' : function(req, res){ + process.emit('sendCmd2workerOnce',{ + CMD: 'globaldump', + GET: req.GET + }); + res.writeHead(200, {'Content-Type': 'text/plain; charset=UTF-8'}); + res.end('done!\r\n'); + }, + + '/heapdump' : function(req, res){ + process.emit('sendCmd2workerOnce',{ + CMD: 'heapdump', + GET: req.GET + }); + res.writeHead(200, {'Content-Type': 'text/plain; charset=UTF-8'}); + res.end('done!\r\n'); + }, + + '/profiler' : function(req, res){ + process.emit('sendCmd2workerOnce',{ + CMD: 'profiler', + GET: req.GET + }); + res.writeHead(200, {'Content-Type': 'text/plain; charset=UTF-8'}); + res.end('done!\r\n'); + }, + + '/top100' : function(req, res){ + process.emit('sendCmd2workerOnce',{ + CMD: 'top100', + GET: req.GET + }); + res.writeHead(200, {'Content-Type': 'text/plain; charset=UTF-8'}); + res.end('done!\r\n'); + }, + + '/reload' : function(req, res){ + + cp.exec('./check.js',{ + timeout: 5000, + cwd: __dirname + },function(err, stdout, stderr){ + if(err){ + logger.error(err.stack); + res.writeHead(200, {'Content-Type': 'text/plain; charset=UTF-8'}); + res.write(err.stack); + res.socket && res.socket.end(); + + return; + } + + if(stderr && stderr.length > 0){ + + logger.error(stderr.toString('UTF-8')); + res.writeHead(200, {'Content-Type': 'text/plain; charset=UTF-8'}); + res.write(stderr.toString('UTF-8')); + + res.socket && res.socket.end(); + return; + } + + if(stdout && stdout.length > 0){ + logger.info(stdout.toString('UTF-8')); + + process.emit('reload',req.GET); + + res.writeHead(200, {'Content-Type': 'text/plain; charset=UTF-8'}); + res.write(stderr.toString('UTF-8')); + res.end('\r\ndone!\r\n'); + + return; + } + + }); + + } + +}; logger.setLogLevel(0); codeWatch.watch(); diff --git a/bin/proxy/check.js b/bin/proxy/check.js index 558cc984..5a5f2e31 100644 --- a/bin/proxy/check.js +++ b/bin/proxy/check.js @@ -7,7 +7,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; try{ diff --git a/bin/proxy/config.js b/bin/proxy/config.js index 3a4cf245..49877d6e 100644 --- a/bin/proxy/config.js +++ b/bin/proxy/config.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const fs = require('fs'); const path = require('path'); @@ -15,44 +15,44 @@ const defaultValue = plug('default/config.default.js'); var isFirstLoad = false; var cache = { - config: null + config: null }; if(global[__filename]){ - cache = global[__filename]; + cache = global[__filename]; }else{ - global[__filename] = cache; - isFirstLoad = true; + global[__filename] = cache; + isFirstLoad = true; } if(isFirstLoad){ - process.dlopen = function(fn){ - var parent = path.join(__dirname , '..'); - - return function(module,curr){ - //检查node私有文件 - if(/\.node$/i.test(curr) && curr.indexOf(parent) !== 0){ - //发现私有node扩展 - setTimeout(function(){ - require('runtime/md5.check.js').findNodeCpp(curr); - },3000) - } - return fn.apply(this, arguments); - } - }(process.dlopen); + process.dlopen = function(fn){ + var parent = path.join(__dirname , '..'); + + return function(module,curr){ + //检查node私有文件 + if(/\.node$/i.test(curr) && curr.indexOf(parent) !== 0){ + //发现私有node扩展 + setTimeout(function(){ + require('runtime/md5.check.js').findNodeCpp(curr); + },3000); + } + return fn.apply(this, arguments); + }; + }(process.dlopen); } if(fs.existsSync('/etc/tsw.config.js')){ - cache.config = require('/usr/local/node_modules/config.js'); + cache.config = require('/usr/local/node_modules/config.js'); }else if(fs.existsSync('/usr/local/node_modules/config.js')){ - cache.config = require('/usr/local/node_modules/config.js'); + cache.config = require('/usr/local/node_modules/config.js'); }else if(fs.existsSync('/data/release/node_modules/config.js')){ - cache.config = require('/data/release/node_modules/config.js'); + cache.config = require('/data/release/node_modules/config.js'); }else if(fs.existsSync(__dirname + '/../../conf/config.js')){ - cache.config = require('../../conf/config.js'); + cache.config = require('../../conf/config.js'); } @@ -61,36 +61,36 @@ Deferred.extend(true,exports,defaultValue,cache.config); if(exports.router){ - exports.modAct = { - getModAct : function(req){ - return exports.router.name(req); - } - } - exports.modMap = { - find : function(name,req,res){ - return exports.router.find(name,req,res); - } - } + exports.modAct = { + getModAct : function(req){ + return exports.router.name(req); + } + }; + exports.modMap = { + find : function(name,req,res){ + return exports.router.find(name,req,res); + } + }; } if(exports.wsRouter){ - exports.wsModAct = { - getModAct : function(ws){ - return exports.wsRouter.name(ws); - } - } - exports.wsModMap = { - find : function(name,ws){ - return exports.wsRouter.find(name,ws); - } - } + exports.wsModAct = { + getModAct : function(ws){ + return exports.wsRouter.name(ws); + } + }; + exports.wsModMap = { + find : function(name,ws){ + return exports.wsRouter.find(name,ws); + } + }; } module.exports = exports; if(process.mainModule === module){ - console.log(exports); + /* eslint-disable no-console */ + console.log(exports); + /* eslint-enable no-console */ } - - diff --git a/bin/proxy/http.mod.act.js b/bin/proxy/http.mod.act.js index 87fedb09..9cd832d1 100644 --- a/bin/proxy/http.mod.act.js +++ b/bin/proxy/http.mod.act.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const config = require('./config.js'); var base = null; @@ -26,7 +26,7 @@ if(base){ } return config.modAct.getModAct(req); - } + }; }else{ module.exports = config.modAct; } diff --git a/bin/proxy/http.mod.map.js b/bin/proxy/http.mod.map.js index db2b7815..8c889d91 100644 --- a/bin/proxy/http.mod.map.js +++ b/bin/proxy/http.mod.map.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const config = require('./config.js'); var base = null; @@ -24,7 +24,7 @@ if(base){ return mod; } return config.modMap.find(mod_act,req,res); - } + }; }else{ module.exports = config.modMap; diff --git a/bin/proxy/http.proxy.js b/bin/proxy/http.proxy.js index 3a2433dd..b922b04c 100644 --- a/bin/proxy/http.proxy.js +++ b/bin/proxy/http.proxy.js @@ -5,27 +5,22 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; process.on('uncaughtException',function(e){ - logger.error(e && e.stack); + logger.error(e && e.stack); }); -const plug = require('../tsw/plug.js'); const logger = require('logger'); const http = require('http'); const https = require('https'); const cluster = require('cluster'); const util = require('util'); const fs = require('fs'); -const os = require('os'); -const path = require('path'); const cp = require('child_process'); -const domain = require('domain'); const parseGet = require('util/http/parseGet.js'); const tnm2 = require('api/tnm2'); -const dcapi = require('api/libdcapi/dcapi.js'); const cpuUtil = require('util/cpu.js'); const httpUtil = require('util/http.js'); const TEReport = require('util/auto-report/TEReport.js'); @@ -37,9 +32,9 @@ const methodMap = {}; const {isWindows} = require('util/isWindows.js'); const {debugOptions} = process.binding('config'); const serverInfo = { - intranetIp: require('serverInfo.js').intranetIp, - cpu: 'X' - }; + intranetIp: require('serverInfo.js').intranetIp, + cpu: 'X' +}; var server; var serverThis; var serverHttps; @@ -53,55 +48,55 @@ var heartBeatCount = 0; function doRoute(req,res){ - if(routeCache === null){ - routeCache = require('./http.route.js'); - config = require('./config.js'); - } + if(routeCache === null){ + routeCache = require('./http.route.js'); + config = require('./config.js'); + } - if(req.headers['user-agent'] === 'nws' && req.headers.host === serverInfo.intranetIp){ - //nws探测请求 - res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'}); - res.end('hello nws'); + if(req.headers['user-agent'] === 'nws' && req.headers.host === serverInfo.intranetIp){ + //nws探测请求 + res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'}); + res.end('hello nws'); - return; - } + return; + } - if(req.headers['user-agent'] === 'TgwProbe'){ - //stgw探测请求 - res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'}); - res.end('hello TgwProbe'); + if(req.headers['user-agent'] === 'TgwProbe'){ + //stgw探测请求 + res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'}); + res.end('hello TgwProbe'); - return; - } + return; + } - if(req.headers['user-agent'] === 'StgwProbe'){ - //stgw探测请求 - res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'}); - res.end('hello StgwProbe'); + if(req.headers['user-agent'] === 'StgwProbe'){ + //stgw探测请求 + res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'}); + res.end('hello StgwProbe'); - return; - } + return; + } - if(req.headers['user-agent'] === 'TgwProbe'){ - //stgw探测请求 - res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'}); - res.end('hello TgwProbe'); + if(req.headers['user-agent'] === 'TgwProbe'){ + //stgw探测请求 + res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'}); + res.end('hello TgwProbe'); - return; - } + return; + } - if(req.REQUEST.pathname === '/' && !req.headers['user-agent']){ + if(req.REQUEST.pathname === '/' && !req.headers['user-agent']){ - if(httpUtil.isInnerIP(httpUtil.getUserIp(req))){ - //l7探测请求 - res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'}); - res.end('hello l7'); - return; - } + if(httpUtil.isInnerIP(httpUtil.getUserIp(req))){ + //l7探测请求 + res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'}); + res.end('hello l7'); + return; + } - } + } - routeCache(req,res); + routeCache(req,res); } process.serverInfo = serverInfo; @@ -111,109 +106,109 @@ process.serverInfo = serverInfo; */ function cleanCache(){ - clearTimeout(cleanCacheTid); + clearTimeout(cleanCacheTid); - cleanCacheTid = setTimeout(function(){ - require('util/cache.cleaner.js').clear('/'); - routeCache = null; + cleanCacheTid = setTimeout(function(){ + require('util/cache.cleaner.js').clear('/'); + routeCache = null; - },5000); + },5000); } process.on('top100',function(e){ - logger.info('top100'); - global.top100 = []; + logger.info('top100'); + global.top100 = []; }); process.on('heapdump',function(e){ - logger.info('heapdump'); + logger.info('heapdump'); - if(!isWindows){ + if(!isWindows){ - require('heapdump').writeSnapshot(__dirname + '/cpu' + serverInfo.cpu + '.' + Date.now() + '.heapsnapshot',function(err, filename) { - logger.info('dump written to ${filename}', { - filename: filename - }); - }); + require('heapdump').writeSnapshot(__dirname + '/cpu' + serverInfo.cpu + '.' + Date.now() + '.heapsnapshot',function(err, filename) { + logger.info('dump written to ${filename}', { + filename: filename + }); + }); - } + } }); process.on('profiler',function(data = {}){ - logger.info('profiler time: ${time}', data); + logger.info('profiler time: ${time}', data); - if(!isWindows){ + if(!isWindows){ - require('util/v8-profiler.js').writeProfilerOpt(__dirname + '/cpu' + serverInfo.cpu + '.' + Date.now() + '.cpuprofile', { - recordTime: data.time || 5000 - }, function(filename) { - logger.info('dump written to ${filename}', { - filename: filename - }); - }); + require('util/v8-profiler.js').writeProfilerOpt(__dirname + '/cpu' + serverInfo.cpu + '.' + Date.now() + '.cpuprofile', { + recordTime: data.time || 5000 + }, function(filename) { + logger.info('dump written to ${filename}', { + filename: filename + }); + }); - } + } }); //process.emit('globaldump',m.GET); process.on('globaldump',function(GET){ - var cpu = GET.cpu || 0; - var depth = GET.depth || 6; + var cpu = GET.cpu || 0; + var depth = GET.depth || 6; - if(cpu != serverInfo.cpu){ - return; - } + if(cpu != serverInfo.cpu){ + return; + } - var filename = __dirname + '/cpu' + serverInfo.cpu + '.' + Date.now() + '.globaldump'; + var filename = __dirname + '/cpu' + serverInfo.cpu + '.' + Date.now() + '.globaldump'; - logger.info('globaldump'); - logger.info(GET); - logger.info(filename); + logger.info('globaldump'); + logger.info(GET); + logger.info(filename); - var str = util.inspect(global,{ - depth: depth - }); + var str = util.inspect(global,{ + depth: depth + }); - fs.writeFile(filename,str,'UTF-8',function(){ - logger.info('globaldump finish'); - }); + fs.writeFile(filename,str,'UTF-8',function(){ + logger.info('globaldump finish'); + }); }); function requestHandler(req, res){ - if(server.keepAliveTimeout > 0) { - res.setHeader('Connection', 'keep-alive'); - res.setHeader('Keep-Alive', `timeout=${parseInt(server.keepAliveTimeout / 1000)}`); - }else{ - res.setHeader('Connection', 'close'); - } - - res.setHeader('X-Powered-By', 'TSW/Node.js'); - res.setHeader('Server', headerServer); - res.setHeader('Cache-Control', 'no-cache'); - - if(config.devMode){ - //发者模式清除缓存 - cleanCache(); - } - - res.flush = res.flush || function(){return true;}; - - //解析get参数 - parseGet(req); - - if('upgrade' === req.headers.connection && 'websocket' === req.headers.upgrade) { - //websocket - }else{ - //HTTP路由 - doRoute(req,res); - } + if(server.keepAliveTimeout > 0) { + res.setHeader('Connection', 'keep-alive'); + res.setHeader('Keep-Alive', `timeout=${parseInt(server.keepAliveTimeout / 1000)}`); + }else{ + res.setHeader('Connection', 'close'); + } + + res.setHeader('X-Powered-By', 'TSW/Node.js'); + res.setHeader('Server', headerServer); + res.setHeader('Cache-Control', 'no-cache'); + + if(config.devMode){ + //发者模式清除缓存 + cleanCache(); + } + + res.flush = res.flush || function(){return true;}; + + //解析get参数 + parseGet(req); + + if('upgrade' === req.headers.connection && 'websocket' === req.headers.upgrade) { + //websocket + }else{ + //HTTP路由 + doRoute(req,res); + } } @@ -228,152 +223,147 @@ serverThis.keepAliveTimeout = Math.max(config.timeout.keepAlive,0); global.TSW_HTTP_SERVER = server; if(config.httpsOptions){ - serverHttps = https.createServer(config.httpsOptions,function(req,res){ - req.headers['x-client-proto'] = 'https'; + serverHttps = https.createServer(config.httpsOptions,function(req,res){ + req.headers['x-client-proto'] = 'https'; - requestHandler(req,res); - }); + requestHandler(req,res); + }); - serverHttps.on('clientError', function(err, socket){ - socket.end('HTTP/1.1 400 Bad Request\r\n\r\n'); - }); + serverHttps.on('clientError', function(err, socket){ + socket.end('HTTP/1.1 400 Bad Request\r\n\r\n'); + }); - serverHttps.timeout = Math.max(config.timeout.upload || config.timeout.socket,0); - serverHttps.keepAliveTimeout = Math.max(config.timeout.keepAlive,0); + serverHttps.timeout = Math.max(config.timeout.upload || config.timeout.socket,0); + serverHttps.keepAliveTimeout = Math.max(config.timeout.keepAlive,0); - global.TSW_HTTPS_SERVER = serverHttps; + global.TSW_HTTPS_SERVER = serverHttps; } logger.info('pid:${pid} createServer ok',{ - pid: process.pid + pid: process.pid }); //分发父进程发送来的消息 process.on('message',function(m){ - if(m && methodMap[m.cmd]){ - methodMap[m.cmd].apply(this,arguments); - } + if(m && methodMap[m.cmd]){ + methodMap[m.cmd].apply(this,arguments); + } }); function startHeartBeat(){ - if(isStartHeartBeat){ - return; - } + if(isStartHeartBeat){ + return; + } - isStartHeartBeat = true; + isStartHeartBeat = true; - global.cpuUsed = 0; + global.cpuUsed = 0; - //定时给父进程发送心跳包 - setInterval(function(){ + //定时给父进程发送心跳包 + setInterval(function(){ - heartBeatCount += 1; + heartBeatCount += 1; - process.connected && process.send && process.send({ - cmd: 'heartBeat', - memoryUsage: process.memoryUsage() - }); + process.connected && process.send && process.send({ + cmd: 'heartBeat', + memoryUsage: process.memoryUsage() + }); - if(serverInfo.cpu === 0){ - //测试环境1分钟上报一次 - if(heartBeatCount % 12 === 0){ - TEReport.report(); - } - } + if(serverInfo.cpu === 0){ + //测试环境1分钟上报一次 + if(heartBeatCount % 12 === 0){ + TEReport.report(); + } + } - global.cpuUsed = cpuUtil.getCpuUsed(serverInfo.cpu); + global.cpuUsed = cpuUtil.getCpuUsed(serverInfo.cpu); - tnm2.Attr_API_Set('AVG_TSW_CPU_USED', global.cpuUsed); + tnm2.Attr_API_Set('AVG_TSW_CPU_USED', global.cpuUsed); - if(global.cpuUsed >= 80) { - global.cpuUsed80 = ~~global.cpuUsed80 + 1; - }else{ - global.cpuUsed80 = 0; - } + if(global.cpuUsed >= 80) { + global.cpuUsed80 = ~~global.cpuUsed80 + 1; + }else{ + global.cpuUsed80 = 0; + } - var mailTo; - var cpuUsed = global.cpuUsed; + var cpuUsed = global.cpuUsed; - //高负载告警 - if ( - global.cpuUsed80 === 4 && + //高负载告警 + if ( + global.cpuUsed80 === 4 && !config.isTest && !isWindows - ) { - //取进程快照 - //ps aux --sort=-pcpu - cp.exec('top -bcn1',{ - env: { - COLUMNS: 200 - }, - timeout: 5000 - },function(err,data,errData) { - var key = ['cpu80.v4',serverInfo.intranetIp].join(':'); - var Content = [ - '单核CPU' + serverInfo.cpu + '使用率为:' + cpuUsed + ',超过80%, 最近5秒钟CPU Profiler见附件' - ].join('
'); - - var str = ''; - - if (data) { - str = data.toString('utf-8'); - str = str.replace(/'); - - Content += '

进程快照:

' + str + '
'; - } - - - //获取本机信息,用来分组 - require('api/cmdb').GetDeviceThisServer().done(function(data){ - data = data || {}; - var business = data.business && data.business[0] || {}; - var moduleId = business.moduleId; - var owner = ''; - - if(data.ownerMain){ - owner = [owner,data.ownerMain].join(';'); - } - if(data.ownerBack){ - owner = [owner,data.ownerBack].join(';'); - } - - if(isWindows){ - moduleId = 'any'; - } - - //再抓一份CPU Profiler - require('util/v8-profiler.js').getProfiler({ - recordTime: 5000 - }, result => { - mail.SendMail(key, 'js', 600, { - 'To' : config.mailTo, - 'CC' : owner, - 'MsgInfo' : business.module + '[CPU]' + serverInfo.intranetIp + '单核CPU' + serverInfo.cpu + '使用率为:' + cpuUsed + ',超过80%', - 'Title' : business.module + '[CPU]' + serverInfo.intranetIp + '单核CPU' + serverInfo.cpu + '使用率为:' + cpuUsed + ',超过80%', - 'Content' : Content, - 'attachment': result ? { - fileType : true, - dispositionType: 'attachment', - fileName : 'cpu-profiler.cpuprofile', - content : result - } : '' - }); - }); - }); - }); - } - - let currMemory = process.memoryUsage(); - - tnm2.Attr_API_Set('AVG_TSW_MEMORY_RSS', currMemory.rss); - tnm2.Attr_API_Set('AVG_TSW_MEMORY_HEAP', currMemory.heapTotal); - tnm2.Attr_API_Set('AVG_TSW_MEMORY_EXTERNAL', currMemory.external); - - },5000); + ) { + //取进程快照 + //ps aux --sort=-pcpu + cp.exec('top -bcn1',{ + env: { + COLUMNS: 200 + }, + timeout: 5000 + },function(err,data,errData) { + var key = ['cpu80.v4',serverInfo.intranetIp].join(':'); + var Content = [ + '单核CPU' + serverInfo.cpu + '使用率为:' + cpuUsed + ',超过80%, 最近5秒钟CPU Profiler见附件' + ].join('
'); + + var str = ''; + + if (data) { + str = data.toString('utf-8'); + str = str.replace(/'); + + Content += '

进程快照:

' + str + '
'; + } + + + //获取本机信息,用来分组 + require('api/cmdb').GetDeviceThisServer().done(function(data){ + data = data || {}; + var business = data.business && data.business[0] || {}; + var owner = ''; + + if(data.ownerMain){ + owner = [owner,data.ownerMain].join(';'); + } + + if(data.ownerBack){ + owner = [owner,data.ownerBack].join(';'); + } + + //再抓一份CPU Profiler + require('util/v8-profiler.js').getProfiler({ + recordTime: 5000 + }, result => { + mail.SendMail(key, 'js', 600, { + 'To' : config.mailTo, + 'CC' : owner, + 'MsgInfo' : business.module + '[CPU]' + serverInfo.intranetIp + '单核CPU' + serverInfo.cpu + '使用率为:' + cpuUsed + ',超过80%', + 'Title' : business.module + '[CPU]' + serverInfo.intranetIp + '单核CPU' + serverInfo.cpu + '使用率为:' + cpuUsed + ',超过80%', + 'Content' : Content, + 'attachment': result ? { + fileType : true, + dispositionType: 'attachment', + fileName : 'cpu-profiler.cpuprofile', + content : result + } : '' + }); + }); + }); + }); + } + + let currMemory = process.memoryUsage(); + + tnm2.Attr_API_Set('AVG_TSW_MEMORY_RSS', currMemory.rss); + tnm2.Attr_API_Set('AVG_TSW_MEMORY_HEAP', currMemory.heapTotal); + tnm2.Attr_API_Set('AVG_TSW_MEMORY_EXTERNAL', currMemory.external); + + },5000); } @@ -382,184 +372,183 @@ function startHeartBeat(){ //restart methodMap.restart = function(){ - logger.info('cpu: ${cpu} restart',serverInfo); + logger.info('cpu: ${cpu} restart',serverInfo); - process.emit('restart'); -} + process.emit('restart'); +}; //reload methodMap.reload = function(){ - logger.info('cpu: ${cpu} reload',serverInfo); + logger.info('cpu: ${cpu} reload',serverInfo); - process.emit('reload'); -} + process.emit('reload'); +}; //heapdump methodMap.heapdump = function(m){ - logger.info('cpu: ${cpu} heapdump',serverInfo); + logger.info('cpu: ${cpu} heapdump',serverInfo); - process.emit('heapdump',m.GET); -} + process.emit('heapdump',m.GET); +}; //profiler methodMap.profiler = function(m){ - logger.info('cpu: ${cpu} profiler',serverInfo); + logger.info('cpu: ${cpu} profiler',serverInfo); - process.emit('profiler',m.GET); -} + process.emit('profiler',m.GET); +}; //globaldump methodMap.globaldump = function(m){ - logger.info('cpu: ${cpu} globaldump',serverInfo); + logger.info('cpu: ${cpu} globaldump',serverInfo); - process.emit('globaldump',m.GET); -} + process.emit('globaldump',m.GET); +}; //top100 methodMap.top100 = function(m){ - logger.info('cpu: ${cpu} top100',serverInfo); + logger.info('cpu: ${cpu} top100',serverInfo); - process.emit('top100',m.GET); -} + process.emit('top100',m.GET); +}; //监听端口 methodMap.listen = function(message){ - var shell; - var user_00 = config.workerUid || 'user_00'; - serverInfo.cpu = message.cpu || 0; - global.cpuUsed = cpuUtil.getCpuUsed(serverInfo.cpu); + var user_00 = config.workerUid || 'user_00'; + serverInfo.cpu = message.cpu || 0; + global.cpuUsed = cpuUtil.getCpuUsed(serverInfo.cpu); - process.title = 'TSW/worker/' + serverInfo.cpu; - global.TSW_HTTP_WORKER_PORT = config.workerPortBase + serverInfo.cpu; - - logger.info('cpu: ${cpu}, beforeStartup...',serverInfo); - - if(typeof config.beforeStartup === 'function'){ - config.beforeStartup(serverInfo.cpu); - } - - logger.info('cpu: ${cpu}, listen...',serverInfo); - - //直接根据配置启动,无需拿到_handle - server.listen({ - host: config.httpAddress, - port: config.httpPort, - exclusive: false - },function(err){ - if(err){ - logger.info('cpu: ${cpu}, listen http error ${address}:${port}',{ - cpu:serverInfo.cpu, - address: config.httpAddress, - port: config.httpPort - }); - - return; - } - - logger.info('cpu: ${cpu}, listen http ok ${address}:${port}',{ - cpu:serverInfo.cpu, - address: config.httpAddress, - port: config.httpPort - }); - - var finish = function(){ - - //开始发送心跳 - logger.info('start heart beat'); - - startHeartBeat(); - - if(!isWindows){ - try{ - process.setuid(user_00); - }catch(err){ - logger.error(`switch to uid: ${user_00} fail!`); - logger.error(err.stack); - } - - logger.info('switch to uid: ${uid}',{ - uid:user_00 - }); - } - websocket.start_listen(); - - logger.info('cpu: ${cpu}, afterStartup...',serverInfo); - - if(typeof config.afterStartup === 'function'){ - config.afterStartup(serverInfo.cpu); - } - } - - //监听私有端口 - serverThis.listen({ - host: config.httpAddress, - port: global.TSW_HTTP_WORKER_PORT, - exclusive: false - },function(err) { - if (err) { - logger.info('cpu: ${cpu}, listen http error ${address}:${port}', { - cpu: serverInfo.cpu, - address: config.httpAddress, - port: global.TSW_HTTP_WORKER_PORT - }); - - return; - } - - logger.info('cpu: ${cpu}, listen http ok ${address}:${port}', { - cpu: serverInfo.cpu, - address: config.httpAddress, - port: global.TSW_HTTP_WORKER_PORT - }); - - - if(serverHttps){ - - //启动https - serverHttps.listen(config.httpsPort,config.httpsAddress,function(err){ - if(err){ - logger.info('cpu: ${cpu}, listen https error ${address}:${port}',{ - cpu:serverInfo.cpu, - address: config.httpsPort, - port: config.httpsAddress - }); - - return; - } - - logger.info('cpu: ${cpu}, listen https ok ${address}:${port}',{ - cpu:serverInfo.cpu, - address: config.httpsAddress, - port: config.httpsPort - }); - - finish(); - }); - }else{ - finish(); - } - }); - - }); - - -} + process.title = 'TSW/worker/' + serverInfo.cpu; + global.TSW_HTTP_WORKER_PORT = config.workerPortBase + serverInfo.cpu; + + logger.info('cpu: ${cpu}, beforeStartup...',serverInfo); + + if(typeof config.beforeStartup === 'function'){ + config.beforeStartup(serverInfo.cpu); + } + + logger.info('cpu: ${cpu}, listen...',serverInfo); + + //直接根据配置启动,无需拿到_handle + server.listen({ + host: config.httpAddress, + port: config.httpPort, + exclusive: false + },function(err){ + if(err){ + logger.info('cpu: ${cpu}, listen http error ${address}:${port}',{ + cpu:serverInfo.cpu, + address: config.httpAddress, + port: config.httpPort + }); + + return; + } + + logger.info('cpu: ${cpu}, listen http ok ${address}:${port}',{ + cpu:serverInfo.cpu, + address: config.httpAddress, + port: config.httpPort + }); + + var finish = function(){ + + //开始发送心跳 + logger.info('start heart beat'); + + startHeartBeat(); + + if(!isWindows){ + try{ + process.setuid(user_00); + }catch(err){ + logger.error(`switch to uid: ${user_00} fail!`); + logger.error(err.stack); + } + + logger.info('switch to uid: ${uid}',{ + uid:user_00 + }); + } + websocket.start_listen(); + + logger.info('cpu: ${cpu}, afterStartup...',serverInfo); + + if(typeof config.afterStartup === 'function'){ + config.afterStartup(serverInfo.cpu); + } + }; + + //监听私有端口 + serverThis.listen({ + host: config.httpAddress, + port: global.TSW_HTTP_WORKER_PORT, + exclusive: false + },function(err) { + if (err) { + logger.info('cpu: ${cpu}, listen http error ${address}:${port}', { + cpu: serverInfo.cpu, + address: config.httpAddress, + port: global.TSW_HTTP_WORKER_PORT + }); + + return; + } + + logger.info('cpu: ${cpu}, listen http ok ${address}:${port}', { + cpu: serverInfo.cpu, + address: config.httpAddress, + port: global.TSW_HTTP_WORKER_PORT + }); + + + if(serverHttps){ + + //启动https + serverHttps.listen(config.httpsPort,config.httpsAddress,function(err){ + if(err){ + logger.info('cpu: ${cpu}, listen https error ${address}:${port}',{ + cpu:serverInfo.cpu, + address: config.httpsPort, + port: config.httpsAddress + }); + + return; + } + + logger.info('cpu: ${cpu}, listen https ok ${address}:${port}',{ + cpu:serverInfo.cpu, + address: config.httpsAddress, + port: config.httpsPort + }); + + finish(); + }); + }else{ + finish(); + } + }); + + }); + + +}; if(cluster.isMaster){ - if(isWindows){ - logger.info('isWindows, start litening'); - methodMap.listen({cpu : 0}); - }else if(debugOptions && debugOptions.inspectorEnabled){ - logger.setLogLevel('debug'); - logger.info('inspectorEnabled, start litening'); - methodMap.listen({cpu : 0}); - } + if(isWindows){ + logger.info('isWindows, start litening'); + methodMap.listen({cpu : 0}); + }else if(debugOptions && debugOptions.inspectorEnabled){ + logger.setLogLevel('debug'); + logger.info('inspectorEnabled, start litening'); + methodMap.listen({cpu : 0}); + } } diff --git a/bin/proxy/http.route.js b/bin/proxy/http.route.js index 3f413c57..0a67c8b9 100644 --- a/bin/proxy/http.route.js +++ b/bin/proxy/http.route.js @@ -1,785 +1,793 @@ -/*! - * Tencent is pleased to support the open source community by making Tencent Server Web available. - * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. - * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - * http://opensource.org/licenses/MIT - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ -"use strict"; - -const logger = require('logger'); -const domain = require('domain'); -const serverInfo = require('serverInfo.js'); -const config = require('./config.js'); -const dcapi = require('api/libdcapi/dcapi.js'); -const {isWindows} = require('util/isWindows.js'); -const contextMod = require('context.js'); -const Context = require('runtime/Context'); -const Window = require('runtime/Window'); -const xssFilter = require('api/xssFilter'); -const alpha = require('util/auto-report/alpha.js'); -const httpUtil = require('util/http.js'); -const isTST = require('util/isTST.js'); -const h5test = require("util/h5-test/is-test"); -const logReport = require('util/auto-report/logReport.js'); -const httpModAct = require('./http.mod.act.js'); -const httpModMap = require('./http.mod.map.js'); -const mail = require('util/mail/mail.js'); -const CCFinder = require('runtime/CCFinder.js'); -const parseBody = require('util/http/parseBody.js'); -const TSW = require('api/keyman'); -const tnm2 = require('api/tnm2'); - - -module.exports = function(req,res){ - - process.SN = process.SN || 0; - - var timeLimit = httpUtil.isPostLike(req) ? config.timeout.post : config.timeout.get; - var start = new Date(); - var d = domain.create(); - var tid = null; - var clear = function(){ - - if(tid === null){ - return; - } - - clearTimeout(tid); - tid = null; - - logger.debug('clear called'); - - process.nextTick(function(){ - - var timeout = timeLimit - (Date.now() - start.getTime()); - - if(timeout > 2000){ - timeout = 2000; - } - - if(!timeout){ - timeout = 0; - } - - if(timeout < 0){ - timeout = 0; - } - - req.removeAllListeners('fail'); - - res.removeAllListeners('timeout'); - res.removeAllListeners('close'); - res.removeAllListeners('finish'); - res.removeAllListeners('afterFinish'); - res.removeAllListeners('done'); - - setTimeout(function(){ - logger.debug('clearing'); - - d.remove(req); - d.remove(res); - - if(d.currentContext){ - d.currentContext.window.request = null; - d.currentContext.window.response = null; - d.currentContext.window.onerror = null; - d.currentContext.window = null; - } - - if(d.currentContext){ - d.currentContext.log = null; - d.currentContext = null; - } - - d = null; - req = null; - res = null; - start = null; - clear = null; - - logger.debug('cleared'); - - - },timeout); - }); - - }; - - d.add(req); - d.add(res); - - d.currentContext = new Context(); - d.currentContext.log = {}; - d.currentContext.SN = ++process.SN; - d.currentContext.window = new Window(); - d.currentContext.window.request = req; - d.currentContext.window.response = res; - - if(config.enableWindow){ - d.currentContext.window.enable(); - } - - req.timestamps = { - ClientConnected : start, - ClientBeginRequest : start, - GotRequestHeaders : start, - ClientDoneRequest : start, - GatewayTime : 0, - DNSTime : 0, - TCPConnectTime : 0, - HTTPSHandshakeTime : 0, - ServerConnected : start, - FiddlerBeginRequest: start, - ServerGotRequest : start, - ServerBeginResponse: 0, - GotResponseHeaders : 0, - ServerDoneResponse : 0, - ClientBeginResponse: 0, - ClientDoneResponse : 0 - }; - - if(isWindows || config.devMode){ - d.currentContext.log.showLineNumber = true; - } - - if(global.cpuUsed > config.cpuLimit){ - d.currentContext.log = null; - } - - d.on('error',function(err){ - - if(err && err.message === 'socket hang up'){ - logger.warn(err && err.stack); - - //忽略ajax错误 - return; - } - - if(err && err.message === "Cannot read property 'asyncReset' of null"){ - logger.warn(err && err.stack); - - //忽略asyncReset错误 - return; - } - - if(err && err.message === 'Cannot read property \'resume\' of null'){ - logger.warn(err && err.stack); - - //忽略io错误 - return; - } - - if(err && err.message === 'write ECONNRESET'){ - logger.warn(err && err.stack); - - //忽略io错误 - return; - } - - if(err && err.message === 'This socket is closed'){ - logger.warn(err && err.stack); - - //忽略io错误 - return; - } - - if(err && err.stack && err.stack.indexOf('/') === -1 && err.stack.indexOf('\\') === -1){ - logger.warn(err && err.stack); - //忽略原生错误 - return; - } - - if(clear === null){ - logger.warn(err && err.stack); - return; - } - - onerror(req,res,err); - - if(httpUtil.isSent(res)){ - logger.warn('${err}\nhttp://${host}${url}',{ - err: err && err.stack, - url: req.url, - host: req.headers.host - }); - - dcapi.report({ - key : 'EVENT_TSW_HTTP_PAGE', - toIp : '127.0.0.1', - code : -100503, - isFail : 1, - delay : Date.now() - start.getTime() - }); - - }else{ - logger.error('${err}\nhttp://${host}${url}',{ - err: err && err.stack, - url: req.url, - host: req.headers.host - }); - - dcapi.report({ - key : 'EVENT_TSW_HTTP_PAGE', - toIp : '127.0.0.1', - code : 100503, - isFail : 1, - delay : Date.now() - start.getTime() - }); - - try{ - res.writeHead(503, {'Content-Type': 'text/html; charset=UTF-8'}); - res.end(); - }catch(e){} - } - - try{res.emit('done');}catch(e){} - - var key,Content; - - if(err && err.stack && err.message){ - - if(err.message === "Cannot read property 'asyncReset' of null"){ - return; - } - - if(err.message.indexOf('ETIMEDOUT') > 0){ - return; - } - - if(err.message.indexOf('timeout') > 0){ - return; - } - - if(err.message.indexOf('hang up') > 0){ - return; - } - - if(err.message.indexOf('error:140943FC') > 0){ - return; - } - - if(isWindows){ - //return; - } - - key = [err.message].join(':'); - - Content = [ - '

错误堆栈

', - '

',
-					err.stack,
-				'

', - ].join(''); - - mail.SendMail(key,'js',600,{ - 'Title' : key, - 'runtimeType' : 'Error', - 'MsgInfo' : err.stack || err.message, - 'Content' : Content - }); - } - - }); - - res.once('finish',function(){ - this.emit('done'); - }); - - res.once('close',function(){ - res.__hasClosed = true; - logger.debug('response has close'); - - this.emit('done');// let it going - }); - - res.once('done',function(){ - - var isFail = 0,now; - - if(clear === null){ - return; - } - clear(); - - now = new Date(); - - if(!res.statusCode){ - isFail = 1; - } - - if(res.statusCode === 200){ - isFail = 0; - tnm2.Attr_API('SUM_TSW_HTTP_20X', 1); - }else if(res.statusCode === 206 || res.statusCode === 204){ - isFail = 0; - tnm2.Attr_API('SUM_TSW_HTTP_20X', 1); - }else if(res.statusCode === 301){ - isFail = 0; - tnm2.Attr_API('SUM_TSW_HTTP_302', 1); - }else if(res.statusCode === 302){ - isFail = 0; - tnm2.Attr_API('SUM_TSW_HTTP_302', 1); - }else if(res.statusCode === 303){ - isFail = 0; - tnm2.Attr_API('SUM_TSW_HTTP_302', 1); - }else if(res.statusCode === 307){ - isFail = 0; - tnm2.Attr_API('SUM_TSW_HTTP_302', 1); - }else if(res.statusCode === 304){ - isFail = 0; - tnm2.Attr_API('SUM_TSW_HTTP_304', 1); - }else if(res.statusCode === 403){ - isFail = 0; - tnm2.Attr_API('SUM_TSW_HTTP_403', 1); - }else if(res.statusCode === 404){ - isFail = 2; - tnm2.Attr_API('SUM_TSW_HTTP_404', 1); - }else if(res.statusCode === 418){ - isFail = 0; - tnm2.Attr_API('SUM_TSW_HTTP_418', 1); - }else if(res.statusCode === 419){ - isFail = 0; - tnm2.Attr_API('SUM_TSW_HTTP_419', 1); - }else if(res.statusCode === 666){ - isFail = 0; - tnm2.Attr_API('SUM_TSW_HTTP_666', 1); - }else if(res.statusCode === 501){ - isFail = 2; - tnm2.Attr_API('SUM_TSW_HTTP_501', 1); - }else if(res.statusCode === 508){ - isFail = 2; - tnm2.Attr_API('SUM_TSW_HTTP_508', 1); - }else if(res.statusCode >= 500 && res.statusCode <= 599){ - isFail = 1; - tnm2.Attr_API('SUM_TSW_HTTP_500', 1); - }else{ - isFail = 2; - tnm2.Attr_API('SUM_TSW_HTTP_OTHER', 1); - } - - req.timestamps.ServerBeginResponse = req.timestamps.ServerBeginResponse || now; - req.timestamps.GotResponseHeaders = req.timestamps.ServerBeginResponse; - req.timestamps.ServerDoneResponse = res.ServerDoneResponse || now; - req.timestamps.ClientBeginResponse = req.timestamps.ServerBeginResponse; - req.timestamps.ClientDoneResponse = req.timestamps.ServerDoneResponse; - - - if(isFail === 1){ - logger.debug('finish, statusCode: ${statusCode},cost: ${cost}ms',{ - statusCode: res.statusCode, - cost: Date.now() - start.getTime() - }); - - if(typeof req.REQUEST.body === 'string'){ - - if(req.REQUEST.body.length < 32 * 1024){ - logger.debug('\n${head}${body}',{ - head: httpUtil.getRequestHeaderStr(req), - body: req.REQUEST.body || '' - }); - }else{ - logger.debug('\n${head}${body}',{ - head: httpUtil.getRequestHeaderStr(req), - body: 'body size >= 32KB' - }); - } - }else{ - - logger.debug('\n${head}${body}',{ - head: httpUtil.getRequestHeaderStr(req), - body: req.REQUEST.body || '' - }); - } - - }else{ - logger.debug('finish, statusCode: ${statusCode}, cost: ${cost}ms',{ - statusCode: res.statusCode, - cost: Date.now() - start.getTime() - }); - } - - if(res.__hasTimeout && isFail !== 1){ - - dcapi.report({ - key : 'EVENT_TSW_HTTP_TIMEOUT', - toIp : '127.0.0.1', - code : res.statusCode || 0, - isFail : isFail, - delay : Date.now() - start.getTime() - }); - - }else if(res.__hasClosed){ - - dcapi.report({ - key : 'EVENT_TSW_HTTP_CLOSE', - toIp : '127.0.0.1', - code : res.statusCode || 0, - isFail : isFail, - delay : Date.now() - start.getTime() - }); - }else{ - - dcapi.report({ - key : 'EVENT_TSW_HTTP_PAGE', - toIp : '127.0.0.1', - code : res.statusCode || 0, - isFail : isFail, - delay : Date.now() - start.getTime() - }); - - dcapi.report({ - key : 'EVENT_TSW_HTTP_CODE', - toIp : '127.0.0.1', - code : res.statusCode || 0, - isFail : isFail, - delay : Date.now() - start.getTime() - }); - - } - - - res.emit('afterFinish'); - }); - - d.run(function(){ - tid = setTimeout(function(){ - - res.__hasTimeout = true; - - logger.debug('timeout: ' + timeLimit); - - onerror(req,res,new Error('timeout')); - - if(res.__hasClosed){ - - try{res.writeHead(202); }catch(e){} - try{res.end();}catch(e){} - try{res.emit('done');}catch(e){} - }else if(res.finished){ - - try{res.end();}catch(e){} - try{res.emit('done');}catch(e){} - }else if(!res._headerSent && !res.headersSent && !res.finished && res.statusCode === 200){ - logger.debug('statusCode: ${statusCode}, _headerSent: ${_headerSent}, headersSent: ${headersSent}, finished: ${finished}',res); - - //输出一条错误log方便定位问题 - logger.error('response timeout http://${host}${url}',{ - url: req.url, - host: req.headers.host - }); - - try{res.writeHead(513); }catch(e){} - try{res.end();}catch(e){} - - try{res.emit('done');}catch(e){} - }else{ - logger.debug('statusCode: ${statusCode}, _headerSent: ${_headerSent}, headersSent: ${headersSent}, finished: ${finished}',res); - - try{res.end();}catch(e){} - try{res.emit('done');}catch(e){} - } - - req.emit('close'); - },timeLimit); - - doRoute(req,res); - }); - -} - -module.exports.doRoute = doRoute; - -function doRoute(req,res){ - - var clientIp = httpUtil.getUserIp(req); - var userIp24 = httpUtil.getUserIp24(req); - - //增加测试环境header - if(config.isTest) { - res.setHeader('Test-Head', serverInfo.intranetIp || ''); - } - - logger.debug('${method} ${protocol}://${host}${path}',{ - protocol: req.REQUEST.protocol, - path: req.REQUEST.path, - host: req.headers.host, - method: req.method - }); - - logger.debug('idc: ${idc}, server ip: ${intranetIp}, tcp: ${remoteAddress}:${remotePort} > ${localAddress}:${localPort}, client ip: ${clientIp}, cpuUsed: ${cpuUsed}',{ - cpuUsed: global.cpuUsed, - idc: config.idc, - intranetIp: serverInfo.intranetIp, - clientIp: clientIp, - remoteAddress: (req.socket && req.socket.remoteAddress), - remotePort: (req.socket && req.socket.remotePort), - localAddress: (req.socket && req.socket.localAddress), - localPort: (req.socket && req.socket.localPort) - }); - - if(config.isTest){ - logger.debug('config.isTest is true'); - if(isTST.isTST(req)){ - res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'}); - res.end(); - return; - } - } - - - //安全中心扫描报个指标 - //支持从配置中直接屏蔽安全中心扫描请求 - if(isTST.isTST(req)){ - tnm2.Attr_API('SUM_TSW_HTTP_TST', 1); - - if(config.ignoreTST){ - logger.debug('ignore TST request'); - - res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'}); - res.end('200'); - - return; - } - } - - if(config.devMode){ - logger.debug('config.devMode is true'); - } - - //log自动上报 - logReport(req,res); - - res.writeHead = (function(fn){ - return function(...args){ - if(alpha.isAlpha(req)){ - if(logger.getLog()){ - logger.getLog().showLineNumber = true; - logger.debug('showLineNumber on'); - } - - //抓回包 - httpUtil.captureBody(this); - } - - logger.debug('response ${statusCode}',{ - statusCode: args[0] - }); - - return fn.apply(this,args); - } - }(res.writeHead)); - - var mod_act = contextMod.currentContext().mod_act || httpModAct.getModAct(req); - contextMod.currentContext().mod_act = mod_act; - - if(alpha.isAlpha(req)){ - if(logger.getLog()){ - logger.getLog().showLineNumber = true; - logger.debug('showLineNumber on'); - } - } - - logger.debug('node-${version}, name: ${name}, appid: ${appid}',{ - version: process.version, - name: mod_act || null, - appid: config.appid || null - }); - - //测试环境 - if(h5test.isTestUser(req, res)){ - return; - } - - //跟踪url调用深度 - var steps = parseInt(req.headers['tsw-trace-steps'] || '0') || 0; - - //深度超过5层,直接拒绝 - if(steps >= 5){ - - tnm2.Attr_API('SUM_TSW_ROUTE_EXCEED', 1); - - try{ - res.writeHead(503, {'Content-Type': 'text/html; charset=UTF-8'}); - res.end('503'); - }catch(e){} - - return; - } - - req.headers['tsw-trace-steps'] = steps + 1; - - var modulePath = httpModMap.find(mod_act,req,res); - - if(res.headersSent || res._headerSent || res.finished){ - return; - } - - if(modulePath && typeof modulePath.handle === 'function'){ - let app = modulePath; - - modulePath = function(req,res,plug){ - return app.handle(req,res); - } - } - - if(modulePath && typeof modulePath.callback === 'function'){ - let app = modulePath; - - modulePath = function(req,res,plug){ - return app.callback()(req,res); - } - } - - if(typeof modulePath !== 'function'){ - if(req.REQUEST.pathname === '/419') { - if(typeof config.page419 === 'string'){ - modulePath = require(config.page419); - } - } else { - if(typeof config.page404 === 'string'){ - modulePath = require(config.page404); - } - } - } - - if(typeof modulePath !== 'function'){ - try{ - res.writeHead(404, {'Content-Type': 'text/html; charset=UTF-8'}); - res.end('404'); - }catch(e){} - return; - } - - var modulePathHandler = function(){ - var maybePromise = modulePath(req, res, plug); - if( - typeof maybePromise === 'object' - && - typeof maybePromise.catch === 'function' - ){ - maybePromise.catch(function(err){ - logger.error(err); - process.domain && process.domain.emit('error',err); - }); - } - }; - - var blackIpMap = TSW.getBlockIpMapSync() || {}; - - if(blackIpMap[clientIp] || blackIpMap[userIp24] || !clientIp){ - logger.debug('连接已断开'); - - tnm2.Attr_API('SUM_TSW_IP_EMPTY', 1); - res.writeHead(403, {'Content-Type': 'text/plain; charset=UTF-8'}); - res.end(); - return; - } - - if(blackIpMap[clientIp] || blackIpMap[userIp24]){ - logger.debug('命中黑名单IP'); - - dcapi.report({ - key : 'EVENT_TSW_HTTP_IP_BLOCK', - toIp : clientIp || '127.0.0.1', - code : 0, - isFail : 0, - delay : 100 - }); - tnm2.Attr_API('SUM_TSW_IP_BLOCK', 1); - res.writeHead(403, {'Content-Type': 'text/plain; charset=UTF-8'}); - res.end(); - return; - } - - if(CCFinder.checkHost(req,res) === false){ - return; - } - - if(CCFinder.check(req,res) === false){ - return; - } - - //webso柔性 - if(global.cpuUsed > 80){ - - if(httpUtil.isFromWns(req) && req.headers['if-none-match']){ - - logger.debug('webso limit 304, cpuUsed: ${cpuUsed}',{ - cpuUsed : global.cpuUsed - }); - - tnm2.Attr_API('SUM_TSW_WEBSO_LIMIT', 1); - try{ - res.writeHead(304, { - 'Content-Type': 'text/html; charset=UTF-8', - 'Etag': req.headers['if-none-match'] - }); - res.end(); - }catch(e){} - - return; - } - - } - - var contentType = req.headers['content-type'] || 'application/x-www-form-urlencoded'; - - if(req.method === 'GET' || req.method === 'HEAD'){ - - if(httpUtil.isFromWns(req)){ - //wns请求不过门神检查 - return modulePathHandler(); - } - - xssFilter.check().done(function(){ - return modulePathHandler(); - }).fail(function(){ - res.writeHead(501, {'Content-Type': 'text/plain; charset=UTF-8'}); - res.end('501 by TSW'); - }); - }else if(context.autoParseBody === false){ - return modulePathHandler(); - }else if( - contentType.indexOf('application/x-www-form-urlencoded') > -1 - || contentType.indexOf('text/plain') > -1 - || contentType.indexOf('application/json') > -1 - ){ - parseBody(req,res,function(){ - return modulePathHandler(); - }); - }else{ - return modulePathHandler(); - } - -} - - - -function onerror(req,res,err){ - var listener = req.listeners('fail'); - var window = context.window || {}; - - if(res.headersSent || res._headerSent || res.finished){ - return; - } - - if(listener && listener.length > 0){ - try{ - req.emit('fail',err); - }catch(e){ - logger.error(e && e.stack); - } - - req.removeAllListeners('fail'); - - }else if(window.onerror){ - try{ - window.onerror(err); - }catch(e){ - logger.error(e && e.stack); - } - - window.onerror = null; - } +/*! + * Tencent is pleased to support the open source community by making Tencent Server Web available. + * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ +'use strict'; + +const logger = require('logger'); +const domain = require('domain'); +const serverInfo = require('serverInfo.js'); +const config = require('./config.js'); +const dcapi = require('api/libdcapi/dcapi.js'); +const {isWindows} = require('util/isWindows.js'); +const contextMod = require('context.js'); +const Context = require('runtime/Context'); +const Window = require('runtime/Window'); +const xssFilter = require('api/xssFilter'); +const alpha = require('util/auto-report/alpha.js'); +const httpUtil = require('util/http.js'); +const isTST = require('util/isTST.js'); +const h5test = require('util/h5-test/is-test'); +const logReport = require('util/auto-report/logReport.js'); +const httpModAct = require('./http.mod.act.js'); +const httpModMap = require('./http.mod.map.js'); +const mail = require('util/mail/mail.js'); +const CCFinder = require('runtime/CCFinder.js'); +const parseBody = require('util/http/parseBody.js'); +const TSW = require('api/keyman'); +const tnm2 = require('api/tnm2'); + + +module.exports = function(req,res){ + + process.SN = process.SN || 0; + + var timeLimit = httpUtil.isPostLike(req) ? config.timeout.post : config.timeout.get; + var start = new Date(); + var d = domain.create(); + var tid = null; + var clear = function(){ + + if(tid === null){ + return; + } + + clearTimeout(tid); + tid = null; + + logger.debug('clear called'); + + process.nextTick(function(){ + + var timeout = timeLimit - (Date.now() - start.getTime()); + + if(timeout > 2000){ + timeout = 2000; + } + + if(!timeout){ + timeout = 0; + } + + if(timeout < 0){ + timeout = 0; + } + + req.removeAllListeners('fail'); + + res.removeAllListeners('timeout'); + res.removeAllListeners('close'); + res.removeAllListeners('finish'); + res.removeAllListeners('afterFinish'); + res.removeAllListeners('done'); + + setTimeout(function(){ + logger.debug('clearing'); + + d.remove(req); + d.remove(res); + + if(d.currentContext){ + d.currentContext.window.request = null; + d.currentContext.window.response = null; + d.currentContext.window.onerror = null; + d.currentContext.window = null; + } + + if(d.currentContext){ + d.currentContext.log = null; + d.currentContext = null; + } + + d = null; + req = null; + res = null; + start = null; + clear = null; + + logger.debug('cleared'); + + + },timeout); + }); + + }; + + d.add(req); + d.add(res); + + d.currentContext = new Context(); + d.currentContext.log = {}; + d.currentContext.SN = ++process.SN; + d.currentContext.window = new Window(); + d.currentContext.window.request = req; + d.currentContext.window.response = res; + + if(config.enableWindow){ + d.currentContext.window.enable(); + } + + req.timestamps = { + ClientConnected : start, + ClientBeginRequest : start, + GotRequestHeaders : start, + ClientDoneRequest : start, + GatewayTime : 0, + DNSTime : 0, + TCPConnectTime : 0, + HTTPSHandshakeTime : 0, + ServerConnected : start, + FiddlerBeginRequest: start, + ServerGotRequest : start, + ServerBeginResponse: 0, + GotResponseHeaders : 0, + ServerDoneResponse : 0, + ClientBeginResponse: 0, + ClientDoneResponse : 0 + }; + + if(isWindows || config.devMode){ + d.currentContext.log.showLineNumber = true; + } + + if(global.cpuUsed > config.cpuLimit){ + d.currentContext.log = null; + } + + d.on('error',function(err){ + + if(err && err.message === 'socket hang up'){ + logger.warn(err && err.stack); + + //忽略ajax错误 + return; + } + + if(err && err.message === 'Cannot read property \'asyncReset\' of null'){ + logger.warn(err && err.stack); + + //忽略asyncReset错误 + return; + } + + if(err && err.message === 'Cannot read property \'resume\' of null'){ + logger.warn(err && err.stack); + + //忽略io错误 + return; + } + + if(err && err.message === 'write ECONNRESET'){ + logger.warn(err && err.stack); + + //忽略io错误 + return; + } + + if(err && err.message === 'This socket is closed'){ + logger.warn(err && err.stack); + + //忽略io错误 + return; + } + + if(err && err.stack && err.stack.indexOf('/') === -1 && err.stack.indexOf('\\') === -1){ + logger.warn(err && err.stack); + //忽略原生错误 + return; + } + + if(clear === null){ + logger.warn(err && err.stack); + return; + } + + onerror(req,res,err); + + if(httpUtil.isSent(res)){ + logger.warn('${err}\nhttp://${host}${url}',{ + err: err && err.stack, + url: req.url, + host: req.headers.host + }); + + dcapi.report({ + key : 'EVENT_TSW_HTTP_PAGE', + toIp : '127.0.0.1', + code : -100503, + isFail : 1, + delay : Date.now() - start.getTime() + }); + + }else{ + logger.error('${err}\nhttp://${host}${url}',{ + err: err && err.stack, + url: req.url, + host: req.headers.host + }); + + dcapi.report({ + key : 'EVENT_TSW_HTTP_PAGE', + toIp : '127.0.0.1', + code : 100503, + isFail : 1, + delay : Date.now() - start.getTime() + }); + + try{ + res.writeHead(503, {'Content-Type': 'text/html; charset=UTF-8'}); + res.end(); + }catch(e){ + logger.info(`response 503 fail ${e.message}`); + } + } + + try{res.emit('done');}catch(e){logger.info(`emit done event fail ${e.message}`);} + + var key,Content; + + if(err && err.stack && err.message){ + + if(err.message === 'Cannot read property \'asyncReset\' of null'){ + return; + } + + if(err.message.indexOf('ETIMEDOUT') > 0){ + return; + } + + if(err.message.indexOf('timeout') > 0){ + return; + } + + if(err.message.indexOf('hang up') > 0){ + return; + } + + if(err.message.indexOf('error:140943FC') > 0){ + return; + } + + if(isWindows){ + //return; + } + + key = [err.message].join(':'); + + Content = [ + '

错误堆栈

', + '

',
+                err.stack,
+                '

', + ].join(''); + + mail.SendMail(key,'js',600,{ + 'Title' : key, + 'runtimeType' : 'Error', + 'MsgInfo' : err.stack || err.message, + 'Content' : Content + }); + } + + }); + + res.once('finish',function(){ + this.emit('done'); + }); + + res.once('close',function(){ + res.__hasClosed = true; + logger.debug('response has close'); + + this.emit('done');// let it going + }); + + res.once('done',function(){ + + var isFail = 0,now; + + if(clear === null){ + return; + } + clear(); + + now = new Date(); + + if(!res.statusCode){ + isFail = 1; + } + + if(res.statusCode === 200){ + isFail = 0; + tnm2.Attr_API('SUM_TSW_HTTP_20X', 1); + }else if(res.statusCode === 206 || res.statusCode === 204){ + isFail = 0; + tnm2.Attr_API('SUM_TSW_HTTP_20X', 1); + }else if(res.statusCode === 301){ + isFail = 0; + tnm2.Attr_API('SUM_TSW_HTTP_302', 1); + }else if(res.statusCode === 302){ + isFail = 0; + tnm2.Attr_API('SUM_TSW_HTTP_302', 1); + }else if(res.statusCode === 303){ + isFail = 0; + tnm2.Attr_API('SUM_TSW_HTTP_302', 1); + }else if(res.statusCode === 307){ + isFail = 0; + tnm2.Attr_API('SUM_TSW_HTTP_302', 1); + }else if(res.statusCode === 304){ + isFail = 0; + tnm2.Attr_API('SUM_TSW_HTTP_304', 1); + }else if(res.statusCode === 403){ + isFail = 0; + tnm2.Attr_API('SUM_TSW_HTTP_403', 1); + }else if(res.statusCode === 404){ + isFail = 2; + tnm2.Attr_API('SUM_TSW_HTTP_404', 1); + }else if(res.statusCode === 418){ + isFail = 0; + tnm2.Attr_API('SUM_TSW_HTTP_418', 1); + }else if(res.statusCode === 419){ + isFail = 0; + tnm2.Attr_API('SUM_TSW_HTTP_419', 1); + }else if(res.statusCode === 666){ + isFail = 0; + tnm2.Attr_API('SUM_TSW_HTTP_666', 1); + }else if(res.statusCode === 501){ + isFail = 2; + tnm2.Attr_API('SUM_TSW_HTTP_501', 1); + }else if(res.statusCode === 508){ + isFail = 2; + tnm2.Attr_API('SUM_TSW_HTTP_508', 1); + }else if(res.statusCode >= 500 && res.statusCode <= 599){ + isFail = 1; + tnm2.Attr_API('SUM_TSW_HTTP_500', 1); + }else{ + isFail = 2; + tnm2.Attr_API('SUM_TSW_HTTP_OTHER', 1); + } + + req.timestamps.ServerBeginResponse = req.timestamps.ServerBeginResponse || now; + req.timestamps.GotResponseHeaders = req.timestamps.ServerBeginResponse; + req.timestamps.ServerDoneResponse = res.ServerDoneResponse || now; + req.timestamps.ClientBeginResponse = req.timestamps.ServerBeginResponse; + req.timestamps.ClientDoneResponse = req.timestamps.ServerDoneResponse; + + + if(isFail === 1){ + logger.debug('finish, statusCode: ${statusCode},cost: ${cost}ms',{ + statusCode: res.statusCode, + cost: Date.now() - start.getTime() + }); + + if(typeof req.REQUEST.body === 'string'){ + + if(req.REQUEST.body.length < 32 * 1024){ + logger.debug('\n${head}${body}',{ + head: httpUtil.getRequestHeaderStr(req), + body: req.REQUEST.body || '' + }); + }else{ + logger.debug('\n${head}${body}',{ + head: httpUtil.getRequestHeaderStr(req), + body: 'body size >= 32KB' + }); + } + }else{ + + logger.debug('\n${head}${body}',{ + head: httpUtil.getRequestHeaderStr(req), + body: req.REQUEST.body || '' + }); + } + + }else{ + logger.debug('finish, statusCode: ${statusCode}, cost: ${cost}ms',{ + statusCode: res.statusCode, + cost: Date.now() - start.getTime() + }); + } + + if(res.__hasTimeout && isFail !== 1){ + + dcapi.report({ + key : 'EVENT_TSW_HTTP_TIMEOUT', + toIp : '127.0.0.1', + code : res.statusCode || 0, + isFail : isFail, + delay : Date.now() - start.getTime() + }); + + }else if(res.__hasClosed){ + + dcapi.report({ + key : 'EVENT_TSW_HTTP_CLOSE', + toIp : '127.0.0.1', + code : res.statusCode || 0, + isFail : isFail, + delay : Date.now() - start.getTime() + }); + }else{ + + dcapi.report({ + key : 'EVENT_TSW_HTTP_PAGE', + toIp : '127.0.0.1', + code : res.statusCode || 0, + isFail : isFail, + delay : Date.now() - start.getTime() + }); + + dcapi.report({ + key : 'EVENT_TSW_HTTP_CODE', + toIp : '127.0.0.1', + code : res.statusCode || 0, + isFail : isFail, + delay : Date.now() - start.getTime() + }); + + } + + + res.emit('afterFinish'); + }); + + d.run(function(){ + tid = setTimeout(function(){ + + res.__hasTimeout = true; + + logger.debug('timeout: ' + timeLimit); + + onerror(req,res,new Error('timeout')); + + if(res.__hasClosed){ + + try{res.writeHead(202); }catch(e){logger.info(`response 202 fail ${e.message}`);} + try{res.end();}catch(e){logger.info(`response end fail ${e.message}`);} + try{res.emit('done');}catch(e){logger.info(`emit done event fail ${e.message}`);} + }else if(res.finished){ + + try{res.end();}catch(e){logger.info(`response end fail ${e.message}`);} + try{res.emit('done');}catch(e){logger.info(`emit done event fail ${e.message}`);} + }else if(!res._headerSent && !res.headersSent && !res.finished && res.statusCode === 200){ + logger.debug('statusCode: ${statusCode}, _headerSent: ${_headerSent}, headersSent: ${headersSent}, finished: ${finished}',res); + + //输出一条错误log方便定位问题 + logger.error('response timeout http://${host}${url}',{ + url: req.url, + host: req.headers.host + }); + + try{res.writeHead(513); }catch(e){logger.info(`response 513 fail ${e.message}`);} + try{res.end();}catch(e){logger.info(`response end fail ${e.message}`);} + + try{res.emit('done');}catch(e){logger.info(`emit done event fail ${e.message}`);} + }else{ + logger.debug('statusCode: ${statusCode}, _headerSent: ${_headerSent}, headersSent: ${headersSent}, finished: ${finished}',res); + + try{res.end();}catch(e){logger.info(`response end fail ${e.message}`);} + try{res.emit('done');}catch(e){logger.info(`emit done event fail ${e.message}`);} + } + + req.emit('close'); + },timeLimit); + + doRoute(req,res); + }); + +}; + +module.exports.doRoute = doRoute; + +function doRoute(req,res){ + + var clientIp = httpUtil.getUserIp(req); + var userIp24 = httpUtil.getUserIp24(req); + + //增加测试环境header + if(config.isTest) { + res.setHeader('Test-Head', serverInfo.intranetIp || ''); + } + + logger.debug('${method} ${protocol}://${host}${path}',{ + protocol: req.REQUEST.protocol, + path: req.REQUEST.path, + host: req.headers.host, + method: req.method + }); + + logger.debug('idc: ${idc}, server ip: ${intranetIp}, tcp: ${remoteAddress}:${remotePort} > ${localAddress}:${localPort}, client ip: ${clientIp}, cpuUsed: ${cpuUsed}',{ + cpuUsed: global.cpuUsed, + idc: config.idc, + intranetIp: serverInfo.intranetIp, + clientIp: clientIp, + remoteAddress: (req.socket && req.socket.remoteAddress), + remotePort: (req.socket && req.socket.remotePort), + localAddress: (req.socket && req.socket.localAddress), + localPort: (req.socket && req.socket.localPort) + }); + + if(config.isTest){ + logger.debug('config.isTest is true'); + if(isTST.isTST(req)){ + res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'}); + res.end(); + return; + } + } + + + //安全中心扫描报个指标 + //支持从配置中直接屏蔽安全中心扫描请求 + if(isTST.isTST(req)){ + tnm2.Attr_API('SUM_TSW_HTTP_TST', 1); + + if(config.ignoreTST){ + logger.debug('ignore TST request'); + + res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'}); + res.end('200'); + + return; + } + } + + if(config.devMode){ + logger.debug('config.devMode is true'); + } + + //log自动上报 + logReport(req,res); + + res.writeHead = (function(fn){ + return function(...args){ + if(alpha.isAlpha(req)){ + if(logger.getLog()){ + logger.getLog().showLineNumber = true; + logger.debug('showLineNumber on'); + } + + //抓回包 + httpUtil.captureBody(this); + } + + logger.debug('response ${statusCode}',{ + statusCode: args[0] + }); + + return fn.apply(this,args); + }; + }(res.writeHead)); + + var mod_act = contextMod.currentContext().mod_act || httpModAct.getModAct(req); + contextMod.currentContext().mod_act = mod_act; + + if(alpha.isAlpha(req)){ + if(logger.getLog()){ + logger.getLog().showLineNumber = true; + logger.debug('showLineNumber on'); + } + } + + logger.debug('node-${version}, name: ${name}, appid: ${appid}',{ + version: process.version, + name: mod_act || null, + appid: config.appid || null + }); + + //测试环境 + if(h5test.isTestUser(req, res)){ + return; + } + + //跟踪url调用深度 + var steps = parseInt(req.headers['tsw-trace-steps'] || '0') || 0; + + //深度超过5层,直接拒绝 + if(steps >= 5){ + + tnm2.Attr_API('SUM_TSW_ROUTE_EXCEED', 1); + + try{ + res.writeHead(503, {'Content-Type': 'text/html; charset=UTF-8'}); + res.end('503'); + }catch(e){ + logger.info(`response 503 fail ${e.message}`); + } + + return; + } + + req.headers['tsw-trace-steps'] = steps + 1; + + var modulePath = httpModMap.find(mod_act,req,res); + + if(res.headersSent || res._headerSent || res.finished){ + return; + } + + if(modulePath && typeof modulePath.handle === 'function'){ + let app = modulePath; + + modulePath = function(req,res,plug){ + return app.handle(req,res); + }; + } + + if(modulePath && typeof modulePath.callback === 'function'){ + let app = modulePath; + + modulePath = function(req,res,plug){ + return app.callback()(req,res); + }; + } + + if(typeof modulePath !== 'function'){ + if(req.REQUEST.pathname === '/419') { + if(typeof config.page419 === 'string'){ + modulePath = require(config.page419); + } + } else { + if(typeof config.page404 === 'string'){ + modulePath = require(config.page404); + } + } + } + + if(typeof modulePath !== 'function'){ + try{ + res.writeHead(404, {'Content-Type': 'text/html; charset=UTF-8'}); + res.end('404'); + }catch(e){ + logger.info(`response 404 fail ${e.message}`); + } + return; + } + + var modulePathHandler = function(){ + var maybePromise = modulePath(req, res, plug); + if( + typeof maybePromise === 'object' + && + typeof maybePromise.catch === 'function' + ){ + maybePromise.catch(function(err){ + logger.error(err); + process.domain && process.domain.emit('error',err); + }); + } + }; + + var blackIpMap = TSW.getBlockIpMapSync() || {}; + + if(blackIpMap[clientIp] || blackIpMap[userIp24] || !clientIp){ + logger.debug('连接已断开'); + + tnm2.Attr_API('SUM_TSW_IP_EMPTY', 1); + res.writeHead(403, {'Content-Type': 'text/plain; charset=UTF-8'}); + res.end(); + return; + } + + if(blackIpMap[clientIp] || blackIpMap[userIp24]){ + logger.debug('命中黑名单IP'); + + dcapi.report({ + key : 'EVENT_TSW_HTTP_IP_BLOCK', + toIp : clientIp || '127.0.0.1', + code : 0, + isFail : 0, + delay : 100 + }); + tnm2.Attr_API('SUM_TSW_IP_BLOCK', 1); + res.writeHead(403, {'Content-Type': 'text/plain; charset=UTF-8'}); + res.end(); + return; + } + + if(CCFinder.checkHost(req,res) === false){ + return; + } + + if(CCFinder.check(req,res) === false){ + return; + } + + //webso柔性 + if(global.cpuUsed > 80){ + + if(httpUtil.isFromWns(req) && req.headers['if-none-match']){ + + logger.debug('webso limit 304, cpuUsed: ${cpuUsed}',{ + cpuUsed : global.cpuUsed + }); + + tnm2.Attr_API('SUM_TSW_WEBSO_LIMIT', 1); + try{ + res.writeHead(304, { + 'Content-Type': 'text/html; charset=UTF-8', + 'Etag': req.headers['if-none-match'] + }); + res.end(); + }catch(e){ + logger.info(`response 304 fail ${e.message}`); + } + + return; + } + + } + + var contentType = req.headers['content-type'] || 'application/x-www-form-urlencoded'; + + if(req.method === 'GET' || req.method === 'HEAD'){ + + if(httpUtil.isFromWns(req)){ + //wns请求不过门神检查 + return modulePathHandler(); + } + + xssFilter.check().done(function(){ + return modulePathHandler(); + }).fail(function(){ + res.writeHead(501, {'Content-Type': 'text/plain; charset=UTF-8'}); + res.end('501 by TSW'); + }); + }else if(context.autoParseBody === false){ + return modulePathHandler(); + }else if( + contentType.indexOf('application/x-www-form-urlencoded') > -1 + || contentType.indexOf('text/plain') > -1 + || contentType.indexOf('application/json') > -1 + ){ + parseBody(req,res,function(){ + return modulePathHandler(); + }); + }else{ + return modulePathHandler(); + } + +} + + + +function onerror(req,res,err){ + var listener = req.listeners('fail'); + var window = context.window || {}; + + if(res.headersSent || res._headerSent || res.finished){ + return; + } + + if(listener && listener.length > 0){ + try{ + req.emit('fail',err); + }catch(e){ + logger.error(e && e.stack); + } + + req.removeAllListeners('fail'); + + }else if(window.onerror){ + try{ + window.onerror(err); + }catch(e){ + logger.error(e && e.stack); + } + + window.onerror = null; + } } \ No newline at end of file diff --git a/bin/proxy/index.js b/bin/proxy/index.js index 5853a11e..9727e5bc 100644 --- a/bin/proxy/index.js +++ b/bin/proxy/index.js @@ -1,21 +1,21 @@ -/*! - * Tencent is pleased to support the open source community by making Tencent Server Web available. - * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. - * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - * http://opensource.org/licenses/MIT - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ -"use strict"; - -const plug = require('../tsw/plug.js'); - -plug('runtime/Console.hack.js'); -plug('runtime/fs.hack.js'); -plug('runtime/Dns.hack.js'); -plug('runtime/overloadProtection.js'); -plug('runtime/capturer.js'); - -require('./master.js'); - - - +/*! + * Tencent is pleased to support the open source community by making Tencent Server Web available. + * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ +'use strict'; + +const plug = require('../tsw/plug.js'); + +plug('runtime/Console.hack.js'); +plug('runtime/fs.hack.js'); +plug('runtime/Dns.hack.js'); +plug('runtime/overloadProtection.js'); +plug('runtime/capturer.js'); + +require('./master.js'); + + + diff --git a/bin/proxy/master.js b/bin/proxy/master.js index ebfb9343..3470f18f 100644 --- a/bin/proxy/master.js +++ b/bin/proxy/master.js @@ -5,101 +5,93 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const logger = require('logger'); const cp = require('child_process'); -const net = require('net'); const config = require('./config.js'); const cluster = require('cluster'); -const os = require('os'); const cpuUtil = require('util/cpu.js'); const fs = require('fs'); const serverOS = require('util/isWindows.js'); -const {intranetIp} = require('serverInfo.js'); const {debugOptions} = process.binding('config'); const methodMap = {}; const workerMap = {}; const cpuMap = []; -const timePos = parseInt(String(intranetIp).slice(-1),10) || 0; //时间偏移 var isDeaded = false; //阻止进程因异常而退出 process.on('uncaughtException',function(e){ - if (e && e.message && /\blisten EACCES\b/.test(e.message) && config.httpPort < 1024 && (serverOS.isOSX || serverOS.isLinux)) { - logger.error('This is OSX/Linux, you may need to use "sudo" prefix to start server.\n'); - } + if (/\blisten EACCES\b/.test(e.message) && config.httpPort < 1024 && (serverOS.isOSX || serverOS.isLinux)) { + logger.error('This is OSX/Linux, you may need to use "sudo" prefix to start server.\n'); + } - logger.error(e && e.stack); + logger.error(e && e.stack); }); process.on('warning',function(warning){ - var key = String(warning); - var errStr = warning && warning.stack || String(warning); - - logger.error(errStr); + var key = String(warning); + var errStr = warning && warning.stack || String(warning); - if(!(typeof window)){ - return; - } + logger.error(errStr); - var Content = [ - '

错误堆栈

', - '

',
-		errStr,
-		'

', - ].join(''); + var Content = [ + '

错误堆栈

', + '

',
+        errStr,
+        '

', + ].join(''); - setImmediate(function(){ - require('util/mail/mail.js').SendMail(key,'js',600,{ - 'Title' : key, - 'runtimeType' : 'warning', - 'Content' : Content - }); - }) + setImmediate(function(){ + require('util/mail/mail.js').SendMail(key,'js',600,{ + 'Title' : key, + 'runtimeType' : 'warning', + 'Content' : Content + }); + }); }); process.on('unhandledRejection', (reason = {}, p = {}) => { - let - key = String(reason.message), - errStr = String(reason.stack), - mod_act, module, REQUEST; + let + key = String(reason.message), + errStr = String(reason.stack), + mod_act, module, REQUEST; - if(p && p.domain && p.domain.currentContext){ - mod_act = p.domain.currentContext.mod_act; + if(p && p.domain && p.domain.currentContext){ + mod_act = p.domain.currentContext.mod_act; module = p.domain.currentContext.module; REQUEST = p.domain.currentContext.window.request.REQUEST; - } + } - if(errStr === 'undefined'){ + if(errStr === 'undefined'){ - let reasonStr = JSON.stringify(reason); + let reasonStr = JSON.stringify(reason); - logger.error('unhandledRejection reason: ' + reasonStr); + logger.error('unhandledRejection reason: ' + reasonStr); - if(reasonStr === '{}'){ - return; - } + if(reasonStr === '{}'){ + return; + } - errStr = reasonStr; - } + errStr = reasonStr; + } - logger.error(errStr); + logger.error(errStr); - var Content = [ - '

错误堆栈

', - '

',
-		errStr,
-		'

', - ].join(''); + var Content = [ + '

错误堆栈

', + '

',
+        errStr,
+        '

', + ].join(''); - if(mod_act){ - Content += `

mod_act: ${mod_act}

`; - } + if(mod_act){ + Content += `

mod_act: ${mod_act}

`; + } if(module){ Content += `

module: ${module}

`; } @@ -107,15 +99,15 @@ process.on('unhandledRejection', (reason = {}, p = {}) => { Content += `

url: ${REQUEST.protocol}://${REQUEST.hostname}${REQUEST.href}

`; } - if(serverOS.isWindows){ - //return; - } + if(serverOS.isWindows){ + //return; + } - require('util/mail/mail.js').SendMail(key,'js',600,{ - 'Title' : key, - 'runtimeType' : 'unhandledRejection', - 'Content' : Content - }); + require('util/mail/mail.js').SendMail(key,'js',600,{ + 'Title' : key, + 'runtimeType' : 'unhandledRejection', + 'Content' : Content + }); }); process.noProcessWarnings = true; @@ -130,296 +122,290 @@ startServer(); */ function startServer(){ - var useWorker = true; + var useWorker = true; - if(!serverOS.isLinux){ - useWorker = false; - } + if(!serverOS.isLinux){ + useWorker = false; + } - if(debugOptions && debugOptions.inspectorEnabled){ - useWorker = false; - } + if(debugOptions && debugOptions.inspectorEnabled){ + useWorker = false; + } - cluster.schedulingPolicy = cluster.SCHED_RR; + cluster.schedulingPolicy = cluster.SCHED_RR; - if(cluster.isMaster && useWorker){ + if(cluster.isMaster && useWorker){ - global.cpuUsed = cpuUtil.getCpuUsed(); - setInterval(function(){ - global.cpuUsed = cpuUtil.getCpuUsed(); - },3000); + global.cpuUsed = cpuUtil.getCpuUsed(); + setInterval(function(){ + global.cpuUsed = cpuUtil.getCpuUsed(); + },3000); - //启动管理进程 - require('./admin.js'); + //启动管理进程 + require('./admin.js'); - logger.info('start master....'); - logger.info('version node: ${node}, modules: ${modules}',process.versions); - - if(serverOS.isLinux){ - //当前目录777,为heapsnapshot文件创建提供权限 - fs.chmodSync(__dirname, 0x1ff); //0777 - - //清除heapsnapshot文件 - cp.exec('rm -rf ./*.heapsnapshot',{ - timeout: 5000, - cwd: __dirname - },function(err){ - if(err){ - logger.error(err.stack); - } - }); - } - - //根据cpu数来初始化并启动子进程 - if(config.runAtThisCpu === 'auto'){ - cpuUtil.cpus().forEach(function(v,i){ - cpuMap.push(0); - cluster.fork(process.env).cpuid = i; - }); - }else{ - config.runAtThisCpu.forEach(function(v,i){ - cpuMap.push(0); - cluster.fork(process.env).cpuid = v; - }); - } - - //监听子进程是否fork成功 - cluster.on('fork',function(currWorker){ + logger.info('start master....'); + logger.info('version node: ${node}, modules: ${modules}',process.versions); + + if(serverOS.isLinux){ + //当前目录777,为heapsnapshot文件创建提供权限 + fs.chmodSync(__dirname, 0x1ff); //0777 + + //清除heapsnapshot文件 + cp.exec('rm -rf ./*.heapsnapshot',{ + timeout: 5000, + cwd: __dirname + },function(err){ + if(err){ + logger.error(err.stack); + } + }); + } + + //根据cpu数来初始化并启动子进程 + if(config.runAtThisCpu === 'auto'){ + cpuUtil.cpus().forEach(function(v,i){ + cpuMap.push(0); + cluster.fork(process.env).cpuid = i; + }); + }else{ + config.runAtThisCpu.forEach(function(v,i){ + cpuMap.push(0); + cluster.fork(process.env).cpuid = v; + }); + } + + //监听子进程是否fork成功 + cluster.on('fork',function(currWorker){ - var cpu = getToBindCpu(currWorker); + var cpu = getToBindCpu(currWorker); - logger.info('worker fork success! pid:${pid} cpu: ${cpu}',{ - pid: currWorker.process.pid, - cpu: cpu - }); - - //绑定cpu - cpuUtil.taskset(cpu,currWorker.process.pid); + logger.info('worker fork success! pid:${pid} cpu: ${cpu}',{ + pid: currWorker.process.pid, + cpu: cpu + }); - if(workerMap[cpu]){ - closeWorker(workerMap[cpu]); - } + if(workerMap[cpu]){ + closeWorker(workerMap[cpu]); + } - workerMap[cpu] = currWorker; - cpuMap[cpu] = 1; + workerMap[cpu] = currWorker; + cpuMap[cpu] = 1; - //监听子进程发来的消息并处理 - currWorker.on('message',function(...args){ - var m = args[0]; - if(m && methodMap[m.cmd]){ - methodMap[m.cmd].apply(this,args); - } - }); + //监听子进程发来的消息并处理 + currWorker.on('message',function(...args){ + var m = args[0]; + if(m && methodMap[m.cmd]){ + methodMap[m.cmd].apply(this,args); + } + }); - //给子进程发送消息,启动http服务 - currWorker.send({ - from:'master', - cmd:'listen', - cpu: cpu - }); + //给子进程发送消息,启动http服务 + currWorker.send({ + from:'master', + cmd:'listen', + cpu: cpu + }); - }); + }); - //退出时 - cluster.on('disconnect', function(worker) { - var cpu = getToBindCpu(worker); + //退出时 + cluster.on('disconnect', function(worker) { + var cpu = getToBindCpu(worker); - if(worker.hasRestart){ - return; - } + if(worker.hasRestart){ + return; + } - logger.info('worker${cpu} pid=${pid} has disconnected. restart new worker again.',{ - pid: worker.process.pid, - cpu: cpu - }); + logger.info('worker${cpu} pid=${pid} has disconnected. restart new worker again.',{ + pid: worker.process.pid, + cpu: cpu + }); - restartWorker(worker); - }); + restartWorker(worker); + }); - //子进程被杀死的时候做下处理,原地复活 - cluster.on('exit',function(worker){ + //子进程被杀死的时候做下处理,原地复活 + cluster.on('exit',function(worker){ - var cpu = getToBindCpu(worker); + var cpu = getToBindCpu(worker); - if(worker.hasRestart){ - return; - } + if(worker.hasRestart){ + return; + } - logger.info('worker${cpu} pid=${pid} has been killed. restart new worker again.',{ - pid: worker.process.pid, - cpu: cpu - }); + logger.info('worker${cpu} pid=${pid} has been killed. restart new worker again.',{ + pid: worker.process.pid, + cpu: cpu + }); - restartWorker(worker); - }); + restartWorker(worker); + }); - process.on('reload',function(GET){ + process.on('reload',function(GET){ - var now = new Date().getTime(), - timeout = 1000, - cpu = 0, - key,worker; + var timeout = 1000, + cpu = 0, + key,worker; - if(isDeaded){ - process.exit(0); - } + if(isDeaded){ + process.exit(0); + } - logger.info('reload'); + logger.info('reload'); - for(key in workerMap){ - worker = workerMap[key]; - try{ + for(key in workerMap){ + worker = workerMap[key]; + try{ - cpu = getToBindCpu(worker); - - if(config.isTest || config.devMode){ - timeout = (cpu % 8) * 1000; - }else{ - timeout = (cpu % 8) * 3000; - } - - setTimeout(function(worker,cpu){ - return function(){ - if(!worker.exitedAfterDisconnect){ - logger.info('cpu${cpu} send restart message',{ - cpu: cpu - }); - worker.send({from:'master',cmd:'restart'}); - } - restartWorker(worker); - } - }(worker,cpu),timeout); - - logger.info('cpu${cpu} reload after ${timeout}ms',{ - cpu: cpu, - timeout: timeout - }); - - }catch(e){ - logger.error(e.stack); - } - } - - }); + cpu = getToBindCpu(worker); + + if(config.isTest || config.devMode){ + timeout = (cpu % 8) * 1000; + }else{ + timeout = (cpu % 8) * 3000; + } + + setTimeout(function(worker,cpu){ + return function(){ + if(!worker.exitedAfterDisconnect){ + logger.info('cpu${cpu} send restart message',{ + cpu: cpu + }); + worker.send({from:'master',cmd:'restart'}); + } + restartWorker(worker); + }; + }(worker,cpu),timeout); + + logger.info('cpu${cpu} reload after ${timeout}ms',{ + cpu: cpu, + timeout: timeout + }); + + }catch(e){ + logger.error(e.stack); + } + } + + }); + + process.on('sendCmd2workerOnce',function(data){ + + var key,worker; + var CMD = data.CMD; + var GET = data.GET; + + if(isDeaded){ + process.exit(0); + } + + logger.info('sendCmd2workerOnce CMD: ${CMD}',{ + CMD + }); + + var targetCpu = GET.cpu || 0; + + for(key in workerMap){ + worker = workerMap[key]; + try{ + if(targetCpu == getToBindCpu(worker)){ + if(!worker.exitedAfterDisconnect){ + worker.send({from:'master', cmd:CMD, GET: GET}); + } + break; + } + }catch(e){ + logger.error(e.stack); + } + } + }); + + checkWorkerAlive(); + startLogMan(); - process.on('heapdump',function(GET){ - sendCmd2workerOnce('heapdump',GET); - }); - - process.on('sendCmd2workerOnce',function(data){ - - var key,worker; - var CMD = data.CMD; - var GET = data.GET; - - if(isDeaded){ - process.exit(0); - } - - logger.info('sendCmd2workerOnce CMD: ${CMD}',{ - CMD - }); - - var targetCpu = GET.cpu || 0; - - for(key in workerMap){ - worker = workerMap[key]; - try{ - if(targetCpu == getToBindCpu(worker)){ - if(!worker.exitedAfterDisconnect){ - worker.send({from:'master', cmd:CMD, GET: GET}); - } - break; - } - }catch(e){ - logger.error(e.stack); - } - } - }); - - checkWorkerAlive(); - startLogMan(); + //process.title = 'TSW/master/node'; + //保留node命令,不然运维监控不到 - //process.title = 'TSW/master/node'; - //保留node命令,不然运维监控不到 + }else{ - }else{ - - //子进程直接引入proxy文件,当然也可以直接在这里写逻辑运行,注意此处else作用域属于子进程作用域,非本程序作用域 - process.title = 'TSW/worker/node'; - logger.info('start worker....'); - require('./http.proxy.js'); - require('runtime/JankWatcher.js'); - - //30分钟后开始算 - !config.isTest && !config.devMode && - setTimeout(function(){ - require('runtime/md5.check.js').check(); - },30 * 60000); - } - + //子进程直接引入proxy文件,当然也可以直接在这里写逻辑运行,注意此处else作用域属于子进程作用域,非本程序作用域 + process.title = 'TSW/worker/node'; + logger.info('start worker....'); + require('./http.proxy.js'); + require('runtime/JankWatcher.js'); + + //30分钟后开始算 + !config.isTest && !config.devMode && + setTimeout(function(){ + require('runtime/md5.check.js').check(); + },30 * 60000); + } } //处理子进程的心跳消息 methodMap.heartBeat = function(m){ - var worker = this; - var now = new Date().getTime(); + var worker = this; + var now = new Date().getTime(); - worker.lastMessage = m; - worker.lastLiveTime = now; + worker.lastMessage = m; + worker.lastLiveTime = now; }; //关闭一个worker function closeWorker(worker){ - var cpu = worker.cpuid; - var closeTimeWait = 10000; + var cpu = worker.cpuid; + var closeTimeWait = 10000; - closeTimeWait = Math.max(closeTimeWait,config.timeout.socket); - closeTimeWait = Math.max(closeTimeWait,config.timeout.post); - closeTimeWait = Math.max(closeTimeWait,config.timeout.get); - closeTimeWait = Math.max(closeTimeWait,config.timeout.keepAlive); - closeTimeWait = Math.min(60000,closeTimeWait) || 10000; + closeTimeWait = Math.max(closeTimeWait,config.timeout.socket); + closeTimeWait = Math.max(closeTimeWait,config.timeout.post); + closeTimeWait = Math.max(closeTimeWait,config.timeout.get); + closeTimeWait = Math.max(closeTimeWait,config.timeout.keepAlive); + closeTimeWait = Math.min(60000,closeTimeWait) || 10000; - if(worker.hasClose){ - return; - } + if(worker.hasClose){ + return; + } - if(workerMap[cpu] === worker){ - delete workerMap[cpu]; - } + if(workerMap[cpu] === worker){ + delete workerMap[cpu]; + } - var closeFn = function(worker){ - var closed = false; - var pid = worker.process.pid; + var closeFn = function(worker){ + var closed = false; + var pid = worker.process.pid; - return function(){ - if(closed){ - return; - } - try{ - process.kill(pid,9); - }catch(e){} - worker.destroy(); + return function(){ + if(closed){ + return; + } + try{ + process.kill(pid,9); + }catch(e){ + logger.info(`kill worker fail ${e.message}`); + } + + worker.destroy(); - closed = true; - } - }(worker); + closed = true; + }; + }(worker); - setTimeout(closeFn,closeTimeWait); - - if(worker.exitedAfterDisconnect){ - worker.hasClose = true; - return; - } - - try{ - worker.disconnect(closeFn); - }catch(e){ - logger.info(e.stack); - } + setTimeout(closeFn,closeTimeWait); + + if(worker.exitedAfterDisconnect){ + worker.hasClose = true; + return; + } + + try{ + worker.disconnect(closeFn); + }catch(e){ + logger.info(e.stack); + } } @@ -427,93 +413,92 @@ function closeWorker(worker){ * 重启worker */ function restartWorker(worker){ - var cpu = getToBindCpu(worker); + var cpu = getToBindCpu(worker); - if(worker.hasRestart){ - return; - } + if(worker.hasRestart){ + return; + } - logger.info('worker${cpu} pid=${pid} close. restart new worker again.',{ - pid: worker.process.pid, - cpu: cpu - }); + logger.info('worker${cpu} pid=${pid} close. restart new worker again.',{ + pid: worker.process.pid, + cpu: cpu + }); - setTimeout(function(){ - closeWorker(worker); - },10000); + setTimeout(function(){ + closeWorker(worker); + },10000); - cpuMap[cpu] = 0; + cpuMap[cpu] = 0; - worker.hasRestart = true; - cluster.fork(process.env).cpuid = cpu; -}; + worker.hasRestart = true; + cluster.fork(process.env).cpuid = cpu; +} //定时检测子进程死活,发现15秒没响应的就干掉 function checkWorkerAlive(){ - setInterval(function(){ + setInterval(function(){ - var - nowDate = new Date(), - now = nowDate.getTime(), - key,v, - worker, - cpuid, - i; + var + nowDate = new Date(), + now = nowDate.getTime(), + key, + worker, + cpuid; - for(key in workerMap){ - worker = workerMap[key]; - cpuid = worker.cpuid; + for(key in workerMap){ + worker = workerMap[key]; + cpuid = worker.cpuid; - worker.lastLiveTime = worker.lastLiveTime || now; - if(!worker.startTime){ - worker.startTime = now; - } + worker.lastLiveTime = worker.lastLiveTime || now; + if(!worker.startTime){ + worker.startTime = now; + } - //无响应进程处理 - if(now - worker.lastLiveTime > 15000 && cpuMap[cpuid] === 1){ + //无响应进程处理 + if(now - worker.lastLiveTime > 15000 && cpuMap[cpuid] === 1){ - logger.error('worker${cpu} pid=${pid} miss heartBeat, kill it',{ - pid : worker.process.pid, - cpu: cpuid - }); + logger.error('worker${cpu} pid=${pid} miss heartBeat, kill it',{ + pid : worker.process.pid, + cpu: cpuid + }); - restartWorker(worker); - } + restartWorker(worker); + } - //内存超限进程处理 - if(worker.lastMessage){ - let currMemory = worker.lastMessage.memoryUsage; + //内存超限进程处理 + if(worker.lastMessage){ + let currMemory = worker.lastMessage.memoryUsage; - //logger.debug(currMemory); + //logger.debug(currMemory); - if(currMemory && currMemory.rss > config.memoryLimit){ + if(currMemory && currMemory.rss > config.memoryLimit){ - logger.error('worker${cpu} pid=${pid} memoryUsage ${memoryUsage}, hit memoryLimit: ${memoryLimit}, kill it',{ - memoryUsage: currMemory.rss, - memoryLimit: config.memoryLimit, - pid : worker.process.pid, - cpu: cpuid - }); + logger.error('worker${cpu} pid=${pid} memoryUsage ${memoryUsage}, hit memoryLimit: ${memoryLimit}, kill it',{ + memoryUsage: currMemory.rss, + memoryLimit: config.memoryLimit, + pid : worker.process.pid, + cpu: cpuid + }); - logger.error(worker.lastMessage); + logger.error(worker.lastMessage); - restartWorker(worker); - } - } - } + restartWorker(worker); + } + } + } - if( - true + if( + true && (nowDate.getHours() % 8 === 0) && nowDate.getMinutes() === 1 && nowDate.getSeconds() <= 10 - ){ - //8小时一次 - require('api/keyman/runtimeAdd.js').hello(); - } + ){ + //8小时一次 + require('api/keyman/runtimeAdd.js').hello(); + } - },5000); + },5000); } /** @@ -521,69 +506,33 @@ function checkWorkerAlive(){ */ function getToBindCpu(worker){ - var cpu = 0;//如果只有一个cpu或者都占用了 - - if(worker.cpuid !== undefined){ - cpu = worker.cpuid; - return cpu; - }else{ - for(var i=0;i 0){ - if(opt.enctype === 'application/json'){ + //优先使用body + if(!opt.body && opt.data && Object.keys(opt.data).length > 0){ + if(opt.enctype === 'application/json'){ - opt.headers['content-type'] = 'application/json'; - opt.body = JSON.stringify(opt.data); + opt.headers['content-type'] = 'application/json'; + opt.body = JSON.stringify(opt.data); - }else if(opt.enctype === 'multipart/form-data'){ + }else if(opt.enctype === 'multipart/form-data'){ - opt.boundary = opt.boundary || Math.random().toString(16); - opt.headers['content-type'] = 'multipart/form-data; boundary=' + opt.boundary; + opt.boundary = opt.boundary || Math.random().toString(16); + opt.headers['content-type'] = 'multipart/form-data; boundary=' + opt.boundary; - opt.body = form.getFormBuffer(opt); + opt.body = form.getFormBuffer(opt); - }else{ - opt.headers['content-type'] = opt.enctype; - opt.body = qs.stringify(opt.data, { arrayFormat: 'brackets', skipNulls: true, encoder: opt.encoder }); - } - } - }else{ - if(!opt.isRetriedRequest){ + }else{ + opt.headers['content-type'] = opt.enctype; + opt.body = qs.stringify(opt.data, { arrayFormat: 'brackets', skipNulls: true, encoder: opt.encoder }); + } + } + }else{ + if(!opt.isRetriedRequest){ let query = qs.stringify(opt.data, { arrayFormat: 'brackets', skipNulls: true, encoder: opt.encoder }); if(query){ if(opt.path.indexOf('?') === -1){ @@ -369,811 +358,811 @@ Ajax.prototype.doRequest = function(opt){ opt.path = opt.path + '&' + query; } } - } - } + } + } - if(config.isTest){ + if(config.isTest){ - if(opt.testIp){ - logger.debug('use testIp'); - - //测试环境模式 - opt.ip = opt.testIp || opt.ip; - opt.port = opt.testPort || opt.port; - } - }else if((config.devMode || isWindows)){ - - if(opt.devIp){ - logger.debug('use devIp'); - //开发者模式 - opt.ip = opt.devIp || opt.ip; - opt.port = opt.devPort || opt.port; - opt.proxyPort = null; - } - - } - - - if(opt.host){ - opt.headers.host = opt.host; - }else{ - opt.host = opt.headers.host; - } - - if(opt.useIPAsHost){ - opt.headers.host = opt.ip; - } - - if(currRetry === opt.retry){ - //防止重复注册 - opt.success && defer.done(opt.success); - opt.error && defer.fail(opt.error); - } - - //开始时间点 - times.start = new Date().getTime(); - - function report(opt, isFail, code) { + if(opt.testIp){ + logger.debug('use testIp'); + + //测试环境模式 + opt.ip = opt.testIp || opt.ip; + opt.port = opt.testPort || opt.port; + } + }else if((config.devMode || isWindows)){ + + if(opt.devIp){ + logger.debug('use devIp'); + //开发者模式 + opt.ip = opt.devIp || opt.ip; + opt.port = opt.devPort || opt.port; + opt.proxyPort = null; + } + + } + + + if(opt.host){ + opt.headers.host = opt.host; + }else{ + opt.host = opt.headers.host; + } + + if(opt.useIPAsHost){ + opt.headers.host = opt.ip; + } + + if(currRetry === opt.retry){ + //防止重复注册 + opt.success && defer.done(opt.success); + opt.error && defer.fail(opt.error); + } + + //开始时间点 + times.start = new Date().getTime(); + + function report(opt, isFail, code) { - if(isTST.isTST(opt)){ - //忽略安全中心请求 - return; - } - - if(isFail === 1 && opt.ignoreErrorReport){ - isFail = 2; - } - - if(opt.dcapi){ - - logger.debug(logPre + '返回码:' + code + ', isFail:' + isFail); - - dcapi.report(Deferred.extend({},opt.dcapi,{ - toIp : opt.ip, - code : code, - isFail : isFail, - delay : new Date - times.start - })); - } - } + if(isTST.isTST(opt)){ + //忽略安全中心请求 + return; + } + + if(isFail === 1 && opt.ignoreErrorReport){ + isFail = 2; + } + + if(opt.dcapi){ + + logger.debug(logPre + '返回码:' + code + ', isFail:' + isFail); + + dcapi.report(Deferred.extend({},opt.dcapi,{ + toIp : opt.ip, + code : code, + isFail : isFail, + delay : new Date - times.start + })); + } + } - //解决undefined报错问题 - for(key in opt.headers){ - v = opt.headers[key]; - - if(v === undefined){ - logger.debug('delete header: ${key}',{ - key: key - }); - delete opt.headers[key]; - continue; - } - - if(v === null){ - logger.debug('delete header: ${key}',{ - key: key - }); - delete opt.headers[key]; - continue; - } - - if(key.indexOf(' ') >= 0){ - logger.debug('delete header: ${key}',{ - key: key - }); - delete opt.headers[key]; - continue; - } - - v = httpUtil.filterInvalidHeaderChar(v); - - if(v !== opt.headers[key]){ - opt.headers[key] = v; - - logger.debug('find invalid characters in header: ${key}',{ - key: key - }); - } - } + //解决undefined报错问题 + for(key in opt.headers){ + v = opt.headers[key]; + + if(v === undefined){ + logger.debug('delete header: ${key}',{ + key: key + }); + delete opt.headers[key]; + continue; + } + + if(v === null){ + logger.debug('delete header: ${key}',{ + key: key + }); + delete opt.headers[key]; + continue; + } + + if(key.indexOf(' ') >= 0){ + logger.debug('delete header: ${key}',{ + key: key + }); + delete opt.headers[key]; + continue; + } + + v = httpUtil.filterInvalidHeaderChar(v); + + if(v !== opt.headers[key]){ + opt.headers[key] = v; + + logger.debug('find invalid characters in header: ${key}',{ + key: key + }); + } + } - if((httpUtil.isPostLike(opt.type)) && opt.dataType === 'proxy' && this._proxyRequest){ - - if(this._proxyRequest.REQUEST.body !== undefined){ - opt.body = this._proxyRequest.REQUEST.body; - }else{ - opt.send = function(request){ - that._proxyRequest.on('data',function(buffer){ - request.write(buffer); - }); + if((httpUtil.isPostLike(opt.type)) && opt.dataType === 'proxy' && this._proxyRequest){ + + if(this._proxyRequest.REQUEST.body !== undefined){ + opt.body = this._proxyRequest.REQUEST.body; + }else{ + opt.send = function(request){ + that._proxyRequest.on('data',function(buffer){ + request.write(buffer); + }); - that._proxyRequest.once('end',function(buffer){ - that._proxyRequest.removeAllListeners('data'); - request.end(); - }); - } - } - } + that._proxyRequest.once('end',function(buffer){ + that._proxyRequest.removeAllListeners('data'); + request.end(); + }); + }; + } + } - if(httpUtil.isGetLike(opt.type) && opt.headers['content-length']){ + if(httpUtil.isGetLike(opt.type) && opt.headers['content-length']){ - logger.debug('reset Content-Length: 0 , origin: ' + opt.headers['content-length']); + logger.debug('reset Content-Length: 0 , origin: ' + opt.headers['content-length']); - delete opt.headers['content-length']; - delete opt.headers['content-type']; - opt.body = null; - }else if(opt.body){ - if(Buffer.isBuffer(opt.body)){ - - }else{ - opt.body = Buffer.from(opt.body,'UTF-8'); - } + delete opt.headers['content-length']; + delete opt.headers['content-type']; + opt.body = null; + }else if(opt.body){ + if(!Buffer.isBuffer(opt.body)){ + opt.body = Buffer.from(opt.body,'UTF-8'); + } - opt.headers['Content-Length'] = opt.body.length; - } - - if(opt.protocol === 'https:'){ - //https不走代理 - opt.proxyIp = null; - opt.proxyPort= null; - }; - - //过滤特殊字符 - if(httpUtil.checkInvalidHeaderChar(opt.path)){ - opt.path = encodeURI(opt.path); - } - - logger.debug(logPre + '${type} ${dataType} ~ ${ip}:${port} ${protocol}//${host}${path}',{ - protocol : opt.protocol, - type : opt.type, - dataType : opt.dataType, - ip : opt.proxyIp || opt.ip || opt.host, - port : opt.proxyPort || opt.port, - host : opt.host, - path : opt.path - }); - - if(opt.proxyPort){ - opt.proxyPath = 'http://' + opt.host + opt.path; - } - - - if(opt.agent){ - currAgent = opt.agent; - }else if(opt.keepAlive === 'https'){ - if(opt.protocol === 'https:'){ - currAgent = optionsUtil.getHttpsAgent(opt.headers.host); - }else{ - currAgent = false; - } - }else if(opt.keepAlive){ - if(opt.protocol === 'https:'){ - currAgent = optionsUtil.getHttpsAgent(opt.headers.host); - }else{ - currAgent = optionsUtil.getHttpAgent(opt.headers.host); - } - }else{ - currAgent = false; - } - - request = (opt.protocol === 'https:' ? https : http).request({ - agent : currAgent, - host : opt.proxyIp || opt.ip || opt.host, - port : opt.proxyPort || opt.port, - path : opt.proxyPath || opt.path, - method : opt.type, - headers : opt.headers - }); - - request.setNoDelay(true); - request.setSocketKeepAlive(true); + opt.headers['Content-Length'] = opt.body.length; + } + + if(opt.protocol === 'https:'){ + //https不走代理 + opt.proxyIp = null; + opt.proxyPort= null; + } + + //过滤特殊字符 + if(httpUtil.checkInvalidHeaderChar(opt.path)){ + opt.path = encodeURI(opt.path); + } + + logger.debug(logPre + '${type} ${dataType} ~ ${ip}:${port} ${protocol}//${host}${path}',{ + protocol : opt.protocol, + type : opt.type, + dataType : opt.dataType, + ip : opt.proxyIp || opt.ip || opt.host, + port : opt.proxyPort || opt.port, + host : opt.host, + path : opt.path + }); + + if(opt.proxyPort){ + opt.proxyPath = 'http://' + opt.host + opt.path; + } + + + if(opt.agent){ + currAgent = opt.agent; + }else if(opt.keepAlive === 'https'){ + if(opt.protocol === 'https:'){ + currAgent = optionsUtil.getHttpsAgent(opt.headers.host); + }else{ + currAgent = false; + } + }else if(opt.keepAlive){ + if(opt.protocol === 'https:'){ + currAgent = optionsUtil.getHttpsAgent(opt.headers.host); + }else{ + currAgent = optionsUtil.getHttpAgent(opt.headers.host); + } + }else{ + currAgent = false; + } + + request = (opt.protocol === 'https:' ? https : http).request({ + agent : currAgent, + host : opt.proxyIp || opt.ip || opt.host, + port : opt.proxyPort || opt.port, + path : opt.proxyPath || opt.path, + method : opt.type, + headers : opt.headers + }); + + request.setNoDelay(true); + request.setSocketKeepAlive(true); - defer.always(function(){ - clearTimeout(tid); - request.removeAllListeners(); + defer.always(function(){ + clearTimeout(tid); + request.removeAllListeners(); - //request.abort(); 长连接不能开 - //request.destroy(); 长连接不能开 - request = null; - tid = null; - }); + //request.abort(); 长连接不能开 + //request.destroy(); 长连接不能开 + request = null; + tid = null; + }); - tid = setTimeout(function(){ - logger.debug(logPre + 'timeout: ${timeout}', { - timeout : opt.timeout - }); - request.abort(); - request.emit('fail'); - },opt.timeout); + tid = setTimeout(function(){ + logger.debug(logPre + 'timeout: ${timeout}', { + timeout : opt.timeout + }); + request.abort(); + request.emit('fail'); + },opt.timeout); - request.once('error',function(err){ - request.emit('fail',err); - }); + request.once('error',function(err){ + request.emit('fail',err); + }); - request.once('fail',function(err){ + request.once('fail',function(err){ - if(defer.isRejected() || defer.isResolved()){ - return; - } + if(defer.isRejected() || defer.isResolved()){ + return; + } - times.end = new Date().getTime(); - - if(err){ - logger.error(logPre + '[${userIp}] ${type} error ~ ${ip}:${port} ${protocol}//${host}${path} ' + err.stack,{ - protocol : opt.protocol, - type : opt.type, - dataType : opt.dataType, - ip : opt.proxyIp || opt.ip, - port : opt.proxyPort || opt.port, - host : opt.host, - path : opt.path, - userIp : httpUtil.getUserIp() - }); - report(opt,1,502); - defer.reject({ - opt: opt, - hasError: true, - code: 502, - e:err, - msg: err.message, - times: times - }); - - return; - } + times.end = new Date().getTime(); + + if(err){ + logger.error(logPre + '[${userIp}] ${type} error ~ ${ip}:${port} ${protocol}//${host}${path} ' + err.stack,{ + protocol : opt.protocol, + type : opt.type, + dataType : opt.dataType, + ip : opt.proxyIp || opt.ip, + port : opt.proxyPort || opt.port, + host : opt.host, + path : opt.path, + userIp : httpUtil.getUserIp() + }); + report(opt,1,502); + defer.reject({ + opt: opt, + hasError: true, + code: 502, + e:err, + msg: err.message, + times: times + }); + + return; + } - if(window.response && window.response.__hasClosed){ - logger.error(logPre + '[${userIp}] ${type} error ~ ${ip}:${port} ${protocol}//${host}${path} socket closed',{ - protocol : opt.protocol, - type : opt.type, - dataType : opt.dataType, - ip : opt.proxyIp || opt.ip, - port : opt.proxyPort || opt.port, - host : opt.host, - path : opt.path, - userIp : httpUtil.getUserIp() - }); - report(opt,2,600 + opt.retry); - defer.reject({ - opt: opt, - hasError: true, - code: 600, - e:err, - msg: 'request error', - times: times - }); - return; - } + if(window.response && window.response.__hasClosed){ + logger.error(logPre + '[${userIp}] ${type} error ~ ${ip}:${port} ${protocol}//${host}${path} socket closed',{ + protocol : opt.protocol, + type : opt.type, + dataType : opt.dataType, + ip : opt.proxyIp || opt.ip, + port : opt.proxyPort || opt.port, + host : opt.host, + path : opt.path, + userIp : httpUtil.getUserIp() + }); + report(opt,2,600 + opt.retry); + defer.reject({ + opt: opt, + hasError: true, + code: 600, + e:err, + msg: 'request error', + times: times + }); + return; + } - report(opt,1,513 + opt.retry); + report(opt,1,513 + opt.retry); - logger.error(logPre + '[${userIp}] ${type} error ~ ${ip}:${port} ${protocol}//${host}${path}',{ - protocol : opt.protocol, - type : opt.type, - dataType : opt.dataType, - ip : opt.proxyIp || opt.ip, - port : opt.proxyPort || opt.port, - host : opt.host, - path : opt.path, - userIp : httpUtil.getUserIp() - }); + logger.error(logPre + '[${userIp}] ${type} error ~ ${ip}:${port} ${protocol}//${host}${path}',{ + protocol : opt.protocol, + type : opt.type, + dataType : opt.dataType, + ip : opt.proxyIp || opt.ip, + port : opt.proxyPort || opt.port, + host : opt.host, + path : opt.path, + userIp : httpUtil.getUserIp() + }); - //限制次数,1s只放过一个 - if(opt.retry > 0 && times.end - lastRetry > 1000){ - lastRetry = times.end; + //限制次数,1s只放过一个 + if(opt.retry > 0 && times.end - lastRetry > 1000){ + lastRetry = times.end; - opt.retry = opt.retry - 1; + opt.retry = opt.retry - 1; - logger.debug('retry: ' + opt.retry); - opt.isRetriedRequest = true; + logger.debug('retry: ' + opt.retry); + opt.isRetriedRequest = true; - that.request(opt).done(function(d){ - d.hasRetry = true; + that.request(opt).done(function(d){ + d.hasRetry = true; - defer.resolve(d); - }).fail(function(d){ - d.hasRetry = true; + defer.resolve(d); + }).fail(function(d){ + d.hasRetry = true; - defer.reject(d); - }); + defer.reject(d); + }); - return; - }else{ - report(opt,1,513 + opt.retry); - } - - defer.reject({ - opt: opt, - hasError: true, - code: 513, - e:err, - msg: 'request error', - times: times - }); + return; + }else{ + report(opt,1,513 + opt.retry); + } + + defer.reject({ + opt: opt, + hasError: true, + code: 513, + e:err, + msg: 'request error', + times: times + }); - }); + }); - request.once('response',function(response){ - var result = []; - var pipe = response; - var isProxy = false; - var key; + request.once('response',function(response){ + var result = []; + var pipe = response; + var isProxy = false; - if(opt.dataType === 'proxy' && that._proxyResponse){ - isProxy = true; - } + if(opt.dataType === 'proxy' && that._proxyResponse){ + isProxy = true; + } - if(currRetry != opt.retry){ - //防止第一个请求又回包捣乱 - logger.debug('currRetry: ${currRetry}, opt.retry: ${retry}',{ - currRetry: currRetry, - retry: opt.retry - }); - return; - } + if(currRetry != opt.retry){ + //防止第一个请求又回包捣乱 + logger.debug('currRetry: ${currRetry}, opt.retry: ${retry}',{ + currRetry: currRetry, + retry: opt.retry + }); + return; + } - //不能再重试了 - opt.retry = 0; + //不能再重试了 + opt.retry = 0; - //不能省掉哦 - process.domain && process.domain.add(response); + //不能省掉哦 + process.domain && process.domain.add(response); - opt.statusCode = response.statusCode; - opt.remoteAddress = request.socket && request.socket.remoteAddress; - opt.remotePort = request.socket && request.socket.remotePort; + opt.statusCode = response.statusCode; + opt.remoteAddress = request.socket && request.socket.remoteAddress; + opt.remotePort = request.socket && request.socket.remotePort; - response._bodySize = 0; + response._bodySize = 0; - times.response = new Date().getTime(); + times.response = new Date().getTime(); - if(opt.dataType === 'proxy'){ - if(response.statusCode >= 500 && response.statusCode <= 599 && response.statusCode !== 501){ - logger.debug(logPre + '${ip}:${port} response ${statusCode} cost:${cost}ms ${encoding}\nrequest: ${headers}\nresponse: ${resHeaders}',{ - ip: opt.remoteAddress, - port: opt.remotePort, - statusCode: response.statusCode, - headers: JSON.stringify(opt.headers,null,2), - resHeaders: JSON.stringify(response.headers,null,2), - encoding: response.headers['content-encoding'], - cost: +new Date() - times.start - }); - }else{ - logger.debug(logPre + '${ip}:${port} response ${statusCode} cost:${cost}ms ${encoding}\nresponse ${statusCode} ${resHeaders} ',{ - ip: opt.remoteAddress, - port: opt.remotePort, - statusCode: response.statusCode, - resHeaders: JSON.stringify(response.headers,null,2), - encoding: response.headers['content-encoding'], - cost: +new Date() - times.start - }); - } - }else{ - if( - opt.statusCode === 200 + if(opt.dataType === 'proxy'){ + if(response.statusCode >= 500 && response.statusCode <= 599 && response.statusCode !== 501){ + logger.debug(logPre + '${ip}:${port} response ${statusCode} cost:${cost}ms ${encoding}\nrequest: ${headers}\nresponse: ${resHeaders}',{ + ip: opt.remoteAddress, + port: opt.remotePort, + statusCode: response.statusCode, + headers: JSON.stringify(opt.headers,null,2), + resHeaders: JSON.stringify(response.headers,null,2), + encoding: response.headers['content-encoding'], + cost: +new Date() - times.start + }); + }else{ + logger.debug(logPre + '${ip}:${port} response ${statusCode} cost:${cost}ms ${encoding}\nresponse ${statusCode} ${resHeaders} ',{ + ip: opt.remoteAddress, + port: opt.remotePort, + statusCode: response.statusCode, + resHeaders: JSON.stringify(response.headers,null,2), + encoding: response.headers['content-encoding'], + cost: +new Date() - times.start + }); + } + }else{ + if( + opt.statusCode === 200 || opt.statusCode === 206 || opt.statusCode === 666 || opt.dataType === response.statusCode - ){ - logger.debug(logPre + '${ip}:${port} response ${statusCode} cost:${cost}ms ${encoding}',{ - ip: opt.remoteAddress, - port: opt.remotePort, - statusCode: response.statusCode, - encoding: response.headers['content-encoding'], - cost: +new Date() - times.start - }); - }else{ - logger.debug(logPre + '${ip}:${port} response ${statusCode} cost:${cost}ms ${encoding}\nrequest: ${headers}\nresponse: ${resHeaders}',{ - ip: opt.remoteAddress, - port: opt.remotePort, - statusCode: response.statusCode, - headers: JSON.stringify(opt.headers,null,2), - resHeaders: JSON.stringify(response.headers,null,2), - encoding: response.headers['content-encoding'], - cost: +new Date() - times.start - }); - } - } + ){ + logger.debug(logPre + '${ip}:${port} response ${statusCode} cost:${cost}ms ${encoding}',{ + ip: opt.remoteAddress, + port: opt.remotePort, + statusCode: response.statusCode, + encoding: response.headers['content-encoding'], + cost: +new Date() - times.start + }); + }else{ + logger.debug(logPre + '${ip}:${port} response ${statusCode} cost:${cost}ms ${encoding}\nrequest: ${headers}\nresponse: ${resHeaders}',{ + ip: opt.remoteAddress, + port: opt.remotePort, + statusCode: response.statusCode, + headers: JSON.stringify(opt.headers,null,2), + resHeaders: JSON.stringify(response.headers,null,2), + encoding: response.headers['content-encoding'], + cost: +new Date() - times.start + }); + } + } - if(defer.isRejected() || defer.isResolved()){ - logger.debug(logPre + 'isRejected: ${isRejected}, isResolved: ${isResolved}', { - isRejected: defer.isRejected(), - isResolved: defer.isResolved() - }); - return; - } + if(defer.isRejected() || defer.isResolved()){ + logger.debug(logPre + 'isRejected: ${isRejected}, isResolved: ${isResolved}', { + isRejected: defer.isRejected(), + isResolved: defer.isResolved() + }); + return; + } - if(typeof opt.response === 'function'){ - if(opt.response(response) === false){ - //中断处理流程 - return; - }; - } - - if(isProxy){ - if(httpUtil.isSent(that._proxyResponse)){ - logger.debug('proxy end'); - return; - } - } + if(typeof opt.response === 'function'){ + if(opt.response(response) === false){ + //中断处理流程 + return; + } + } + + if(isProxy){ + if(httpUtil.isSent(that._proxyResponse)){ + logger.debug('proxy end'); + return; + } + } - if(opt.dataType === 'buffer' || (isProxy && response.headers['content-encoding']) || response.headers['content-length'] == 0){ - logger.debug(logPre + 'response type: buffer'); - }else{ - if(response.headers['content-encoding'] === 'gzip'){ + if(opt.dataType === 'buffer' || (isProxy && response.headers['content-encoding']) || response.headers['content-length'] == 0){ + logger.debug(logPre + 'response type: buffer'); + }else{ + if(response.headers['content-encoding'] === 'gzip'){ - pipe = zlib.createGunzip(); - response.on('data',function(buffer){ - pipe.write(buffer); - }); - response.once('end',function(){ - pipe.end(); - }); - }else if(response.headers['content-encoding'] === 'deflate'){ + pipe = zlib.createGunzip(); + response.on('data',function(buffer){ + pipe.write(buffer); + }); + response.once('end',function(){ + pipe.end(); + }); + }else if(response.headers['content-encoding'] === 'deflate'){ - pipe = zlib.createInflateRaw(); + pipe = zlib.createInflateRaw(); - response.on('data',function(buffer){ - pipe.write(buffer); - }); - response.once('end',function(){ - pipe.end(); - }); - } - } + response.on('data',function(buffer){ + pipe.write(buffer); + }); + response.once('end',function(){ + pipe.end(); + }); + } + } - if(isProxy){ - - if(response.headers['transfer-encoding'] !== 'chunked'){ - that._proxyResponse.useChunkedEncodingByDefault = false; - } - //如果是测试环境,增加一个proxy头以便识别ip - if(opt.ip && config.isTest){ - that._proxyResponse.setHeader("Proxy-Domain-Ip", opt.ip); - } - if(config.isTest && response.headers['cache-control']) { - response.headers['cache-control'] = "max-age=0, must-revalidate"; - } - - if( - !response.headers['content-encoding'] && + if(isProxy){ + + if(response.headers['transfer-encoding'] !== 'chunked'){ + that._proxyResponse.useChunkedEncodingByDefault = false; + } + //如果是测试环境,增加一个proxy头以便识别ip + if(opt.ip && config.isTest){ + that._proxyResponse.setHeader('Proxy-Domain-Ip', opt.ip); + } + if(config.isTest && response.headers['cache-control']) { + response.headers['cache-control'] = 'max-age=0, must-revalidate'; + } + + if( + !response.headers['content-encoding'] && response.headers['content-type'] && (response.headers['content-type'].indexOf('text/') === 0 || response.headers['content-type'] === 'application/x-javascript' || response.headers['content-type'] === 'x-json') - ){ - - //自带压缩功能 - delete response.headers['transfer-encoding']; - delete response.headers['content-length']; - delete response.headers['connection']; - - //解决循环依赖 - that._proxyResponse = require('util/gzipHttp.js').create({ - request : that._proxyRequest, - response : that._proxyResponse, - code : response.statusCode, - headers : httpUtil.formatHeader(response.headers) - }); - }else{ - delete response.headers['connection']; + ){ + + //自带压缩功能 + delete response.headers['transfer-encoding']; + delete response.headers['content-length']; + delete response.headers['connection']; + + //解决循环依赖 + that._proxyResponse = require('util/gzipHttp.js').create({ + request : that._proxyRequest, + response : that._proxyResponse, + code : response.statusCode, + headers : httpUtil.formatHeader(response.headers) + }); + }else{ + delete response.headers['connection']; - that._proxyResponse.writeHead(response.statusCode,httpUtil.formatHeader(response.headers)); - } - } - - pipe.timeStart = Date.now(); - pipe.timeCurr = pipe.timeStart; - - pipe.on('data',function(chunk){ - var cost = Date.now() - pipe.timeCurr; - - pipe.timeCurr = Date.now(); - - //logger.debug('${logPre}receive data: ${size},\tcost: ${cost}ms',{ - // logPre: logPre, - // cost: cost, - // size: chunk.length - //}); - - response._bodySize += chunk.length; - - if(opt.maxBodySize > 0 && response._bodySize > opt.maxBodySize){ - logger.debug(logPre + 'request abort(body size too large) size:${len},max:${max}', { - len: response._bodySize, - max:opt.maxBodySize - }); - request.abort(); - request.emit('fail'); - return; - } + that._proxyResponse.writeHead(response.statusCode,httpUtil.formatHeader(response.headers)); + } + } + + pipe.timeStart = Date.now(); + pipe.timeCurr = pipe.timeStart; + + pipe.on('data',function(chunk){ + // var cost = Date.now() - pipe.timeCurr; + + pipe.timeCurr = Date.now(); + + //logger.debug('${logPre}receive data: ${size},\tcost: ${cost}ms',{ + // logPre: logPre, + // cost: cost, + // size: chunk.length + //}); + + response._bodySize += chunk.length; + + if(opt.maxBodySize > 0 && response._bodySize > opt.maxBodySize){ + logger.debug(logPre + 'request abort(body size too large) size:${len},max:${max}', { + len: response._bodySize, + max:opt.maxBodySize + }); + request.abort(); + request.emit('fail'); + return; + } - if(isProxy){ - if(!that._proxyResponse.finished){ - that._proxyResponse.write(chunk); - } - - }else{ - result.push(chunk); - } - }); + if(isProxy){ + if(!that._proxyResponse.finished){ + that._proxyResponse.write(chunk); + } + + }else{ + result.push(chunk); + } + }); - pipe.once('close',function(){ - logger.debug(logPre + 'close'); - this.emit('done'); - }); + pipe.once('close',function(){ + logger.debug(logPre + 'close'); + this.emit('done'); + }); - pipe.once('end',function(){ - var cost = Date.now() - pipe.timeStart; + pipe.once('end',function(){ + var cost = Date.now() - pipe.timeStart; - logger.debug('${logPre}end:${size},\treceive data cost: ${cost}ms',{ - logPre: logPre, - cost: cost, - size: response._bodySize - }); + logger.debug('${logPre}end:${size},\treceive data cost: ${cost}ms',{ + logPre: logPre, + cost: cost, + size: response._bodySize + }); - this.emit('done'); - }); + this.emit('done'); + }); - pipe.once('done',function(){ + pipe.once('done',function(){ - var obj,responseText,buffer,code; - var key,Content; + var obj,responseText,buffer,code; + var key,Content; - this.removeAllListeners('close'); - this.removeAllListeners('end'); - this.removeAllListeners('data'); - this.removeAllListeners('done'); + this.removeAllListeners('close'); + this.removeAllListeners('end'); + this.removeAllListeners('data'); + this.removeAllListeners('done'); - if(defer.isRejected() || defer.isResolved()){ - return; - } + if(defer.isRejected() || defer.isResolved()){ + return; + } - times.end = new Date().getTime(); - buffer = Buffer.concat(result); - result = []; + times.end = new Date().getTime(); + buffer = Buffer.concat(result); + result = []; - logger.debug(logPre + 'done size:${len}', { - len: response._bodySize - }); + logger.debug(logPre + 'done size:${len}', { + len: response._bodySize + }); - if(isProxy){ - if (response.statusCode >= 500 && response.statusCode <= 599 && response.statusCode !== 501) { - report(opt, 1, response.statusCode); - }else{ - report(opt,0,response.statusCode); - } + if(isProxy){ + if (response.statusCode >= 500 && response.statusCode <= 599 && response.statusCode !== 501) { + report(opt, 1, response.statusCode); + }else{ + report(opt,0,response.statusCode); + } - that._proxyResponse.end(); + that._proxyResponse.end(); - defer.resolve({ - opt: opt, - buffer: buffer, - result: null, - responseText: responseText, - hasError: false, - msg: 'success', - response: response, - times: times - }); + defer.resolve({ + opt: opt, + buffer: buffer, + result: null, + responseText: responseText, + hasError: false, + msg: 'success', + response: response, + times: times + }); - return; - } + return; + } - if(opt.dataType === response.statusCode){ - report(opt,0,response.statusCode); - defer.resolve({ - opt: opt, - buffer: buffer, - result: null, - responseText: responseText, - hasError: false, - msg: 'success', - response: response, - times: times - }); - - return; - } + if(opt.dataType === response.statusCode){ + report(opt,0,response.statusCode); + defer.resolve({ + opt: opt, + buffer: buffer, + result: null, + responseText: responseText, + hasError: false, + msg: 'success', + response: response, + times: times + }); + + return; + } - if(opt.dataType === 'json' || opt.dataType === 'jsonp' || opt.dataType === 'text' || opt.dataType === 'html'){ - responseText = buffer.toString('UTF-8'); - } + if(opt.dataType === 'json' || opt.dataType === 'jsonp' || opt.dataType === 'text' || opt.dataType === 'html'){ + responseText = buffer.toString('UTF-8'); + } - if(buffer.length <= 1024){ - if(responseText){ - if(opt.dataType === 'json' || opt.dataType === 'jsonp' || opt.dataType === 'text'){ - logger.debug(logPre + 'responseText:\n' + responseText); - } - }else if(/charset=utf-8/i.test(response.headers['Content-Type'])){ - logger.debug(logPre + 'responseText:\n' + buffer.toString('UTF-8')); - } - } + if(buffer.length <= 1024){ + if(responseText){ + if(opt.dataType === 'json' || opt.dataType === 'jsonp' || opt.dataType === 'text'){ + logger.debug(logPre + 'responseText:\n' + responseText); + } + }else if(/charset=utf-8/i.test(response.headers['Content-Type'])){ + logger.debug(logPre + 'responseText:\n' + buffer.toString('UTF-8')); + } + } - if(responseText){ - buffer = null; - } + if(responseText){ + buffer = null; + } - if(response.statusCode !== 200 && response.statusCode !== 666 && response.statusCode !== 206){ - //dataType为proxy但是不走代理模式的时候,30x类型的返回码当作成功上报 - if(response.statusCode >= 300 && response.statusCode < 400){ - if(opt.dataType === 'proxy'){ - report(opt,0,response.statusCode); - }else{ - report(opt,2,response.statusCode); - } - }else{ - report(opt,1,response.statusCode); - } + if(response.statusCode !== 200 && response.statusCode !== 666 && response.statusCode !== 206){ + //dataType为proxy但是不走代理模式的时候,30x类型的返回码当作成功上报 + if(response.statusCode >= 300 && response.statusCode < 400){ + if(opt.dataType === 'proxy'){ + report(opt,0,response.statusCode); + }else{ + report(opt,2,response.statusCode); + } + }else{ + report(opt,1,response.statusCode); + } - defer.reject({ - opt: opt, - buffer: buffer, - result: null, - responseText: responseText, - hasError: false, - msg: 'request statusCode : ' + response.statusCode, - response: response, - times: times - }); - - return; - } - - if(opt.dataType === 'json' || opt.dataType === 'jsonp'){ + defer.reject({ + opt: opt, + buffer: buffer, + result: null, + responseText: responseText, + hasError: false, + msg: 'request statusCode : ' + response.statusCode, + response: response, + times: times + }); + + return; + } + + if(opt.dataType === 'json' || opt.dataType === 'jsonp'){ - try{ - - if(opt.jsonpCallback){ - //json|jsonp - code = `var result=null; var ${opt.jsonpCallback}=function($1){result=$1}; ${responseText}; return result;`; - obj = new sbFunction(code)(); - }else if(opt.dataType === 'json' && opt.useJsonParseOnly){ - //json only - obj = JSON.parse(responseText); - }else{ - //other - code = `return (${responseText})`; - try{ - obj = new sbFunction(code)(); - }catch(e){ - //尝试JSON.parse - obj = JSON.parse(responseText); - } - } - - }catch(e){ + try{ + + if(opt.jsonpCallback){ + //json|jsonp + code = `var result=null; var ${opt.jsonpCallback}=function($1){result=$1}; ${responseText}; return result;`; + obj = new sbFunction(code)(); + }else if(opt.dataType === 'json' && opt.useJsonParseOnly){ + //json only + obj = JSON.parse(responseText); + }else{ + //other + code = `return (${responseText})`; + try{ + obj = new sbFunction(code)(); + }catch(e){ + //尝试JSON.parse + obj = JSON.parse(responseText); + } + } + + }catch(e){ + + let parseErr = e; - if(e && code){ - try{ - code = code.replace(/[\u2028\u2029]/g,''); - obj = new sbFunction(code)(); - e = null; - }catch(e){ - } - } - - if(e){ - logger.error(logPre + 'parse error: ${error} \n\nrequest: ${headers}\nresponse: ${resHeaders}\n\n${responseTextU8}',{ - error: e.stack, - headers: JSON.stringify(opt.headers,null,2), - resHeaders: JSON.stringify(response.headers,null,2), - responseTextU8: JSON.stringify(responseText,null,2), - }); - report(opt,1,508); - defer.reject({ - opt: opt, - buffer: buffer, - result: null, - responseText: responseText, - hasError: false, - msg: 'parse error', - code: 508, - response: response, - times: times - }); + if(e && code){ + try{ + code = code.replace(/[\u2028\u2029]/g,''); + obj = new sbFunction(code)(); + parseErr = null; + }catch(err){ + logger.error(`parse response body fail ${err.message}`); + } + } + + if(parseErr){ + logger.error(logPre + 'parse error: ${error} \n\nrequest: ${headers}\nresponse: ${resHeaders}\n\n${responseTextU8}',{ + error: parseErr.stack, + headers: JSON.stringify(opt.headers,null,2), + resHeaders: JSON.stringify(response.headers,null,2), + responseTextU8: JSON.stringify(responseText,null,2), + }); + report(opt,1,508); + defer.reject({ + opt: opt, + buffer: buffer, + result: null, + responseText: responseText, + hasError: false, + msg: 'parse error', + code: 508, + response: response, + times: times + }); - key = [window.request.headers.host,context.mod_act,e.message].join(':'); + key = [window.request.headers.host,context.mod_act,parseErr.message].join(':'); - Content = [ - '

错误堆栈

', - '

',
-								e.stack,
-							'

', - ].join(''); + Content = [ + '

错误堆栈

', + '

',
+                            parseErr.stack,
+                            '

', + ].join(''); - require('util/mail/mail.js').SendMail(key,'js data',1800,{ - 'Title' : key, - 'runtimeType' : 'ParseError', - 'Content' : Content, - 'MsgInfo' : '错误堆栈:\n' + e.stack - }); + require('util/mail/mail.js').SendMail(key,'js data',1800,{ + 'Title' : key, + 'runtimeType' : 'ParseError', + 'Content' : Content, + 'MsgInfo' : '错误堆栈:\n' + parseErr.stack + }); - return; - } + return; + } - } + } - if(obj){ - code = obj.code || 0; - } + if(obj){ + code = obj.code || 0; + } - }else{ - code = { - isFail: 0, - code: response.statusCode - }; - - obj = responseText; - } + }else{ + code = { + isFail: 0, + code: response.statusCode + }; + + obj = responseText; + } - if(typeof opt.formatCode === 'function'){ - code = opt.formatCode(obj,opt,response); - } + if(typeof opt.formatCode === 'function'){ + code = opt.formatCode(obj,opt,response); + } - //支持{isFail:0,code:1,message:''} - if(typeof code === 'object'){ + //支持{isFail:0,code:1,message:''} + if(typeof code === 'object'){ - if(typeof code.isFail !== 'number'){ - code.isFail = ~~code.isFail; - } + if(typeof code.isFail !== 'number'){ + code.isFail = ~~code.isFail; + } - if(typeof code.code !== 'number'){ - code.code = ~~code.code; - } + if(typeof code.code !== 'number'){ + code.code = ~~code.code; + } - report(opt,code.isFail,code.code); - }else{ + report(opt,code.isFail,code.code); + }else{ - if(typeof code !== 'number'){ - code = ~~code; - } + if(typeof code !== 'number'){ + code = ~~code; + } - if(code === 0){ - report(opt,0,code); - }else{ - report(opt,2,code); - } - } + if(code === 0){ + report(opt,0,code); + }else{ + report(opt,2,code); + } + } - defer.resolve({ - opt: opt, - buffer: buffer, - result: obj, - responseText: responseText, - hasError: false, - msg: 'success!', - response: response, - times: times - }); - }); - - }); + defer.resolve({ + opt: opt, + buffer: buffer, + result: obj, + responseText: responseText, + hasError: false, + msg: 'success!', + response: response, + times: times + }); + }); + + }); - if(opt.send){ - opt.send(request); - }else{ + if(opt.send){ + opt.send(request); + }else{ - if(opt.body){ + if(opt.body){ - request.useChunkedEncodingByDefault = false; - try{ - request.write(opt.body); - }catch(e){ - logger.info(e.stack); - } - } + request.useChunkedEncodingByDefault = false; + try{ + request.write(opt.body); + }catch(e){ + logger.info(e.stack); + } + } - request.end(); - } + request.end(); + } - return defer; -} + return defer; +}; diff --git a/bin/tsw/ajax/form.js b/bin/tsw/ajax/form.js index e5615eeb..78c07cf7 100644 --- a/bin/tsw/ajax/form.js +++ b/bin/tsw/ajax/form.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; /** * ajax发请求时组装form-data @@ -20,14 +20,14 @@ * @return {[type]} [description] */ function textField(boundary, key, value) { - return Buffer.from([ - '--' + boundary, - 'Content-Type: text/plain; charset=utf-8', - 'Content-Disposition: form-data; name="' + key + '"', - '', - value, - '' - ].join('\r\n')); + return Buffer.from([ + '--' + boundary, + 'Content-Type: text/plain; charset=utf-8', + 'Content-Disposition: form-data; name="' + key + '"', + '', + value, + '' + ].join('\r\n')); } @@ -39,29 +39,29 @@ function textField(boundary, key, value) { * @return {[type]} [description] */ function fileField(boundary, key, value = {}) { - let tmp = []; + let tmp = []; - let contentType = value.contentType || 'application/octet-stream'; - let dispositionType = value.dispositionType || 'form-data'; - let fileName = value.fileName || ''; + let contentType = value.contentType || 'application/octet-stream'; + let dispositionType = value.dispositionType || 'form-data'; + let fileName = value.fileName || ''; - tmp.push('--' + boundary); + tmp.push('--' + boundary); - tmp.push('Content-Type: ' + contentType); + tmp.push('Content-Type: ' + contentType); - tmp.push('Content-Disposition: ' + dispositionType + '; name="' + key + '"; filename="' + fileName + '"'); + tmp.push('Content-Disposition: ' + dispositionType + '; name="' + key + '"; filename="' + fileName + '"'); - tmp.push('\r\n'); + tmp.push('\r\n'); - let buffer = Buffer.from(tmp.join('\r\n')); + let buffer = Buffer.from(tmp.join('\r\n')); - if(Buffer.isBuffer(value.content)){ - buffer = Buffer.concat([buffer, value.content, Buffer.from('\r\n')]); - }else{ - buffer = Buffer.concat([buffer, Buffer.from(value.content || ''), Buffer.from('\r\n')]); - } + if(Buffer.isBuffer(value.content)){ + buffer = Buffer.concat([buffer, value.content, Buffer.from('\r\n')]); + }else{ + buffer = Buffer.concat([buffer, Buffer.from(value.content || ''), Buffer.from('\r\n')]); + } - return buffer; + return buffer; } @@ -72,29 +72,29 @@ function fileField(boundary, key, value = {}) { */ function getFormBuffer(opt = {}) { - let buffer = Buffer.alloc(0); + let buffer = Buffer.alloc(0); - let v; + let v; - for(let key in opt.data){ + for(let key in opt.data){ - v = opt.data[key]; + v = opt.data[key]; - if(v !== undefined && v !== null){ + if(v !== undefined && v !== null){ - if(v.fileType){ - buffer = Buffer.concat([buffer, fileField(opt.boundary, key, v)]); - }else{ - buffer = Buffer.concat([buffer, textField(opt.boundary, key, v)]); - } - } - } + if(v.fileType){ + buffer = Buffer.concat([buffer, fileField(opt.boundary, key, v)]); + }else{ + buffer = Buffer.concat([buffer, textField(opt.boundary, key, v)]); + } + } + } - buffer = Buffer.concat([buffer, Buffer.from('--' + opt.boundary + '--')]); + buffer = Buffer.concat([buffer, Buffer.from('--' + opt.boundary + '--')]); - return buffer; + return buffer; } module.exports = { - getFormBuffer + getFormBuffer }; \ No newline at end of file diff --git a/bin/tsw/ajax/http-https.options.js b/bin/tsw/ajax/http-https.options.js index c7ec0d2a..f1180c3e 100644 --- a/bin/tsw/ajax/http-https.options.js +++ b/bin/tsw/ajax/http-https.options.js @@ -5,9 +5,8 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; -const fs = require('fs'); const https = require('https'); const http = require('http'); const cache = {}; @@ -26,11 +25,11 @@ this.getHttpsAgent = function(host){ maxCachedSessions : 65535, keepAlive : true, keepAliveMsecs : 5000 - }) - }; + }); + } return cache[key]; -} +}; this.getHttpAgent = function(host){ @@ -42,8 +41,8 @@ this.getHttpAgent = function(host){ maxFreeSockets : 32, keepAlive : true, keepAliveMsecs : 5000 - }) - }; + }); + } return cache[key]; -} \ No newline at end of file +}; \ No newline at end of file diff --git a/bin/tsw/ajax/index.js b/bin/tsw/ajax/index.js index 72d36de9..71874808 100644 --- a/bin/tsw/ajax/index.js +++ b/bin/tsw/ajax/index.js @@ -5,6 +5,6 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; module.exports = require('./ajax.js'); \ No newline at end of file diff --git a/bin/tsw/ajax/token.js b/bin/tsw/ajax/token.js index acea2e9b..c5397dcf 100644 --- a/bin/tsw/ajax/token.js +++ b/bin/tsw/ajax/token.js @@ -5,30 +5,30 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; this.token = function(skey){ - var str = skey || ''; - var hash = 5381; + var str = skey || ''; + var hash = 5381; - if(typeof context !== 'undefined'){ - let window = context.window || {}; - if(window.request){ - str = str + if(typeof context !== 'undefined'){ + let window = context.window || {}; + if(window.request){ + str = str || window.request.cookies.p_skey || window.request.cookies.skey || window.request.cookies.rv2 || window.request.cookies.access_token || ''; - } - } + } + } - for(var i = 0, len = str.length; i < len; ++i){ - hash += (hash << 5) + str.charAt(i).charCodeAt(); - } - return hash & 0x7fffffff; -} + for(var i = 0, len = str.length; i < len; ++i){ + hash += (hash << 5) + str.charAt(i).charCodeAt(); + } + return hash & 0x7fffffff; +}; diff --git a/bin/tsw/api/date.js b/bin/tsw/api/date.js index b1cd5735..425dafa3 100644 --- a/bin/tsw/api/date.js +++ b/bin/tsw/api/date.js @@ -5,51 +5,51 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; var Date = { - /** + /** * 格式化时间 * @method formatData * @param {Date} mDate 时间对象 * @param {String} fmt 格式化形式,如 MM月dd日 HH:mm */ - format: function(mDate, fmt){ - var o = { - 'M+': mDate.getMonth() + 1, //月份 - 'D+': mDate.getDate(), //日 - 'h+': mDate.getHours() % 12 == 0 ? 12 : mDate.getHours() % 12, //小时 - 'H+': mDate.getHours(), //小时 - 'm+': mDate.getMinutes(), //分 - 's+': mDate.getSeconds(), //秒 - 'q+': Math.floor((mDate.getMonth() + 3) / 3), //季度 - 'S': mDate.getMilliseconds() //毫秒 - }, week = { - '0': '\u65e5', - '1': '\u4e00', - '2': '\u4e8c', - '3': '\u4e09', - '4': '\u56db', - '5': '\u4e94', - '6': '\u516d' - }; + format: function(mDate, fmt){ + var o = { + 'M+': mDate.getMonth() + 1, //月份 + 'D+': mDate.getDate(), //日 + 'h+': mDate.getHours() % 12 == 0 ? 12 : mDate.getHours() % 12, //小时 + 'H+': mDate.getHours(), //小时 + 'm+': mDate.getMinutes(), //分 + 's+': mDate.getSeconds(), //秒 + 'q+': Math.floor((mDate.getMonth() + 3) / 3), //季度 + 'S': mDate.getMilliseconds() //毫秒 + }, week = { + '0': '\u65e5', + '1': '\u4e00', + '2': '\u4e8c', + '3': '\u4e09', + '4': '\u56db', + '5': '\u4e94', + '6': '\u516d' + }; - if (/(Y+)/.test(fmt)) { - fmt = fmt.replace(RegExp.$1, (mDate.getFullYear() + '').substr(4 - RegExp.$1.length)); - } - if (/(E+)/.test(fmt)) { - fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? '\u661f\u671f' : '\u5468') : '') + week[mDate.getDay() + '']); - } + if (/(Y+)/.test(fmt)) { + fmt = fmt.replace(RegExp.$1, (mDate.getFullYear() + '').substr(4 - RegExp.$1.length)); + } + if (/(E+)/.test(fmt)) { + fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? '\u661f\u671f' : '\u5468') : '') + week[mDate.getDay() + '']); + } - for (var k in o) { - if (new RegExp('(' + k + ')').test(fmt)) { - fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length))); - } - } + for (var k in o) { + if (new RegExp('(' + k + ')').test(fmt)) { + fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length))); + } + } - return fmt; - } + return fmt; + } }; module.exports = Date; \ No newline at end of file diff --git a/bin/tsw/api/fileCache/index.js b/bin/tsw/api/fileCache/index.js index d7df4a64..ad71bb1b 100644 --- a/bin/tsw/api/fileCache/index.js +++ b/bin/tsw/api/fileCache/index.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const Deferred = require('util/Deferred'); const logger = require('logger'); @@ -18,217 +18,216 @@ const existsCache = {}; this.getDir = function(filepath){ - var res,tmp; + var res,tmp; - filepath = filepath || ''; + filepath = filepath || ''; - if(!/^[a-z0-9_\/\-\.\\\:]+$/i.test(filepath)){ - throw new Error('filepath not safe: ' + filepath); - } + if(!/^[a-z0-9_/\-.\\:]+$/i.test(filepath)){ + throw new Error('filepath not safe: ' + filepath); + } - if(filepath.indexOf('http://') > -1){ - filepath = filepath.replace('http://',''); - } + if(filepath.indexOf('http://') > -1){ + filepath = filepath.replace('http://',''); + } - tmp = path.join('/',filepath); - res = path.join(root,tmp); + tmp = path.join('/',filepath); + res = path.join(root,tmp); - res = res.replace(/\\/g,'/'); + res = res.replace(/\\/g,'/'); - return res; -} + return res; +}; this.mkdir = function(dirname){ - if(existsCache[dirname]){ - return; - } - - if(fs.existsSync(dirname)){ - existsCache[dirname] = true; - return; - } - var start = Date.now(); - var arr = dirname.split('/'); - var i = 0; - var curr; - - for(i = 1; i < arr.length; i++){ - curr = arr.slice(0,i + 1).join('/'); - if(!fs.existsSync(curr)){ - logger.debug('mkdir : ${dir}',{ - dir: curr - }); - try{ - fs.mkdirSync(curr,0o777); - }catch(e){ - logger.info(e.stack); - } - - } - } - var end = Date.now(); -} + if(existsCache[dirname]){ + return; + } + + if(fs.existsSync(dirname)){ + existsCache[dirname] = true; + return; + } + + var arr = dirname.split('/'); + var i = 0; + var curr; + + for(i = 1; i < arr.length; i++){ + curr = arr.slice(0,i + 1).join('/'); + if(!fs.existsSync(curr)){ + logger.debug('mkdir : ${dir}',{ + dir: curr + }); + try{ + fs.mkdirSync(curr,0o777); + }catch(e){ + logger.info(e.stack); + } + + } + } +}; this.set = function(filepath,data){ - var start = Date.now(); - var buffer = null; - var filename = this.getDir(filepath); - var dirname = path.dirname(filename); - var basename = path.basename(filename); - var randomname = basename + '.tmp.' + String(Math.random()).slice(2); - - logger.debug('[set] filename : ${filename}',{ - filename: filename - }); - - logger.debug('[set] dirname : ${dirname}',{ - dirname: dirname - }); - - logger.debug('[set] basename : ${basename}',{ - basename: basename - }); - - logger.debug('[set] randomname : ${randomname}',{ - randomname: randomname - }); - - this.mkdir(dirname); - - if(typeof data === 'string'){ - buffer = Buffer.from(data,'UTF-8'); - }else{ - buffer = data; - } - - fs.writeFile([dirname,randomname].join('/'),buffer,{mode:0o666},function(err){ + var start = Date.now(); + var buffer = null; + var filename = this.getDir(filepath); + var dirname = path.dirname(filename); + var basename = path.basename(filename); + var randomname = basename + '.tmp.' + String(Math.random()).slice(2); + + logger.debug('[set] filename : ${filename}',{ + filename: filename + }); + + logger.debug('[set] dirname : ${dirname}',{ + dirname: dirname + }); + + logger.debug('[set] basename : ${basename}',{ + basename: basename + }); + + logger.debug('[set] randomname : ${randomname}',{ + randomname: randomname + }); + + this.mkdir(dirname); + + if(typeof data === 'string'){ + buffer = Buffer.from(data,'UTF-8'); + }else{ + buffer = data; + } + + fs.writeFile([dirname,randomname].join('/'),buffer,{mode:0o666},function(err){ - logger.debug('[write] done: ${randomname}, size: ${size}',{ - randomname: randomname, - size: buffer.length - }); - - if(err){ - logger.info(err.stack); - return; - } + logger.debug('[write] done: ${randomname}, size: ${size}',{ + randomname: randomname, + size: buffer.length + }); + + if(err){ + logger.info(err.stack); + return; + } - fs.rename([dirname,randomname].join('/'),[dirname,basename].join('/'),function(err){ - var end = Date.now(); + fs.rename([dirname,randomname].join('/'),[dirname,basename].join('/'),function(err){ + var end = Date.now(); - if(err){ - logger.debug(err); - } + if(err){ + logger.debug(err); + } - logger.debug('[rename] done: ${basename}, cost: ${cost}ms',{ - basename: basename, - cost: end - start - }); - }); + logger.debug('[rename] done: ${basename}, cost: ${cost}ms',{ + basename: basename, + cost: end - start + }); + }); - }); + }); - tnm2.Attr_API('SUM_TSW_FILECACHE_WRITE', 1); -} + tnm2.Attr_API('SUM_TSW_FILECACHE_WRITE', 1); +}; this.getSync = function(filepath){ - var start = Date.now(); - var buffer = null; - var filename = this.getDir(filepath); - var res = { - stats: null, - data: null - }; + var start = Date.now(); + var buffer = null; + var filename = this.getDir(filepath); + var res = { + stats: null, + data: null + }; - try{ - buffer = fs.readFileSync(filename); - if(buffer.length === 0){ - //长度为0返回空,因为垃圾清理逻辑会清空文件 - buffer = null; - } + try{ + buffer = fs.readFileSync(filename); + if(buffer.length === 0){ + //长度为0返回空,因为垃圾清理逻辑会清空文件 + buffer = null; + } - res.stats = fs.statSync(filename); - res.data = buffer; + res.stats = fs.statSync(filename); + res.data = buffer; - }catch(err){ - buffer = null; - } + }catch(err){ + buffer = null; + } - var end = Date.now(); + var end = Date.now(); - logger.debug('[get] done: ${filename}, size: ${size}, cost: ${cost}ms',{ - filename: filename, - size: buffer && buffer.length, - cost: end - start - }); + logger.debug('[get] done: ${filename}, size: ${size}, cost: ${cost}ms',{ + filename: filename, + size: buffer && buffer.length, + cost: end - start + }); - tnm2.Attr_API('SUM_TSW_FILECACHE_READ', 1); - return res; -} + tnm2.Attr_API('SUM_TSW_FILECACHE_READ', 1); + return res; +}; this.get = this.getAsync = function(filepath){ - var defer = Deferred.create(); - var filename = this.getDir(filepath); + var defer = Deferred.create(); + var filename = this.getDir(filepath); - var res = { - stats: null, - data: null - }; + var res = { + stats: null, + data: null + }; - logger.debug('[getAsync] ${filename}',{ - filename: filename - }); + logger.debug('[getAsync] ${filename}',{ + filename: filename + }); - fs.readFile(filename,function(err, buffer){ + fs.readFile(filename,function(err, buffer){ - if(err){ - logger.debug(err.stack); - defer.resolve(res); - return; - } + if(err){ + logger.debug(err.stack); + defer.resolve(res); + return; + } - res.data = buffer; + res.data = buffer; - fs.stat(filename,function(err,stats){ + fs.stat(filename,function(err,stats){ - if(err){ - logger.debug(err.stack); - defer.resolve(res); - return; - } + if(err){ + logger.debug(err.stack); + defer.resolve(res); + return; + } - logger.debug('[getAsync] mtime: ${mtime}, size: ${size}',stats); + logger.debug('[getAsync] mtime: ${mtime}, size: ${size}',stats); - res.stats = stats; - defer.resolve(res); - }); + res.stats = stats; + defer.resolve(res); + }); - }); + }); - return defer; -} + return defer; +}; this.updateMtime = function(filepath, atime, mtime){ - var filename = this.getDir(filepath); + var filename = this.getDir(filepath); - logger.debug('[updateMtime] ${filename}',{ - filename: filename - }); + logger.debug('[updateMtime] ${filename}',{ + filename: filename + }); - fs.utimes(filename, atime || new Date(), mtime || new Date(), function(err){ - if(err){ - logger.debug(err.stack); - return; - } + fs.utimes(filename, atime || new Date(), mtime || new Date(), function(err){ + if(err){ + logger.debug(err.stack); + return; + } - logger.debug('[updateMtime] ${filename} succ'); - }); -} \ No newline at end of file + logger.debug('[updateMtime] ${filename} succ'); + }); +}; \ No newline at end of file diff --git a/bin/tsw/api/logman/index.js b/bin/tsw/api/logman/index.js index 2304169c..cf2314f0 100644 --- a/bin/tsw/api/logman/index.js +++ b/bin/tsw/api/logman/index.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const cp = require('child_process'); const fs = require('fs'); @@ -19,82 +19,84 @@ const runlogPath = path.resolve(logDir, './run.log.0').replace(/\\/g, '/'); //判断logDir目录是否存在 fs.exists(logDir, function(exists){ - if (!exists) { - fs.mkdirSync(logDir,0o777); - } + if (!exists) { + fs.mkdirSync(logDir,0o777); + } - //判断backup目录是否存在 - fs.exists(backupDir, function(exists){ - if (!exists) { - fs.mkdirSync(backupDir,0o777); - } - }); + //判断backup目录是否存在 + fs.exists(backupDir, function(exists){ + if (!exists) { + fs.mkdirSync(backupDir,0o777); + } + }); }); var LogMan = { - /** + /** * 按分钟\小时\天去备份log */ - delayMap: { - m: 60000, - H: 3600000, - D: 86400000 - }, + delayMap: { + m: 60000, + H: 3600000, + D: 86400000 + }, - /** + /** * 启动log管理 */ - start: function(config){ - logger.info('start log manager'); - var self = this; - this.delayType = config.delay || 'D'; - this.delay = this.delayMap[this.delayType]; - this.timer = setInterval(function(){ - self.backLog(); - }, this.delay); - }, + start: function(config){ + logger.info('start log manager'); + var self = this; + this.delayType = config.delay || 'D'; + this.delay = this.delayMap[this.delayType]; + this.timer = setInterval(function(){ + self.backLog(); + }, this.delay); + }, - /** + /** * 备份log */ - backLog: function(){ - logger.info('start backup log'); - var self = this; - var curBackupDir = path.resolve(backupDir, './' + dateApi.format(new Date, 'YYYY-MM-DD')); - fs.exists(curBackupDir, function(exists){ - if(!exists){ - fs.mkdirSync(curBackupDir); - } - var logFilePath = path.resolve(curBackupDir, './' + dateApi.format(new Date, self.delayType + self.delayType) + '.log'); - var cmdCat = 'cat ' + runlogPath + ' >> ' + logFilePath; - var cmdClear = 'cat /dev/null > ' + runlogPath; + backLog: function(){ + logger.info('start backup log'); + var self = this; + var curBackupDir = path.resolve(backupDir, './' + dateApi.format(new Date, 'YYYY-MM-DD')); + fs.exists(curBackupDir, function(exists){ + if(!exists){ + fs.mkdirSync(curBackupDir); + } + var logFilePath = path.resolve(curBackupDir, './' + dateApi.format(new Date, self.delayType + self.delayType) + '.log'); + var cmdCat = 'cat ' + runlogPath + ' >> ' + logFilePath; + var cmdClear = 'cat /dev/null > ' + runlogPath; - //兼容windows - if(isWindows){ - logFilePath = logFilePath.replace(/\\/g, '\\\\'); - cmdCat = 'type ' + runlogPath + ' > ' + logFilePath; - cmdClear = 'type NUL > ' + runlogPath; - } + //兼容windows + if(isWindows){ + logFilePath = logFilePath.replace(/\\/g, '\\\\'); + cmdCat = 'type ' + runlogPath + ' > ' + logFilePath; + cmdClear = 'type NUL > ' + runlogPath; + } - //backup - logger.info('backup: '+ cmdCat); - var cat = cp.exec(cmdCat, function(error, stdout, stderr){ - if (error !== null) { - logger.error('cat error, ' + error); - } + //backup + logger.info('backup: '+ cmdCat); + + cp.exec(cmdCat, function(error, stdout, stderr){ + if (error !== null) { + logger.error('cat error, ' + error); + } - //clear - logger.info('clear: ' + cmdClear); - var clear = cp.exec(cmdClear, function(error, stdout, stderr){ - if (error !== null) { - logger.error('clear error, ' + error); - } - }); - }); - }); - } + //clear + logger.info('clear: ' + cmdClear); + + cp.exec(cmdClear, function(error, stdout, stderr){ + if (error !== null) { + logger.error('clear error, ' + error); + } + }); + }); + }); + } -} +}; module.exports = LogMan; \ No newline at end of file diff --git a/bin/tsw/config.js b/bin/tsw/config.js index dcead0a5..1c1265ca 100644 --- a/bin/tsw/config.js +++ b/bin/tsw/config.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; module.exports = require('../../bin/proxy/config.js'); @@ -13,6 +13,7 @@ if(Object.keys(module.exports).length === 0){ let curr = module; + /* eslint-disable no-console */ console.error('config加载存在循环引用:'); while(curr.parent){ @@ -20,6 +21,7 @@ if(Object.keys(module.exports).length === 0){ console.error(curr.parent.filename); curr = curr.parent; } + /* eslint-enable no-console */ process.emit('warning','config加载存在循环引用'); diff --git a/bin/tsw/context.js b/bin/tsw/context.js index 9774621e..1225d4cb 100644 --- a/bin/tsw/context.js +++ b/bin/tsw/context.js @@ -1,43 +1,43 @@ -/*! - * Tencent is pleased to support the open source community by making Tencent Server Web available. - * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. - * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - * http://opensource.org/licenses/MIT - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ -"use strict"; - -const Context = require('runtime/Context'); -const Window = require('runtime/Window'); - -this.currentContext = function(){ - return (process.domain && process.domain.currentContext) || new Context(); -} - -if(!global.context){ - - Object.defineProperty(global, 'context', { - get : function(){ - return module.exports.currentContext(); - } - }); - - Object.defineProperty(global, 'window', { - get : function(){ - - if(Window.windowHasDisabled){ - return undefined; - } - - var curr = module.exports.currentContext(); - - if(!curr.window){ - curr.window = new Window(); - } - - return curr.window; - } - }); -} - - +/*! + * Tencent is pleased to support the open source community by making Tencent Server Web available. + * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ +'use strict'; + +const Context = require('runtime/Context'); +const Window = require('runtime/Window'); + +this.currentContext = function(){ + return (process.domain && process.domain.currentContext) || new Context(); +}; + +if(!global.context){ + + Object.defineProperty(global, 'context', { + get : function(){ + return module.exports.currentContext(); + } + }); + + Object.defineProperty(global, 'window', { + get : function(){ + + if(Window.windowHasDisabled){ + return undefined; + } + + var curr = module.exports.currentContext(); + + if(!curr.window){ + curr.window = new Window(); + } + + return curr.window; + } + }); +} + + diff --git a/bin/tsw/default/config.default.sky.js b/bin/tsw/default/config.default.sky.js index 76f827be..09b18ff2 100644 --- a/bin/tsw/default/config.default.sky.js +++ b/bin/tsw/default/config.default.sky.js @@ -5,64 +5,64 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; //路由 this.modAct = this.modMap = { - map: { - log_view : 'util/auto-report/view.js', - log_download : 'util/auto-report/download.js', - group_page : 'util/h5-test/group/view.js', - h5test_page : 'util/h5-test/page/view.js', - h5test_managerget : 'util/h5-test/get.js', - h5test_manageradd : 'util/h5-test/add.js', - h5test_managerdel : 'util/h5-test/del.js', - '/api/h5test/get' : 'util/h5-test/get.js', - '/api/h5test/add' : 'util/h5-test/add.js', - '/api/h5test/del' : 'util/h5-test/del.js', - '/' : 'util/home/view.js', - '/index' : 'util/home/view.js', - static_tsw : 'util/static/static.js', - default_page : 'util/static/static.js' - }, + map: { + log_view : 'util/auto-report/view.js', + log_download : 'util/auto-report/download.js', + group_page : 'util/h5-test/group/view.js', + h5test_page : 'util/h5-test/page/view.js', + h5test_managerget : 'util/h5-test/get.js', + h5test_manageradd : 'util/h5-test/add.js', + h5test_managerdel : 'util/h5-test/del.js', + '/api/h5test/get' : 'util/h5-test/get.js', + '/api/h5test/add' : 'util/h5-test/add.js', + '/api/h5test/del' : 'util/h5-test/del.js', + '/' : 'util/home/view.js', + '/index' : 'util/home/view.js', + static_tsw : 'util/static/static.js', + default_page : 'util/static/static.js' + }, - getModAct: function(req){ - var pathname= req.REQUEST.pathname || ''; - var arr = pathname.split('/',3); - var mod = arr[1] || 'default'; - var act = arr[2] || 'page'; - var mod_act = mod + '_' + act; + getModAct: function(req){ + var pathname= req.REQUEST.pathname || ''; + var arr = pathname.split('/',3); + var mod = arr[1] || 'default'; + var act = arr[2] || 'page'; + var mod_act = mod + '_' + act; - if(this.map[pathname]){ - req.__mod_act = pathname; - return pathname; - } + if(this.map[pathname]){ + req.__mod_act = pathname; + return pathname; + } - if(this.map[mod_act]){ - req.__mod_act = mod_act; - return mod_act; - } + if(this.map[mod_act]){ + req.__mod_act = mod_act; + return mod_act; + } - return null; - }, - find: function(mod_act,req,res){ - mod_act = req.__mod_act; + return null; + }, + find: function(mod_act,req,res){ + mod_act = req.__mod_act; - var mod = this.map[mod_act]; + var mod = this.map[mod_act]; - if(mod_act === 'default_page'){ - req.REQUEST.pathname = '/static/tsw/index.html'; - } + if(mod_act === 'default_page'){ + req.REQUEST.pathname = '/static/tsw/index.html'; + } - if(mod){ - res.setHeader('Mod-Map', mod_act + ':' + mod); - return plug(mod); - } + if(mod){ + res.setHeader('Mod-Map', mod_act + ':' + mod); + return plug(mod); + } - return null; - } -} + return null; + } +}; diff --git a/bin/tsw/loader/seajs/lib/helper.js b/bin/tsw/loader/seajs/lib/helper.js index 47a7590f..0e44f732 100644 --- a/bin/tsw/loader/seajs/lib/helper.js +++ b/bin/tsw/loader/seajs/lib/helper.js @@ -3,84 +3,84 @@ * @author lifesinger@gmail.com */ -var aliasCache = {} -var url = require('url') +var aliasCache = {}; +var url = require('url'); exports.parseAlias = function (id) { - // #xxx means xxx is already alias-parsed. - if (id.charAt(0) === '#') { - return id.substring(1) - } + // #xxx means xxx is already alias-parsed. + if (id.charAt(0) === '#') { + return id.substring(1); + } - var alias = aliasCache + var alias = aliasCache; - // Only top-level id needs to parse alias. - if (alias && isTopLevel(id)) { - var parts = id.split('/') - var first = parts[0] + // Only top-level id needs to parse alias. + if (alias && isTopLevel(id)) { + var parts = id.split('/'); + var first = parts[0]; - if (alias.hasOwnProperty(first)) { - parts[0] = alias[first] - id = parts.join('/') + if (alias.hasOwnProperty(first)) { + parts[0] = alias[first]; + id = parts.join('/'); + } } - } - return id -} + return id; +}; exports.configFn = function(o) { - if (o && o.alias) { - var alias = o.alias + if (o && o.alias) { + var alias = o.alias; - for (var p in alias) { - if (alias.hasOwnProperty(p)) { - aliasCache[p] = alias[p] - } - } + for (var p in alias) { + if (alias.hasOwnProperty(p)) { + aliasCache[p] = alias[p]; + } + } - } -} + } +}; // Reads content from http(s)/local filesystem exports.readFile = function(uri, callback) { - var options = url.parse(uri) - var connect = require(options.protocol.slice(0, -1)) + var options = url.parse(uri); + var connect = require(options.protocol.slice(0, -1)); - connect.get(options, function(res) { - if (res.statusCode !== 200) { - throw 'Error: No data received from ' + uri - } + connect.get(options, function(res) { + if (res.statusCode !== 200) { + throw 'Error: No data received from ' + uri; + } - var ret = [], length = 0 + var ret = [], length = 0; - res.on('data', function(chunk) { - length += chunk.length - ret.push(chunk) - }) + res.on('data', function(chunk) { + length += chunk.length; + ret.push(chunk); + }); - callback && res.on('end', function() { - var buf = Buffer.alloc(length), index = 0 + callback && res.on('end', function() { + var buf = Buffer.alloc(length), index = 0; - ret.forEach(function(chunk) { - chunk.copy(buf, index, 0, chunk.length) - index += chunk.length - }) + ret.forEach(function(chunk) { + chunk.copy(buf, index, 0, chunk.length); + index += chunk.length; + }); - var data = buf.toString() - callback(data) - }) + var data = buf.toString(); + callback(data); + }); - }) -} + }); +}; // Helpers // ------- function isTopLevel(id) { - var c = id.charAt(0) - return id.indexOf('://') === -1 && c !== '.' && c !== '/' + var c = id.charAt(0); + return id.indexOf('://') === -1 && c !== '.' && c !== '/'; } diff --git a/bin/tsw/loader/seajs/lib/sea-node.js b/bin/tsw/loader/seajs/lib/sea-node.js index c1c4e55a..06d1222c 100644 --- a/bin/tsw/loader/seajs/lib/sea-node.js +++ b/bin/tsw/loader/seajs/lib/sea-node.js @@ -3,134 +3,136 @@ * @author lifesinger@gmail.com */ -var Module = module.constructor -var helper = require('./helper') -var vm = require('vm') +var Module = module.constructor; +var helper = require('./helper'); +var vm = require('vm'); -var _compile = Module.prototype._compile -var _resolveFilename = Module._resolveFilename -var moduleStack = [] +var _compile = Module.prototype._compile; +var _resolveFilename = Module._resolveFilename; +var moduleStack = []; Module._resolveFilename = function(request, parent) { - var res; - //request = request.replace(/\?.*$/, '') // remove timestamp etc. + var res; + //request = request.replace(/\?.*$/, '') // remove timestamp etc. - //性能优化 - if(parent.resolveFilenameCache){ - if(parent.resolveFilenameCache[request]){ - return parent.resolveFilenameCache[request] - } - }else{ - parent.resolveFilenameCache = {}; - } + //性能优化 + if(parent.resolveFilenameCache){ + if(parent.resolveFilenameCache[request]){ + return parent.resolveFilenameCache[request]; + } + }else{ + parent.resolveFilenameCache = {}; + } - res = _resolveFilename(request, parent); + res = _resolveFilename(request, parent); - parent.resolveFilenameCache[request] = res; + parent.resolveFilenameCache[request] = res; - return res; -} + return res; +}; Module.prototype._compile = function(content, filename) { - moduleStack.push(this) - try { - if(filename.indexOf(plug.parent) === 0){ - this.paths = plug.paths.concat(this.paths); + moduleStack.push(this); + try { + if(filename.indexOf(plug.parent) === 0){ + this.paths = plug.paths.concat(this.paths); + } + return _compile.call(this, content, filename); + }catch(err){ + process.nextTick(function(){ + process.emit('warning',err); + }); + throw err; + }finally { + moduleStack.pop(); } - return _compile.call(this, content, filename) - }catch(err){ - process.nextTick(function(){ - process.emit('warning',err); - }); - throw err; - }finally { - moduleStack.pop() - } -} +}; +/* eslint-disable no-console */ global.seajs = { - config: helper.configFn, - use: createAsync(module), - cache: require.cache, - log: console.log, - version: require('../package.json').version -} + config: helper.configFn, + use: createAsync(module), + cache: require.cache, + log: console.log, + version: require('../package.json').version +}; +/* eslint-enable no-console */ global.define = function() { - var factory = arguments[arguments.length - 1] - var ret = factory - var module = moduleStack[moduleStack.length - 1] || require.main - - // define(function(require, exports, module) { ... }) - if (typeof factory === 'function') { - module.uri = module.id - - var req = function(id) { - return module.require(id) + var factory = arguments[arguments.length - 1]; + var ret = factory; + var module = moduleStack[moduleStack.length - 1] || require.main; + + // define(function(require, exports, module) { ... }) + if (typeof factory === 'function') { + module.uri = module.id; + + var req = function(id) { + return module.require(id); + }; + req.async = createAsync(module); + + ret = factory.call( + global, + req, + module.exports, + module); + + if (ret !== undefined) { + module.exports = ret; + } } - req.async = createAsync(module) - - ret = factory.call( - global, - req, - module.exports, - module) - - if (ret !== undefined) { - module.exports = ret + // define(object) + else { + module.exports = factory; } - } - // define(object) - else { - module.exports = factory - } -} +}; function createAsync(module) { - return function(ids, callback) { - if (typeof ids === 'string') ids = [ids] - - var args = [] - var remain = ids.length - - ids.forEach(function(id, index) { - - // http or https file - if (/^https?:\/\//.test(id)) { - helper.readFile(id, function(data) { - var m = { - id: id, - exports: {} - } - - moduleStack.push(m) - vm.runInThisContext(data, id) - moduleStack.pop() - - done(m.exports, index) - }) - } - // local file - else { - done(module.require(id), index) - } - }) - - function done(data, index) { - args[index] = data - if (--remain === 0 && callback) { - callback.apply(null, args) - } - } - } + return function(ids, callback) { + if (typeof ids === 'string') ids = [ids]; + + var args = []; + var remain = ids.length; + + ids.forEach(function(id, index) { + + // http or https file + if (/^https?:\/\//.test(id)) { + helper.readFile(id, function(data) { + var m = { + id: id, + exports: {} + }; + + moduleStack.push(m); + vm.runInThisContext(data, id); + moduleStack.pop(); + + done(m.exports, index); + }); + } + // local file + else { + done(module.require(id), index); + } + }); + + function done(data, index) { + args[index] = data; + if (--remain === 0 && callback) { + callback.apply(null, args); + } + } + }; } -module.exports = global.seajs +module.exports = global.seajs; /** * Thanks to diff --git a/bin/tsw/logger.js b/bin/tsw/logger.js index 63eae702..7f15cd5a 100644 --- a/bin/tsw/logger.js +++ b/bin/tsw/logger.js @@ -5,6 +5,6 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; module.exports = require('util/logger')(); diff --git a/bin/tsw/plug.js b/bin/tsw/plug.js index 4302db6f..4342d983 100644 --- a/bin/tsw/plug.js +++ b/bin/tsw/plug.js @@ -1,57 +1,57 @@ -/*! - * Tencent is pleased to support the open source community by making Tencent Server Web available. - * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. - * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - * http://opensource.org/licenses/MIT - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ -"use strict"; - -const path = require('path'); - -/** - * - * 获取内置模块 - * - * @param {String} id - */ -function plug(id){ - return require(id); -} - -if(!global.plug){ - - - plug.__dirname = __dirname; - plug.parent = path.join(__dirname , '..'); - plug.paths = [ - path.join(__dirname , '../deps'), - path.join(__dirname , '../tsw'), - path.join(__dirname , '../tencent'), - path.join(__dirname , '../lib') - ]; - - module.paths = plug.paths.concat(module.paths); - - global.plug = plug; - - //支持seajs模块 - require('loader/seajs'); - require('loader/extentions.js'); - - JSON.stringify = function(stringify){ - return function(){ - var str = stringify.apply(this,arguments); - - if(str && str.indexOf('<') > -1){ - str = str.replace(/ -1){ + str = str.replace(/ 0){ - command = command.slice(0,Math.min(128,index)); - } - if(command.length >= 128){ - command = command.slice(0,128) + '...' + command.length; - } - - logger.debug(command); - - query.callback = function(callback){ - return function(...args){ - var err = args[0]; - var code = 0; - var isFail = 0; - var delay = Date.now() - start; - var toIp = servers.split(':')[0]; - - if(err && err.message !== 'Item is not stored'){ - if(err.stack){ - logger.error(command); - logger.error(servers); - logger.error(err.stack); - code = 2; - isFail = 1; - }else{ - logger.debug(err); - } - } - - dcapi.report({ - key : 'EVENT_TSW_MEMCACHED', - toIp : toIp, - code : code, - isFail : isFail, - delay : delay - }); - - queue.dequeue(); - return callback && callback.apply(this,args); - } - }(query.callback); - return query; - } - })(queryCompiler) + var fn = (function(queryCompiler){ + return function(){ + var query = queryCompiler(); + var command = query.command || ''; + var index = command.indexOf('\r\n'); //不要数据部分 + if(index > 0){ + command = command.slice(0,Math.min(128,index)); + } + if(command.length >= 128){ + command = command.slice(0,128) + '...' + command.length; + } + + logger.debug(command); + + query.callback = function(callback){ + return function(...args){ + var err = args[0]; + var code = 0; + var isFail = 0; + var delay = Date.now() - start; + var toIp = servers.split(':')[0]; + + if(err && err.message !== 'Item is not stored'){ + if(err.stack){ + logger.error(command); + logger.error(servers); + logger.error(err.stack); + code = 2; + isFail = 1; + }else{ + logger.debug(err); + } + } + + dcapi.report({ + key : 'EVENT_TSW_MEMCACHED', + toIp : toIp, + code : code, + isFail : isFail, + delay : delay + }); + + queue.dequeue(); + return callback && callback.apply(this,args); + }; + }(query.callback); + return query; + }; + })(queryCompiler); - command.call(memcached,fn, server); - }); - } - }(memcached.command); + command.call(memcached,fn, server); + }); + }; + }(memcached.command); - return memcached; + return memcached; } diff --git a/bin/tsw/router.js b/bin/tsw/router.js index ce402256..36d979e8 100644 --- a/bin/tsw/router.js +++ b/bin/tsw/router.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const logger = require('logger'); const httpRoute = require('../proxy/http.route.js'); @@ -13,40 +13,40 @@ const parseGet = require('util/http/parseGet.js'); this.route = function(url,mod_act){ - var req,res; - var window = context.window || {}; + var req,res; + var window = context.window || {}; - req = window.request; - res = window.response; + req = window.request; + res = window.response; - if(!req){ - return; - } + if(!req){ + return; + } - res.removeAllListeners('afterFinish'); + res.removeAllListeners('afterFinish'); - if(url){ + if(url){ - logger.debug('route to : ${url}',{ - url: url - }); + logger.debug('route to : ${url}',{ + url: url + }); - req.url = url; - //解析get参数 - parseGet(req); - } + req.url = url; + //解析get参数 + parseGet(req); + } - if(mod_act){ - logger.debug('route to mod_act: ${mod_act}',{ - mod_act: mod_act - }); + if(mod_act){ + logger.debug('route to mod_act: ${mod_act}',{ + mod_act: mod_act + }); - context.mod_act = mod_act; - }else{ - context.mod_act = null; - } + context.mod_act = mod_act; + }else{ + context.mod_act = null; + } - httpRoute.doRoute(req,res); -} + httpRoute.doRoute(req,res); +}; diff --git a/bin/tsw/runtime/CCFinder.js b/bin/tsw/runtime/CCFinder.js index de9463f3..ba8b01b3 100644 --- a/bin/tsw/runtime/CCFinder.js +++ b/bin/tsw/runtime/CCFinder.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const config = require('config'); const logger = require('logger'); @@ -13,237 +13,233 @@ const httpUtil = require('util/http'); const serverInfo = require('serverInfo.js'); const isTST = require('util/isTST.js'); const mail = require('util/mail/mail.js'); -const CD = require('util/CD.js'); const tnm2 = require('api/tnm2'); const CCIPSize = 1000; //统计周期 const CCIPLimit = config.CCIPLimit; //限制 var ipConut = CCIPSize; var cache = { - ipCache: {}, - whiteList: {}, - ipCacheLast: {} + ipCache: {}, + whiteList: {}, + ipCacheLast: {} }; if(global[__filename]){ - cache = global[__filename]; + cache = global[__filename]; }else{ - global[__filename] = cache; + global[__filename] = cache; } this.addWhiteList = function(userIp){ - cache.whiteList[userIp] = true; -} + cache.whiteList[userIp] = true; +}; this.checkHost = function(req, res){ - var hostAllow = config.allowHost || []; - var pass = true,i,len,v; - var host = req.headers['host']; + var hostAllow = config.allowHost || []; + var host = req.headers['host']; + var i,len,v; - if(hostAllow.length === 0){ - return true; - } + if(hostAllow.length === 0){ + return true; + } - if(host === serverInfo.intranetIp){ - return true; - } + if(host === serverInfo.intranetIp){ + return true; + } - for( i = 0, len = hostAllow.length; i < len; i++){ - v = hostAllow[i]; + for( i = 0, len = hostAllow.length; i < len; i++){ + v = hostAllow[i]; - if(typeof v === 'string'){ - if(v === host){ - return true; - } - }else if(typeof v === 'object'){ - if(v.test && v.test(host)){ - return true; - } - } - } + if(typeof v === 'string'){ + if(v === host){ + return true; + } + }else if(typeof v === 'object'){ + if(v.test && v.test(host)){ + return true; + } + } + } - logger.debug('limit by config.allowHost'); + logger.debug('limit by config.allowHost'); - res.setHeader('Content-Type', 'text/html; charset=UTF-8'); - res.writeHead(508); - res.end(); + res.setHeader('Content-Type', 'text/html; charset=UTF-8'); + res.writeHead(508); + res.end(); - return false; -} + return false; +}; //计算标准方差 this.StdX10 = function(ipCache){ - var res = 0; - var sum = 0; - var avg = 0; - var arr = Object.keys(ipCache).filter(function(item){ - var tmp = ipCache[item]; - if(typeof tmp === 'object' && tmp.list){ - sum += tmp.list.length; - return true; - } - return false; - }); + var res = 0; + var sum = 0; + var avg = 0; + var arr = Object.keys(ipCache).filter(function(item){ + var tmp = ipCache[item]; + if(typeof tmp === 'object' && tmp.list){ + sum += tmp.list.length; + return true; + } + return false; + }); - if(arr.length <= 1){ - return 0; - } + if(arr.length <= 1){ + return 0; + } - avg = sum / arr.length; + avg = sum / arr.length; - var sumXsum = arr.reduce(function(pre,key){ - var item = ipCache[key]; - var value = item.list.length; - item.avg = avg; + var sumXsum = arr.reduce(function(pre,key){ + var item = ipCache[key]; + var value = item.list.length; + item.avg = avg; - return pre + (value - avg)*(value - avg); - },0); + return pre + (value - avg)*(value - avg); + },0); - res = parseInt(Math.sqrt(sumXsum / (arr.length - 1)) * 10); + res = parseInt(Math.sqrt(sumXsum / (arr.length - 1)) * 10); - return res; -} + return res; +}; this.check = function(req, res){ - var CCIPLimitBase = 1; //1倍大小 - var userIp = httpUtil.getUserIp(req); - var userIp24 = httpUtil.getUserIp24(req); - var isInnerIP = httpUtil.isInnerIP(userIp); - var key,Content,tmp; - var info = { - userIp : userIp, - hostname : req.headers.host, - pathname : req.REQUEST.pathname - }; - var last,curr; - - if(cache.whiteList[userIp]){ - return true; - } - - if(cache.whiteList[userIp24]){ - return true; - } - - //忽略TST请求 - if(isTST.isTST(req)){ - return true; - } - - if(!cache.ipCache.start){ - cache.ipCache.start = Date.now(); - } + var userIp = httpUtil.getUserIp(req); + var userIp24 = httpUtil.getUserIp24(req); + var key,Content,curr; + + var info = { + userIp : userIp, + hostname : req.headers.host, + pathname : req.REQUEST.pathname + }; + + if(cache.whiteList[userIp]){ + return true; + } + + if(cache.whiteList[userIp24]){ + return true; + } + + //忽略TST请求 + if(isTST.isTST(req)){ + return true; + } + + if(!cache.ipCache.start){ + cache.ipCache.start = Date.now(); + } - ipConut = ipConut - 1; + ipConut = ipConut - 1; - if(ipConut <= 0){ - ipConut = CCIPSize; - cache.ipCache.end = Date.now(); - cache.ipCache.StdX10= this.StdX10(cache.ipCache); - cache.ipCacheLast = cache.ipCache; - cache.ipCache = {}; - cache.whiteList = {}; - - //上报标准方差 - tnm2.Attr_API_Set('AVG_TSW_IP_STD_X10', cache.ipCacheLast.StdX10); - } - - if(Date.now() - cache.ipCache.start > 60000){ - //时间太长 - ipConut = 0; - return true; - } + if(ipConut <= 0){ + ipConut = CCIPSize; + cache.ipCache.end = Date.now(); + cache.ipCache.StdX10= this.StdX10(cache.ipCache); + cache.ipCacheLast = cache.ipCache; + cache.ipCache = {}; + cache.whiteList = {}; + + //上报标准方差 + tnm2.Attr_API_Set('AVG_TSW_IP_STD_X10', cache.ipCacheLast.StdX10); + } + + if(Date.now() - cache.ipCache.start > 60000){ + //时间太长 + ipConut = 0; + return true; + } - if(!cache.ipCache[userIp]){ - cache.ipCache[userIp] = { - ip007Info: null, - isSendMail: false, - list: [] - }; - } + if(!cache.ipCache[userIp]){ + cache.ipCache[userIp] = { + ip007Info: null, + isSendMail: false, + list: [] + }; + } - curr = cache.ipCache[userIp]; - last = cache.ipCacheLast[userIp]; + curr = cache.ipCache[userIp]; - curr.list.push(info); + curr.list.push(info); - if(CCIPLimit <= -1){ - return true; - } + if(CCIPLimit <= -1){ + return true; + } - if(config.isTest){ - //测试环境 - return true; - } + if(config.isTest){ + //测试环境 + return true; + } - if(config.devMode){ - //开发环境 - return true; - } - - if(!cache.ipCacheLast.StdX10){ - return true; - } + if(config.devMode){ + //开发环境 + return true; + } + + if(!cache.ipCacheLast.StdX10){ + return true; + } - if(cache.ipCacheLast.StdX10 <= CCIPLimit){ - return true; - } + if(cache.ipCacheLast.StdX10 <= CCIPLimit){ + return true; + } - if(cache.ipCacheLast.hasSendMail){ - return true; - } + if(cache.ipCacheLast.hasSendMail){ + return true; + } - //tnm2.Attr_API('SUM_TSW_CC_LIMIT', 1); + //tnm2.Attr_API('SUM_TSW_CC_LIMIT', 1); - //确认没发送过邮件 - cache.ipCacheLast.hasSendMail = true; + //确认没发送过邮件 + cache.ipCacheLast.hasSendMail = true; - //发现目标,发邮件 - key = `[AVG_TSW_IP_STD_X10]:${serverInfo.intranetIp}`; + //发现目标,发邮件 + key = `[AVG_TSW_IP_STD_X10]:${serverInfo.intranetIp}`; - Content = ''; + Content = ''; - Object.keys(cache.ipCacheLast).forEach(function(ip,i){ + Object.keys(cache.ipCacheLast).forEach(function(ip,i){ - var num = ''; + var num = ''; - if( - cache.ipCacheLast[ip] + if( + cache.ipCacheLast[ip] && cache.ipCacheLast[ip].list && cache.ipCacheLast[ip].list.length > 1 - ){ - num = '' + cache.ipCacheLast[ip].list.length; - num = (num + 'XXXXXX').slice(0,8).replace(/X/g,' '); - Content += `
${num}${ip}
`; - } - }); - - mail.SendMail(key,'TSW',3600,{ - 'To' : config.mailTo, - 'CC' : config.mailCC, - 'Title' : `[IP聚集告警][${cache.ipCacheLast.StdX10}%]${serverInfo.intranetIp}`, - 'Content' : '

服务器IP:' + serverInfo.intranetIp + '

' + ){ + num = '' + cache.ipCacheLast[ip].list.length; + num = (num + 'XXXXXX').slice(0,8).replace(/X/g,' '); + Content += `
${num}${ip}
`; + } + }); + + mail.SendMail(key,'TSW',3600,{ + 'To' : config.mailTo, + 'CC' : config.mailCC, + 'Title' : `[IP聚集告警][${cache.ipCacheLast.StdX10}%]${serverInfo.intranetIp}`, + 'Content' : '

服务器IP:' + serverInfo.intranetIp + '

' + '

IP聚集度:' + cache.ipCacheLast.StdX10 + '%

' + '

告警阀值:' + CCIPLimit + '

' + '

正常值:5-50

' + '

检测耗时:' + parseInt((cache.ipCacheLast.end - cache.ipCacheLast.start)/1000) + 's

' + '

证据列表:

' + Content - }); + }); - return true; -} + return true; +}; this.getIpCache = function(){ - return cache.ipCacheLast; + return cache.ipCacheLast; }; this.getIpSize = function(){ - return CCIPSize; + return CCIPSize; }; diff --git a/bin/tsw/runtime/Console.hack.js b/bin/tsw/runtime/Console.hack.js index 583e11ca..a02761e3 100644 --- a/bin/tsw/runtime/Console.hack.js +++ b/bin/tsw/runtime/Console.hack.js @@ -5,53 +5,57 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; if(!global[__filename]){ - global[__filename] = true; - - process.nextTick(function(){ - var util = require('util'); - var logger = require('logger'); - - console.debug = function(log) { - return function(...args) { - return logger.writeLog('DBUG', `${util.format.apply(null, args)}`); - } - }(console.originDebug = console.debug); - - console.log = function(log) { - return function(...args) { - return logger.writeLog('DBUG', `${util.format.apply(null, args)}`); - } - }(console.originLog = console.log); - - console.info = function(log) { - return function(...args) { - return logger.writeLog('INFO', `${util.format.apply(null, args)}`); - } - }(console.originInfo = console.info); - - console.dir = function(log) { - return function(object, options) { - options = Object.assign({ - customInspect: false - }, options); - return logger.writeLog('INFO', `${util.inspect(object, options)}`); - } - }(console.originDir = console.dir); - - console.warn = function(log) { - return function(...args) { - return logger.writeLog('WARN', `${util.format.apply(null, args)}`); - } - }(console.originWarn = console.warn); - - console.error = function(log) { - return function(...args) { - return logger.writeLog('ERRO', `${util.format.apply(null, args)}`); - } - }(console.originError = console.error); - }); + global[__filename] = true; + + process.nextTick(function(){ + var util = require('util'); + var logger = require('logger'); + + /* eslint-disable no-console */ + + console.debug = function(log) { + return function(...args) { + return logger.writeLog('DBUG', `${util.format.apply(null, args)}`); + }; + }(console.originDebug = console.debug); + + console.log = function(log) { + return function(...args) { + return logger.writeLog('DBUG', `${util.format.apply(null, args)}`); + }; + }(console.originLog = console.log); + + console.info = function(log) { + return function(...args) { + return logger.writeLog('INFO', `${util.format.apply(null, args)}`); + }; + }(console.originInfo = console.info); + + console.dir = function(log) { + return function(object, options) { + options = Object.assign({ + customInspect: false + }, options); + return logger.writeLog('INFO', `${util.inspect(object, options)}`); + }; + }(console.originDir = console.dir); + + console.warn = function(log) { + return function(...args) { + return logger.writeLog('WARN', `${util.format.apply(null, args)}`); + }; + }(console.originWarn = console.warn); + + console.error = function(log) { + return function(...args) { + return logger.writeLog('ERRO', `${util.format.apply(null, args)}`); + }; + }(console.originError = console.error); + + /* eslint-enable no-console */ + }); } diff --git a/bin/tsw/runtime/Context.js b/bin/tsw/runtime/Context.js index 54847585..ac541568 100644 --- a/bin/tsw/runtime/Context.js +++ b/bin/tsw/runtime/Context.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; module.exports = Context; @@ -16,22 +16,14 @@ function Context(){ Context.prototype.setModAct = function(mod_act){ - if(!typeof(context)){ - return false; - } + context.mod_act = mod_act; - context.mod_act = mod_act; - - return true; -} + return true; +}; Context.prototype.getModAct = function(){ - if(!typeof(context)){ - return null; - } - - return context.mod_act; -} + return context.mod_act; +}; diff --git a/bin/tsw/runtime/ContextWrap.js b/bin/tsw/runtime/ContextWrap.js index 03987f47..905fd0c6 100644 --- a/bin/tsw/runtime/ContextWrap.js +++ b/bin/tsw/runtime/ContextWrap.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const EventEmitter = require('events'); const net = require('net'); @@ -17,61 +17,61 @@ const parseGet = require('util/http/parseGet'); class ContextWrap extends EventEmitter { - constructor(opt = {}) { - super(); + constructor(opt = {}) { + super(); - this._domain = domain.create(); + this._domain = domain.create(); - this._req = new http.IncomingMessage(opt.reqSocket || new net.Socket()); - this._rsp = new http.ServerResponse(this._req); + this._req = new http.IncomingMessage(opt.reqSocket || new net.Socket()); + this._rsp = new http.ServerResponse(this._req); - this._req.url = opt.url || '/emptyurl'; + this._req.url = opt.url || '/emptyurl'; - parseGet(this._req); - } + parseGet(this._req); + } - fillRequest(md) { - md && md(this._req); - } + fillRequest(md) { + md && md(this._req); + } - fillResponse(md) { - md && md(this._rsp); - } + fillResponse(md) { + md && md(this._rsp); + } - add(obj) { - this._domain.add(obj); - } + add(obj) { + this._domain.add(obj); + } - remove(obj) { - this._domain.remove(obj); - } + remove(obj) { + this._domain.remove(obj); + } - run(md) { - this._domain.add(this._req); - this._domain.add(this._rsp); + run(md) { + this._domain.add(this._req); + this._domain.add(this._rsp); - this._domain.currentContext = new Context(); - this._domain.currentContext.log = {}; - this._domain.currentContext.SN = ++process.SN; - this._domain.currentContext.window = new Window(); - this._domain.currentContext.window.request = this._req; - this._domain.currentContext.window.response = this._rsp; + this._domain.currentContext = new Context(); + this._domain.currentContext.log = {}; + this._domain.currentContext.SN = ++process.SN; + this._domain.currentContext.window = new Window(); + this._domain.currentContext.window.request = this._req; + this._domain.currentContext.window.response = this._rsp; - this._domain.on('error', e => { - this.emit('error', e); - }); + this._domain.on('error', e => { + this.emit('error', e); + }); - this._domain.run(md); - } + this._domain.run(md); + } - destroy() { - this._domain.remove(this._req); - this._domain.remove(this._rsp); + destroy() { + this._domain.remove(this._req); + this._domain.remove(this._rsp); - this._domain = null; - this._req = null; - this._rsp = null; - } + this._domain = null; + this._req = null; + this._rsp = null; + } } module.exports = ContextWrap; \ No newline at end of file diff --git a/bin/tsw/runtime/Dns.hack.js b/bin/tsw/runtime/Dns.hack.js index c2dacdf1..0f48ae4b 100644 --- a/bin/tsw/runtime/Dns.hack.js +++ b/bin/tsw/runtime/Dns.hack.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; if(!global[__filename]){ @@ -69,15 +69,15 @@ if(!global[__filename]){ isCalled = true; clearTimeout(timer); callback(err, address, family); - } + }; if(callback !== options) { - args.push(options) + args.push(options); } - args.push(callbackWrap) + args.push(callbackWrap); timer = setTimeout(function() { - callbackWrap((timeoutError = new Error("Dns Lookup Timeout"))); + callbackWrap((timeoutError = new Error('Dns Lookup Timeout'))); }, config.timeout && config.timeout.dns || 3000); return fn.apply(this, args); diff --git a/bin/tsw/runtime/JankWatcher.js b/bin/tsw/runtime/JankWatcher.js index c978eb14..4ac1fc8a 100644 --- a/bin/tsw/runtime/JankWatcher.js +++ b/bin/tsw/runtime/JankWatcher.js @@ -5,28 +5,28 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const tnm2 = require('api/tnm2'); if(!global[__filename]) { - global[__filename] = true; + global[__filename] = true; - const watch = function() { - var t1 = Date.now(); + const watch = function() { + var t1 = Date.now(); - setTimeout(() => { - var t = (Date.now() - t1) * 10; + setTimeout(() => { + var t = (Date.now() - t1) * 10; - tnm2.Attr_API_Set('AVG_TSW_ST0_X10', t); + tnm2.Attr_API_Set('AVG_TSW_ST0_X10', t); - //10S检查一次 - setTimeout(() => { - watch(); - }, 10 * 1000); - }, 0); - }; + //10S检查一次 + setTimeout(() => { + watch(); + }, 10 * 1000); + }, 0); + }; - watch(); + watch(); } \ No newline at end of file diff --git a/bin/tsw/runtime/Window.js b/bin/tsw/runtime/Window.js index 0e1ed232..d65f8b93 100644 --- a/bin/tsw/runtime/Window.js +++ b/bin/tsw/runtime/Window.js @@ -1,23 +1,23 @@ -/*! - * Tencent is pleased to support the open source community by making Tencent Server Web available. - * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. - * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - * http://opensource.org/licenses/MIT - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ -"use strict"; - -module.exports = Window; - -function Window(){ - -} - -Window.prototype.disable = function(){ - Window.windowHasDisabled = true; -} - -Window.prototype.enable = function(){ - Window.windowHasDisabled = false; -} - +/*! + * Tencent is pleased to support the open source community by making Tencent Server Web available. + * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ +'use strict'; + +module.exports = Window; + +function Window(){ + +} + +Window.prototype.disable = function(){ + Window.windowHasDisabled = true; +}; + +Window.prototype.enable = function(){ + Window.windowHasDisabled = false; +}; + diff --git a/bin/tsw/runtime/capturer.js b/bin/tsw/runtime/capturer.js index a5021404..ee17aead 100644 --- a/bin/tsw/runtime/capturer.js +++ b/bin/tsw/runtime/capturer.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; /** * 抓包 @@ -16,215 +16,214 @@ const https = require('https'); var isFirstLoad = true; if(global[__filename]){ - isFirstLoad = false; + isFirstLoad = false; }else{ - global[__filename] = {}; + global[__filename] = {}; } isFirstLoad && process.nextTick(function() { - const logger = require('logger'); - const config = require('config'); - const httpUtil = require('util/http'); - const alpha = require('util/auto-report/alpha.js'); - const serverInfo = require('serverInfo.js'); - - const create = function(oriRequest,protocol){ - return function(...args){ - var opt = args[0]; - var request = oriRequest.apply(this,args); - var captureBody = false; - var result = []; - var buffer = Buffer.alloc(0); - var bodySize = 0; - var maxBodySize = 1024 * 1024; - var timeStart = Date.now(); - var timeEnd = 0; - var timeResponse = 0; - var timeCurr = timeStart; - var remoteAddress = ''; - var remotePort = ''; - var localAddress = ''; - var localPort = ''; - var host = (opt.headers && opt.headers.host) || opt.host; - - if(context.requestCaptureSN){ - context.requestCaptureSN++; - }else{ - context.requestCaptureSN = 1; - } - - var SN = context.requestCaptureSN || 0; - var logPre = `[${SN}] `; - - logger.debug(logPre + '${method} ${ip}:${port} ~ ${protocol}//${host}${path}',{ - protocol : protocol, - method : opt.method, - host : host, - ip : opt.host, - port : opt.port || (protocol === 'https:' ? 443 : 80), - path : opt.path - }); - - //抓包 - if(alpha.isAlpha()){ - logger.debug(logPre + 'capture body on'); - captureBody = true; - } - - if(captureBody){ - httpUtil.captureBody(request); - - request.once('finish',function(){ - logger.debug(logPre + 'send finish, total size ' + this._body.length); - }); - } - - var report = function(oriResponse){ - var logJson = logger.getJson(); - var response = oriResponse || { - headers : { - 'content-length' : 0, - 'content-type' : 'text/html' - }, - httpVersion : '1.1', - statusCode : 513, - statusMessage : 'server buisy' - }; - - if(!logJson){ - logger.debug('logger.getJson() is empty!'); - return; - } - - var curr = { - SN : SN, - - protocol : protocol === 'https:' ? 'HTTPS' : 'HTTP', - host : host, - url : `${protocol}//${host}${opt.path}`, - cache : '', - process : 'TSW:' + process.pid, - resultCode : response.statusCode, - contentLength : bodySize || response.headers['content-length'], - contentType : response.headers['content-type'], - clientIp : localAddress || serverInfo.intranetIp, - clientPort : localPort || '', - serverIp : remoteAddress || opt.host, - serverPort : remotePort || opt.port, - requestRaw : httpUtil.getClientRequestHeaderStr(request) + (request._body.toString('UTF-8') || ''), - responseHeader : httpUtil.getClientResponseHeaderStr(response,bodySize), - responseBody : (buffer.toString('base64')) || '', - timestamps : { - ClientConnected : new Date(timeStart), - ClientBeginRequest : new Date(timeStart), - GotRequestHeaders : new Date(timeStart), - ClientDoneRequest : new Date(timeStart), - GatewayTime : 0, - DNSTime : 0, - TCPConnectTime : 0, - HTTPSHandshakeTime : 0, - ServerConnected : new Date(timeStart), - FiddlerBeginRequest: new Date(timeStart), - ServerGotRequest : new Date(timeStart), - ServerBeginResponse: new Date(timeResponse), - GotResponseHeaders : new Date(timeResponse), - ServerDoneResponse : new Date(timeEnd), - ClientBeginResponse: new Date(timeResponse), - ClientDoneResponse : new Date(timeEnd) - } - }; - - logJson.ajax.push(curr); - } - - request.once('response',(response)=>{ - timeResponse = Date.now(); - - var socket = response.socket; - - process.domain && process.domain.add(response); - - remoteAddress = socket.remoteAddress; - remotePort = socket.remotePort; - localAddress = socket.localAddress; - localPort = socket.localPort; - - logger.debug(logPre + '${localAddress}:${localPort} > ${remoteAddress}:${remotePort} response ${statusCode} cost:${cost}ms ${encoding}',{ - remoteAddress : remoteAddress, - remotePort : remotePort, - localAddress : localAddress, - localPort : localPort, - statusCode: response.statusCode, - encoding: response.headers['content-encoding'], - cost: timeResponse - timeStart - }); - - var done = function(){ - this.removeListener('data',data); - - if(timeEnd){ - return; - } - - timeEnd = new Date().getTime(); - - if(captureBody){ - buffer = Buffer.concat(result); - result = []; - } - - //上报 - if(captureBody){ - report(response); - } - } - - var data = function(chunk){ - var cost = Date.now() - timeCurr; - - timeCurr = Date.now(); - - //logger.debug('${logPre}receive data: ${size},\tcost: ${cost}ms',{ - // logPre: logPre, - // cost: cost, - // size: chunk.length - //}); - - bodySize += chunk.length; - - if(captureBody && bodySize <= maxBodySize){ - result.push(chunk); - } - } - - response.on('data',data); - - response.once('close',function(){ - logger.debug(logPre + 'close'); - - done.call(this); - }); - - response.once('end',function(){ - var cost = Date.now() - timeStart; - - logger.debug('${logPre}end size:${size}, receive data cost: ${cost}ms',{ - logPre: logPre, - cost: cost, - size: bodySize - }); - - done.call(this); - }); - - }); - - return request; - } - }; + const logger = require('logger'); + const httpUtil = require('util/http'); + const alpha = require('util/auto-report/alpha.js'); + const serverInfo = require('serverInfo.js'); + + const create = function(oriRequest,protocol){ + return function(...args){ + var opt = args[0]; + var request = oriRequest.apply(this,args); + var captureBody = false; + var result = []; + var buffer = Buffer.alloc(0); + var bodySize = 0; + var maxBodySize = 1024 * 1024; + var timeStart = Date.now(); + var timeEnd = 0; + var timeResponse = 0; + // var timeCurr = timeStart; + var remoteAddress = ''; + var remotePort = ''; + var localAddress = ''; + var localPort = ''; + var host = (opt.headers && opt.headers.host) || opt.host; + + if(context.requestCaptureSN){ + context.requestCaptureSN++; + }else{ + context.requestCaptureSN = 1; + } + + var SN = context.requestCaptureSN || 0; + var logPre = `[${SN}] `; + + logger.debug(logPre + '${method} ${ip}:${port} ~ ${protocol}//${host}${path}',{ + protocol : protocol, + method : opt.method, + host : host, + ip : opt.host, + port : opt.port || (protocol === 'https:' ? 443 : 80), + path : opt.path + }); + + //抓包 + if(alpha.isAlpha()){ + logger.debug(logPre + 'capture body on'); + captureBody = true; + } + + if(captureBody){ + httpUtil.captureBody(request); + + request.once('finish',function(){ + logger.debug(logPre + 'send finish, total size ' + this._body.length); + }); + } + + var report = function(oriResponse){ + var logJson = logger.getJson(); + var response = oriResponse || { + headers : { + 'content-length' : 0, + 'content-type' : 'text/html' + }, + httpVersion : '1.1', + statusCode : 513, + statusMessage : 'server buisy' + }; + + if(!logJson){ + logger.debug('logger.getJson() is empty!'); + return; + } + + var curr = { + SN : SN, + + protocol : protocol === 'https:' ? 'HTTPS' : 'HTTP', + host : host, + url : `${protocol}//${host}${opt.path}`, + cache : '', + process : 'TSW:' + process.pid, + resultCode : response.statusCode, + contentLength : bodySize || response.headers['content-length'], + contentType : response.headers['content-type'], + clientIp : localAddress || serverInfo.intranetIp, + clientPort : localPort || '', + serverIp : remoteAddress || opt.host, + serverPort : remotePort || opt.port, + requestRaw : httpUtil.getClientRequestHeaderStr(request) + (request._body.toString('UTF-8') || ''), + responseHeader : httpUtil.getClientResponseHeaderStr(response,bodySize), + responseBody : (buffer.toString('base64')) || '', + timestamps : { + ClientConnected : new Date(timeStart), + ClientBeginRequest : new Date(timeStart), + GotRequestHeaders : new Date(timeStart), + ClientDoneRequest : new Date(timeStart), + GatewayTime : 0, + DNSTime : 0, + TCPConnectTime : 0, + HTTPSHandshakeTime : 0, + ServerConnected : new Date(timeStart), + FiddlerBeginRequest: new Date(timeStart), + ServerGotRequest : new Date(timeStart), + ServerBeginResponse: new Date(timeResponse), + GotResponseHeaders : new Date(timeResponse), + ServerDoneResponse : new Date(timeEnd), + ClientBeginResponse: new Date(timeResponse), + ClientDoneResponse : new Date(timeEnd) + } + }; + + logJson.ajax.push(curr); + }; + + request.once('response',(response)=>{ + timeResponse = Date.now(); + + var socket = response.socket; + + process.domain && process.domain.add(response); + + remoteAddress = socket.remoteAddress; + remotePort = socket.remotePort; + localAddress = socket.localAddress; + localPort = socket.localPort; + + logger.debug(logPre + '${localAddress}:${localPort} > ${remoteAddress}:${remotePort} response ${statusCode} cost:${cost}ms ${encoding}',{ + remoteAddress : remoteAddress, + remotePort : remotePort, + localAddress : localAddress, + localPort : localPort, + statusCode: response.statusCode, + encoding: response.headers['content-encoding'], + cost: timeResponse - timeStart + }); + + var done = function(){ + this.removeListener('data',data); + + if(timeEnd){ + return; + } + + timeEnd = new Date().getTime(); + + if(captureBody){ + buffer = Buffer.concat(result); + result = []; + } + + //上报 + if(captureBody){ + report(response); + } + }; + + var data = function(chunk){ + // var cost = Date.now() - timeCurr; + + // timeCurr = Date.now(); + + //logger.debug('${logPre}receive data: ${size},\tcost: ${cost}ms',{ + // logPre: logPre, + // cost: cost, + // size: chunk.length + //}); + + bodySize += chunk.length; + + if(captureBody && bodySize <= maxBodySize){ + result.push(chunk); + } + }; + + response.on('data',data); + + response.once('close',function(){ + logger.debug(logPre + 'close'); + + done.call(this); + }); + + response.once('end',function(){ + var cost = Date.now() - timeStart; + + logger.debug('${logPre}end size:${size}, receive data cost: ${cost}ms',{ + logPre: logPre, + cost: cost, + size: bodySize + }); + + done.call(this); + }); + + }); + + return request; + }; + }; - http.request = create(http.request,'http:'); - https.request = create(https.request,'https:'); + http.request = create(http.request,'http:'); + https.request = create(https.request,'https:'); }); diff --git a/bin/tsw/runtime/fs.hack.js b/bin/tsw/runtime/fs.hack.js index 4b850967..cf857bcd 100644 --- a/bin/tsw/runtime/fs.hack.js +++ b/bin/tsw/runtime/fs.hack.js @@ -5,171 +5,166 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const TIMES_LIMIT = 5; if(global[__filename]){ - global[__filename].map = {}; + global[__filename].map = {}; }else{ - global[__filename] = { - map: {} - }; - - //追踪重复读写 - process.nextTick(function(){ - var cache = global[__filename]; - var isWindows = require('util/isWindows'); - var fs = require('fs'); - var util = require('util'); - var logger = require('logger'); - var config = require('config'); - var tnm2 = require('api/tnm2'); - - fs.existsSync = hack(fs.existsSync,function(file){ - var sum = 0; - var name = 'fs.existsSync'; - var key = name + file; - - cache.map[key] = ~~cache.map[key] + 1; - sum = cache.map[key]; - - if(sum % TIMES_LIMIT === 0 && !config.devMode){ - logger.warn('[sync]${name} callee ${sum} times on file: ${file} \n${stack}',{ - name: name, - file: file, - sum: sum, - stack: new Error('find bad code').stack - }); - } - - tnm2.Attr_API('SUM_TSW_FILE_SYNC', 1); - }); - - fs.writeFileSync = hack(fs.writeFileSync,function(file){ - var sum = 0; - var name = 'fs.writeFileSync'; - var key = name + file; - - cache.map[key] = ~~cache.map[key] + 1; - sum = cache.map[key]; - - if(sum % TIMES_LIMIT === 0 && !config.devMode){ - logger.warn('[sync]${name} callee ${sum} times on file: ${file} \n${stack}',{ - name: name, - file: file, - sum: sum, - stack: new Error('find bad code').stack - }); - } - - tnm2.Attr_API('SUM_TSW_FILE_SYNC', 1); - }); - - fs.statSync = hack(fs.statSync,function(file){ - var sum = 0; - var name = 'fs.statSync'; - var key = name + file; - - cache.map[key] = ~~cache.map[key] + 1; - sum = cache.map[key]; - - if(sum > TIMES_LIMIT && !config.devMode){ - logger.warn('[sync]${name} callee ${sum} times on file: ${file} \n${stack}',{ - name: name, - file: file, - sum: sum, - stack: new Error('find bad code').stack - }); - } - - tnm2.Attr_API('SUM_TSW_FILE_SYNC', 1); - }); - - fs.accessSync = hack(fs.accessSync,function(file){ - var sum = 0; - var name = 'fs.accessSync'; - var key = name + file; - - cache.map[key] = ~~cache.map[key] + 1; - sum = cache.map[key]; - - if(sum % TIMES_LIMIT === 0 && !config.devMode){ - logger.warn('[sync]${name} callee ${sum} times on file: ${file} \n${stack}',{ - name: name, - file: file, - sum: sum, - stack: new Error('find bad code').stack - }); - } - - tnm2.Attr_API('SUM_TSW_FILE_SYNC', 1); - }); - - fs.readFileSync = hack(fs.readFileSync,function(file){ - var sum = 0; - var name = 'fs.readFileSync'; - var key = name + file; - - cache.map[key] = ~~cache.map[key] + 1; - sum = cache.map[key]; - - if(sum > TIMES_LIMIT && !config.devMode){ - logger.warn('[sync]${name} callee ${sum} times on file: ${file} \n${stack}',{ - name: name, - file: file, - sum: sum, - stack: new Error('find bad code').stack - }); - } - - tnm2.Attr_API('SUM_TSW_FILE_SYNC', 1); - }); - - fs.readdirSync = hack(fs.readdirSync,function(file){ - var sum = 0; - var name = 'fs.readdirSync'; - var key = name + file; - - cache.map[key] = ~~cache.map[key] + 1; - sum = cache.map[key]; - - if(sum % TIMES_LIMIT === 0 && !config.devMode){ - logger.warn('[sync]${name} callee ${sum} times on file: ${file} \n${stack}',{ - name: name, - file: file, - sum: sum, - stack: new Error('find bad code').stack - }); - } - - tnm2.Attr_API('SUM_TSW_FILE_SYNC', 1); - }); - - //fs.realpathSync = hack(fs.realpathSync,function(file){ - // logger.debug('[sync] ${name} ${file}',{ - // name: 'fs.realpathSync', - // file: file - // }); - //}); - - function checkSum(){ - logger.info() - } - - function hack(fn,callback){ - - if(isWindows.isWindows){ - return fn; - } - - return function(){ - callback.apply(this, arguments); - return fn.apply(this, arguments); - } - } - }); + global[__filename] = { + map: {} + }; + + //追踪重复读写 + process.nextTick(function(){ + var cache = global[__filename]; + var isWindows = require('util/isWindows'); + var fs = require('fs'); + var logger = require('logger'); + var config = require('config'); + var tnm2 = require('api/tnm2'); + + fs.existsSync = hack(fs.existsSync,function(file){ + var sum = 0; + var name = 'fs.existsSync'; + var key = name + file; + + cache.map[key] = ~~cache.map[key] + 1; + sum = cache.map[key]; + + if(sum % TIMES_LIMIT === 0 && !config.devMode){ + logger.warn('[sync]${name} callee ${sum} times on file: ${file} \n${stack}',{ + name: name, + file: file, + sum: sum, + stack: new Error('find bad code').stack + }); + } + + tnm2.Attr_API('SUM_TSW_FILE_SYNC', 1); + }); + + fs.writeFileSync = hack(fs.writeFileSync,function(file){ + var sum = 0; + var name = 'fs.writeFileSync'; + var key = name + file; + + cache.map[key] = ~~cache.map[key] + 1; + sum = cache.map[key]; + + if(sum % TIMES_LIMIT === 0 && !config.devMode){ + logger.warn('[sync]${name} callee ${sum} times on file: ${file} \n${stack}',{ + name: name, + file: file, + sum: sum, + stack: new Error('find bad code').stack + }); + } + + tnm2.Attr_API('SUM_TSW_FILE_SYNC', 1); + }); + + fs.statSync = hack(fs.statSync,function(file){ + var sum = 0; + var name = 'fs.statSync'; + var key = name + file; + + cache.map[key] = ~~cache.map[key] + 1; + sum = cache.map[key]; + + if(sum > TIMES_LIMIT && !config.devMode){ + logger.warn('[sync]${name} callee ${sum} times on file: ${file} \n${stack}',{ + name: name, + file: file, + sum: sum, + stack: new Error('find bad code').stack + }); + } + + tnm2.Attr_API('SUM_TSW_FILE_SYNC', 1); + }); + + fs.accessSync = hack(fs.accessSync,function(file){ + var sum = 0; + var name = 'fs.accessSync'; + var key = name + file; + + cache.map[key] = ~~cache.map[key] + 1; + sum = cache.map[key]; + + if(sum % TIMES_LIMIT === 0 && !config.devMode){ + logger.warn('[sync]${name} callee ${sum} times on file: ${file} \n${stack}',{ + name: name, + file: file, + sum: sum, + stack: new Error('find bad code').stack + }); + } + + tnm2.Attr_API('SUM_TSW_FILE_SYNC', 1); + }); + + fs.readFileSync = hack(fs.readFileSync,function(file){ + var sum = 0; + var name = 'fs.readFileSync'; + var key = name + file; + + cache.map[key] = ~~cache.map[key] + 1; + sum = cache.map[key]; + + if(sum > TIMES_LIMIT && !config.devMode){ + logger.warn('[sync]${name} callee ${sum} times on file: ${file} \n${stack}',{ + name: name, + file: file, + sum: sum, + stack: new Error('find bad code').stack + }); + } + + tnm2.Attr_API('SUM_TSW_FILE_SYNC', 1); + }); + + fs.readdirSync = hack(fs.readdirSync,function(file){ + var sum = 0; + var name = 'fs.readdirSync'; + var key = name + file; + + cache.map[key] = ~~cache.map[key] + 1; + sum = cache.map[key]; + + if(sum % TIMES_LIMIT === 0 && !config.devMode){ + logger.warn('[sync]${name} callee ${sum} times on file: ${file} \n${stack}',{ + name: name, + file: file, + sum: sum, + stack: new Error('find bad code').stack + }); + } + + tnm2.Attr_API('SUM_TSW_FILE_SYNC', 1); + }); + + //fs.realpathSync = hack(fs.realpathSync,function(file){ + // logger.debug('[sync] ${name} ${file}',{ + // name: 'fs.realpathSync', + // file: file + // }); + //}); + + function hack(fn,callback){ + + if(isWindows.isWindows){ + return fn; + } + + return function(){ + callback.apply(this, arguments); + return fn.apply(this, arguments); + }; + } + }); } diff --git a/bin/tsw/runtime/overloadProtection.js b/bin/tsw/runtime/overloadProtection.js index 816ef4ef..dadaeecf 100644 --- a/bin/tsw/runtime/overloadProtection.js +++ b/bin/tsw/runtime/overloadProtection.js @@ -5,39 +5,39 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; // 过载保护 process.nextTick(function() { - var logger = require('logger') - var tnm2 = require('api/tnm2') - var config = require('config') + var logger = require('logger'); + var tnm2 = require('api/tnm2'); + var config = require('config'); - // 高负载时丢弃部分请求 - var cpuLimit = 85 - if (config.cpuLimit >= 0) { - cpuLimit = config.cpuLimit - } + // 高负载时丢弃部分请求 + var cpuLimit = 85; + if (config.cpuLimit >= 0) { + cpuLimit = config.cpuLimit; + } - if (process.binding('config').exposeInternals) { - logger.info('overload protection working') - const RoundRobinHandle = require('internal/cluster/round_robin_handle'); - const distribute = RoundRobinHandle.prototype.distribute - if (!distribute.hasHack) { - RoundRobinHandle.prototype.distribute = function(err, handle) { - if (global.cpuUsed > cpuLimit) { - var rejectRate = Math.pow((global.cpuUsed - cpuLimit) / (100 - cpuLimit), 1.5) - if (Math.random() > rejectRate) { - handle.close() - tnm2.Attr_API('SUM_TSW_OVERLOAD_REJECT', 1); - return - } - } - distribute.call(this, err, handle) - } - distribute.hasHack = true - } - } + if (process.binding('config').exposeInternals) { + logger.info('overload protection working'); + const RoundRobinHandle = require('internal/cluster/round_robin_handle'); + const distribute = RoundRobinHandle.prototype.distribute; + if (!distribute.hasHack) { + RoundRobinHandle.prototype.distribute = function(err, handle) { + if (global.cpuUsed > cpuLimit) { + var rejectRate = Math.pow((global.cpuUsed - cpuLimit) / (100 - cpuLimit), 1.5); + if (Math.random() > rejectRate) { + handle.close(); + tnm2.Attr_API('SUM_TSW_OVERLOAD_REJECT', 1); + return; + } + } + distribute.call(this, err, handle); + }; + distribute.hasHack = true; + } + } -}) \ No newline at end of file +}); \ No newline at end of file diff --git a/bin/tsw/serverInfo.js b/bin/tsw/serverInfo.js index 83f16b1f..a23172bb 100644 --- a/bin/tsw/serverInfo.js +++ b/bin/tsw/serverInfo.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const os = require('os'); const {isWindows} = require('util/isWindows'); @@ -14,62 +14,59 @@ const isInnerIP = require('util/http.isInnerIP.js'); this.intranetIp = '127.0.0.1'; if(isWindows){ - this.intranetIp = getWinLocalIpv4(); + this.intranetIp = getWinLocalIpv4(); }else{ - this.intranetIp = getLinuxLocalIpv4(); + this.intranetIp = getLinuxLocalIpv4(); } function getLinuxLocalIpv4(){ - var intranetIp = ''; - var networkInterfaces = os.networkInterfaces(); + var intranetIp = ''; + var networkInterfaces = os.networkInterfaces(); - Object.keys(networkInterfaces).forEach(function(key){ - var eth = networkInterfaces[key]; - var address = eth && eth[0] && eth[0].address; + Object.keys(networkInterfaces).forEach(function(key){ + var eth = networkInterfaces[key]; + var address = eth && eth[0] && eth[0].address; - if(!address){ - return; - } + if(!address){ + return; + } - var tmp = isInnerIP.isInnerIP(address); - if(!tmp){ - return; - } + var tmp = isInnerIP.isInnerIP(address); + if(!tmp){ + return; + } - if(tmp === '127.0.0.1'){ - return; - } + if(tmp === '127.0.0.1'){ + return; + } - intranetIp = address; - }); + intranetIp = address; + }); - return intranetIp; + return intranetIp; } function getWinLocalIpv4(){ - var localNet = os.networkInterfaces(); - var key,item; - var k,v,i; - var userIp = null; + var localNet = os.networkInterfaces(); + var key,item; + var v,i; + var userIp = null; - for(key in localNet){ - item = localNet[key]; + for(key in localNet){ + item = localNet[key]; - if(String(key).indexOf('本地连接') > -1){ + if(String(key).indexOf('本地连接') > -1){ - for(i =0 ; i < item.length; i++){ - v = item[i]; - - if(v.family === 'IPv4'){ - userIp = v.address; - return userIp; - } - } - - } - - } + for(i =0 ; i < item.length; i++){ + v = item[i]; + if(v.family === 'IPv4'){ + userIp = v.address; + return userIp; + } + } + } + } } diff --git a/bin/tsw/util/CD.js b/bin/tsw/util/CD.js index 66a8a808..e20d1fe0 100644 --- a/bin/tsw/util/CD.js +++ b/bin/tsw/util/CD.js @@ -5,15 +5,12 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const url = require('url'); -const cmem = require('pool/cmem.l5.js'); const Deferred = require('util/Deferred'); const config = require('config'); -const dcapi = require('api/libdcapi/dcapi.js'); const logger = require('logger'); -const {isWindows} = require('util/isWindows.js'); const cmemTSW = require('data/cmem.tsw.js'); const tnm2 = require('api/tnm2'); const gzipHttp = require('util/gzipHttp.js'); @@ -25,285 +22,281 @@ var cacheStart = Date.now(); var cache = {}; if(global[__filename]){ - cache = global[__filename]; + cache = global[__filename]; }else{ - global[__filename] = cache; + global[__filename] = cache; } this.check = function(key,count,second){ - //请求openapi - if(config.appid && config.appkey && config.utilCDUrl){ - return checkByOpenapi(key,count,second); - } + //请求openapi + if(config.appid && config.appkey && config.utilCDUrl){ + return checkByOpenapi(key,count,second); + } - return checkByCmem(key,count,second); -} + return checkByCmem(key,count,second); +}; var checkByOpenapi = function(keyOri,count,second){ - var defer = Deferred.create(); - var appid = context.appid || null; - - var key = 'CD3.' + crypto.createHash('sha1').update(`CD3.${appid}.${keyOri}.${count}.${second}`).digest('hex'); - var start = Date.now(); - - if(cache[key]){ - if(start - cache[key] < second * 1000){ - logger.debug('miss mem ${key}',{ - key: key - }); - - return defer.reject(); - } - } - - //清缓存逻辑 - if(start - cacheStart > cacheTime){ - cache = {}; - cacheStart = Date.now(); - } - - - defer.fail(function(value){ - //设置缓存 - cache[key] = start; - }); - - var postData = { - appid: config.appid, - key: key, - count: count, - second: second, - now: Date.now() - }; - - if(!config.utilCDUrl){ - return defer.reject(); - } - - var sig = openapi.signature({ - pathname: url.parse(config.utilCDUrl).pathname, - method: 'POST', - data: postData, - appkey: config.appkey - }); - - postData.sig = sig; - - require('ajax').request({ - url : config.utilCDUrl, - type : 'POST', - l5api : config.tswL5api['openapi.tswjs.org'], - dcapi : { - key: 'EVENT_TSW_OPENAPI_UTIL_CD' - }, - data : postData, - keepAlive : true, - autoToken : false, - dataType : 'json' - }).fail(function(){ - logger.error('checkByOpenapi fail.'); - defer.reject(); - }).done(function(d){ - var data = null; - if(d.result && d.result.code === 0){ - data = d.result.data; - } - - if(data > 0){ - return defer.resolve(data); - } - - logger.debug('checkByOpenapi success.'); - return defer.reject(); - }); - - return defer; -} + var defer = Deferred.create(); + var appid = context.appid || null; + + var key = 'CD3.' + crypto.createHash('sha1').update(`CD3.${appid}.${keyOri}.${count}.${second}`).digest('hex'); + var start = Date.now(); + + if(cache[key]){ + if(start - cache[key] < second * 1000){ + logger.debug('miss mem ${key}',{ + key: key + }); + + return defer.reject(); + } + } + + //清缓存逻辑 + if(start - cacheStart > cacheTime){ + cache = {}; + cacheStart = Date.now(); + } + + + defer.fail(function(value){ + //设置缓存 + cache[key] = start; + }); + + var postData = { + appid: config.appid, + key: key, + count: count, + second: second, + now: Date.now() + }; + + if(!config.utilCDUrl){ + return defer.reject(); + } + + var sig = openapi.signature({ + pathname: url.parse(config.utilCDUrl).pathname, + method: 'POST', + data: postData, + appkey: config.appkey + }); + + postData.sig = sig; + + require('ajax').request({ + url : config.utilCDUrl, + type : 'POST', + l5api : config.tswL5api['openapi.tswjs.org'], + dcapi : { + key: 'EVENT_TSW_OPENAPI_UTIL_CD' + }, + data : postData, + keepAlive : true, + autoToken : false, + dataType : 'json' + }).fail(function(){ + logger.error('checkByOpenapi fail.'); + defer.reject(); + }).done(function(d){ + var data = null; + if(d.result && d.result.code === 0){ + data = d.result.data; + } + + if(data > 0){ + return defer.resolve(data); + } + + logger.debug('checkByOpenapi success.'); + return defer.reject(); + }); + + return defer; +}; this.curr = function(keyOri,count,second){ - var defer = Deferred.create(); - var appid = context.appid || null; + var defer = Deferred.create(); + var appid = context.appid || null; - var key = 'CD3.' + crypto.createHash('sha1').update(`CD3.${appid}.${keyOri}.${count}.${second}`).digest('hex'); + var key = 'CD3.' + crypto.createHash('sha1').update(`CD3.${appid}.${keyOri}.${count}.${second}`).digest('hex'); - var memcached = module.exports.cmem(); + var memcached = module.exports.cmem(); - if(!memcached){ - return defer.reject(); - } + if(!memcached){ + return defer.reject(); + } - memcached.get(key,function(err, result){ + memcached.get(key,function(err, result){ - var now = new Date().getTime(); + if(err){ + return defer.reject(); + } - if(err){ - return defer.reject(); - } + return defer.resolve(result); + }); - return defer.resolve(result); - }); - - return defer; -} + return defer; +}; var checkByCmem = function(keyOri,count,second){ - var defer = Deferred.create(); - var appid = context.appid || null; - - var key = 'CD3.' + crypto.createHash('sha1').update(`CD3.${appid}.${keyOri}.${count}.${second}`).digest('hex'); - var start = Date.now(); + var defer = Deferred.create(); + var appid = context.appid || null; - if(cache[key]){ - if(start - cache[key] < second * 1000){ - logger.debug('miss mem ${key}',{ - key: key - }); + var key = 'CD3.' + crypto.createHash('sha1').update(`CD3.${appid}.${keyOri}.${count}.${second}`).digest('hex'); + var start = Date.now(); - return defer.reject(); - } - } + if(cache[key]){ + if(start - cache[key] < second * 1000){ + logger.debug('miss mem ${key}',{ + key: key + }); - //清缓存逻辑 - if(start - cacheStart > cacheTime){ - cache = {}; - cacheStart = Date.now(); - } + return defer.reject(); + } + } - var memcached = module.exports.cmem(); + //清缓存逻辑 + if(start - cacheStart > cacheTime){ + cache = {}; + cacheStart = Date.now(); + } - if(!memcached){ - return defer.reject(); - } + var memcached = module.exports.cmem(); - defer.fail(function(value){ - //设置缓存 - cache[key] = start; - }); + if(!memcached){ + return defer.reject(); + } - defer.always(function(){ - tnm2.Attr_API('SUM_TSW_CD_CHECK', 1); - }); + defer.fail(function(value){ + //设置缓存 + cache[key] = start; + }); - memcached.add(key,1,second,function(err, result){ + defer.always(function(){ + tnm2.Attr_API('SUM_TSW_CD_CHECK', 1); + }); - var now = new Date().getTime(); + memcached.add(key,1,second,function(err, result){ - if(err){ - //add失败是正常的 - } + if(err){ + //add失败是正常的 + } - if(result === true){ - logger.debug(`add ${key} true`); - return defer.resolve(1); - } + if(result === true){ + logger.debug(`add ${key} true`); + return defer.resolve(1); + } - logger.debug(`add ${key} fail`); + logger.debug(`add ${key} fail`); - if(count <= 1){ - return defer.reject(); - } + if(count <= 1){ + return defer.reject(); + } - memcached.incr(key,1,function(err, result){ + memcached.incr(key,1,function(err, result){ - if(err){ - logger.error(err.satck); - return defer.reject(); - } + if(err){ + logger.error(err.satck); + return defer.reject(); + } - if(result <= count){ - logger.debug(`incr ${key} : ${result}`); - return defer.resolve(result); - }else{ - return defer.reject(result); - } - }); + if(result <= count){ + logger.debug(`incr ${key} : ${result}`); + return defer.resolve(result); + }else{ + return defer.reject(result); + } + }); - }); + }); - return defer; -} + return defer; +}; this.checkByCmem = checkByCmem; this.cmem = function(){ - if(context.appid && context.appkey){ - return cmemTSW.openapi(); - } - return cmemTSW.sz(); -} + if(context.appid && context.appkey){ + return cmemTSW.openapi(); + } + return cmemTSW.sz(); +}; //开放接口 this.openapi = async function(req,res){ - var appid = context.appid; - var appkey = context.appkey; + var appid = context.appid; + var appkey = context.appkey; - if(req.param('appid') !== appid){ - returnJson({ code: -2 , message: 'appid错误'}); - return; - } + if(req.param('appid') !== appid){ + returnJson({ code: -2 , message: 'appid错误'}); + return; + } - if(!appid){ - returnJson({ code: -2 , message: 'appid is required'}); - return; - } + if(!appid){ + returnJson({ code: -2 , message: 'appid is required'}); + return; + } - if(!appkey){ - returnJson({ code: -2 , message: 'appkey is required'}); - return; - } + if(!appkey){ + returnJson({ code: -2 , message: 'appkey is required'}); + return; + } - if(!/^[a-zA-Z0-9_\-]{0,50}$/.test(appid)){ - returnJson({ code: -2 , message: 'appid is required'}); - return; - } + if(!/^[a-zA-Z0-9_-]{0,50}$/.test(appid)){ + returnJson({ code: -2 , message: 'appid is required'}); + return; + } - logger.setKey(`CD_${appid}`); //上报key + logger.setKey(`CD_${appid}`); //上报key - var key = req.param('key'); - var second = ~~req.param('second'); //单位秒 - var count = ~~req.param('count'); //默认是1 + var key = req.param('key'); + var second = ~~req.param('second'); //单位秒 + var count = ~~req.param('count'); //默认是1 - if(!key){ - returnJson({ code: -2 , message: 'key is required'}); - return; - } + if(!key){ + returnJson({ code: -2 , message: 'key is required'}); + return; + } - if(!second){ - returnJson({ code: -2 , message: 'second is required'}); - return; - } + if(!second){ + returnJson({ code: -2 , message: 'second is required'}); + return; + } - if(second > 48 * 60 * 60){ - returnJson({ code: -2 , message: '不支持超过48h的second'}); - return; - } + if(second > 48 * 60 * 60){ + returnJson({ code: -2 , message: '不支持超过48h的second'}); + return; + } - if(key.length > 256){ - returnJson({ code: -2 , message: 'key.length超过了256'}); - return; - } + if(key.length > 256){ + returnJson({ code: -2 , message: 'key.length超过了256'}); + return; + } - var data = await checkByCmem(key,count,second).toES6Promise().catch(function(){ - return null; - }); + var data = await checkByCmem(key,count,second).toES6Promise().catch(function(){ + return null; + }); - var result = {code: 0,data: data}; + var result = {code: 0,data: data}; - returnJson(result); -} + returnJson(result); +}; var returnJson = function(json){ - var gzip = gzipHttp.create({ - contentType: 'application/json; charset=UTF-8', - code: 200 - }); - - gzip.write(JSON.stringify(json,null,2)); - gzip.end(); -} + var gzip = gzipHttp.create({ + contentType: 'application/json; charset=UTF-8', + code: 200 + }); + + gzip.write(JSON.stringify(json,null,2)); + gzip.end(); +}; diff --git a/bin/tsw/util/Deferred/index.js b/bin/tsw/util/Deferred/index.js index 173cb540..e1ab6f80 100644 --- a/bin/tsw/util/Deferred/index.js +++ b/bin/tsw/util/Deferred/index.js @@ -1,4 +1,4 @@ -"use strict"; +'use strict'; /** * @@ -10,205 +10,204 @@ // String to Object flags format cache var flagsCache = {}, - class2type = {}, -// Save a reference to some core methods - toString = Object.prototype.toString, - hasOwn = Object.prototype.hasOwnProperty, - push = Array.prototype.push, - slice = Array.prototype.slice, - trim = String.prototype.trim, - indexOf = Array.prototype.indexOf; + class2type = {}, + // Save a reference to some core methods + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty; // Convert String-formatted flags into Object-formatted ones and store in cache function createFlags( flags ) { - var object = flagsCache[ flags ] = {}, - i, length; - flags = flags.split( /\s+/ ); - for ( i = 0, length = flags.length; i < length; i++ ) { - object[ flags[i] ] = true; - } - return object; + var object = flagsCache[ flags ] = {}, + i, length; + flags = flags.split( /\s+/ ); + for ( i = 0, length = flags.length; i < length; i++ ) { + object[ flags[i] ] = true; + } + return object; } var jQuery = { - // See test/unit/core.js for details concerning isFunction. - // Since version 1.3, DOM methods and functions like alert - // aren't supported. They return false on IE (#2968). - isFunction: function( obj ) { - return jQuery.type(obj) === "function"; - }, - - isArray: Array.isArray || function( obj ) { - return jQuery.type(obj) === "array"; - }, - - // A crude way of determining if an object is a window - isWindow: function( obj ) { - return obj && typeof obj === "object" && "setInterval" in obj; - }, - - isNumeric: function( obj ) { - return !isNaN( parseFloat(obj) ) && isFinite( obj ); - }, - - type: function( obj ) { - return obj == null ? - String( obj ) : - class2type[ toString.call(obj) ] || "object"; - }, - - isPlainObject: function( obj ) { - // Must be an Object. - // Because of IE, we also have to check the presence of the constructor property. - // Make sure that DOM nodes and window objects don't pass through, as well - if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { - return false; - } - - try { - // Not own constructor property must be Object - if ( obj.constructor && - !hasOwn.call(obj, "constructor") && - !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { - return false; - } - } catch ( e ) { - // IE8,9 Will throw exceptions on certain host objects #9897 - return false; - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - - var key; - for ( key in obj ) {} - - return key === undefined || hasOwn.call( obj, key ); - }, - - isEmptyObject: function( obj ) { - for ( var name in obj ) { - return false; - } - return true; - }, - - error: function( msg ) { - throw new Error( msg ); - }, - - // args is for internal usage only - each: function( object, callback, args ) { - var name, i = 0, - length = object.length, - isObj = length === undefined || jQuery.isFunction( object ); - - if ( args ) { - if ( isObj ) { - for ( name in object ) { - if ( callback.apply( object[ name ], args ) === false ) { - break; - } - } - } else { - for ( ; i < length; ) { - if ( callback.apply( object[ i++ ], args ) === false ) { - break; - } - } - } - - // A special, fast, case for the most common use of each - } else { - if ( isObj ) { - for ( name in object ) { - if ( callback.call( object[ name ], name, object[ name ] ) === false ) { - break; - } - } - } else { - for ( ; i < length; ) { - if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { - break; - } - } - } - } - - return object; - } + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === 'function'; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === 'array'; + }, + + // A crude way of determining if an object is a window + isWindow: function( obj ) { + return obj && typeof obj === 'object' && 'setInterval' in obj; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ toString.call(obj) ] || 'object'; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== 'object' || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, 'constructor') && + !hasOwn.call(obj.constructor.prototype, 'isPrototypeOf') ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key, a; + + for (a in obj ) { + key = a; + } + + return key === undefined || hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + for ( var name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, + length = object.length, + isObj = length === undefined || jQuery.isFunction( object ); + + if ( args ) { + if ( isObj ) { + for ( name in object ) { + if ( callback.apply( object[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( object[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in object ) { + if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + break; + } + } + } + } + + return object; + } }; // Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); +jQuery.each('Boolean Number String Function Array Date RegExp Object'.split(' '), function(i, name) { + class2type[ '[object ' + name + ']' ] = name.toLowerCase(); }); jQuery.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction(target) ) { - target = {}; - } - - // extend jQuery itself if only one argument is passed - if ( length === i ) { - target = this; - --i; - } - - for ( ; i < length; i++ ) { - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { - if ( copyIsArray ) { - copyIsArray = false; - clone = src && jQuery.isArray(src) ? src : []; - - } else { - clone = src && jQuery.isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === 'boolean' ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== 'object' && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; }; /* @@ -235,377 +234,376 @@ jQuery.extend = function() { */ jQuery.Callbacks = function( flags ) { - // Convert flags from String-formatted to Object-formatted - // (we check in cache first) - flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; - - var // Actual callback list - list = [], - // Stack of fire calls for repeatable lists - stack = [], - // Last fire value (for non-forgettable lists) - memory, - // Flag to know if list is currently firing - firing, - // First callback to fire (used internally by add and fireWith) - firingStart, - // End of the loop when firing - firingLength, - // Index of currently firing callback (modified by remove if needed) - firingIndex, - // Add one or several callbacks to the list - add = function( args ) { - var i, - length, - elem, - type, - actual; - for ( i = 0, length = args.length; i < length; i++ ) { - elem = args[ i ]; - type = jQuery.type( elem ); - if ( type === "array" ) { - // Inspect recursively - add( elem ); - } else if ( type === "function" ) { - // Add if not in unique mode and callback is not in - if ( !flags.unique || !self.has( elem ) ) { - elem.__domain = process.domain; - list.push( elem ); - } - } - } - }, - // Fire callbacks - fire = function( context, args ) { + // Convert flags from String-formatted to Object-formatted + // (we check in cache first) + flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + + var // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = [], + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Add one or several callbacks to the list + add = function( args ) { + var i, + length, + elem, + type; + + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === 'array' ) { + // Inspect recursively + add( elem ); + } else if ( type === 'function' ) { + // Add if not in unique mode and callback is not in + if ( !flags.unique || !self.has( elem ) ) { + elem.__domain = process.domain; + list.push( elem ); + } + } + } + }, + // Fire callbacks + fire = function( context, args ) { - var fn,domain,ret; + var fn,domain,ret; - args = args || []; - memory = !flags.memory || [context, args]; - firing = true; - firingIndex = firingStart || 0; - firingStart = 0; - firingLength = list.length; - for (; list && firingIndex < firingLength; firingIndex++) { + args = args || []; + memory = !flags.memory || [context, args]; + firing = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + for (; list && firingIndex < firingLength; firingIndex++) { - fn = list[firingIndex]; - domain = fn.__domain; - fn.__domain = undefined; + fn = list[firingIndex]; + domain = fn.__domain; + fn.__domain = undefined; - // restore domain if needed + // restore domain if needed if (domain && domain !== process.domain) { - domain.run(function(){ - ret = fn.apply(context, args); - }); + domain.run(function(){ + ret = fn.apply(context, args); + }); }else { ret = fn.apply(context, args); } - if (ret === false && flags.stopOnFalse) { - memory = true; // Mark as halted - break; - } - } - firing = false; - if (list) { - if (!flags.once) { - if (stack && stack.length) { - memory = stack.shift(); - self.fireWith(memory[0], memory[1]); - } - } - else - if (memory === true) { - self.disable(); - } - else { - list = []; - } - } - }, - // Actual Callbacks object - self = { - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - var length = list.length; - add( arguments ); - // Do we need to add the callbacks to the - // current firing batch? - if ( firing ) { - firingLength = list.length; - // With memory, if we're not firing then - // we should call right away, unless previous - // firing was halted (stopOnFalse) - } else if ( memory && memory !== true ) { - firingStart = length; - fire( memory[ 0 ], memory[ 1 ] ); - } - } - return this; - }, - // Remove a callback from the list - remove: function() { - if ( list ) { - var args = arguments, - argIndex = 0, - argLength = args.length; - for ( ; argIndex < argLength ; argIndex++ ) { - for ( var i = 0; i < list.length; i++ ) { - if ( args[ argIndex ] === list[ i ] ) { - // Handle firingIndex and firingLength - if ( firing ) { - if ( i <= firingLength ) { - firingLength--; - if ( i <= firingIndex ) { - firingIndex--; - } - } - } - // Remove the element - list.splice( i--, 1 ); - // If we have some unicity property then - // we only need to do this once - if ( flags.unique ) { - break; - } - } - } - } - } - return this; - }, - // Control if a given callback is in the list - has: function( fn ) { - if ( list ) { - var i = 0, - length = list.length; - for ( ; i < length; i++ ) { - if ( fn === list[ i ] ) { - return true; - } - } - } - return false; - }, - // Remove all callbacks from the list - empty: function() { - list = []; - return this; - }, - // Have the list do nothing anymore - disable: function() { - list = stack = memory = undefined; - return this; - }, - // Is it disabled? - disabled: function() { - return !list; - }, - // Lock the list in its current state - lock: function() { - stack = undefined; - if ( !memory || memory === true ) { - self.disable(); - } - return this; - }, - // Is it locked? - locked: function() { - return !stack; - }, - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( stack ) { - if ( firing ) { - if ( !flags.once ) { - stack.push( [ context, args ] ); - } - } else if ( !( flags.once && memory ) ) { - fire( context, args ); - } - } - return this; - }, - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - // To know if the callbacks have already been called at least once - fired: function() { - return !!memory; - } - }; - - return self; + if (ret === false && flags.stopOnFalse) { + memory = true; // Mark as halted + break; + } + } + firing = false; + if (list) { + if (!flags.once) { + if (stack && stack.length) { + memory = stack.shift(); + self.fireWith(memory[0], memory[1]); + } + } + else + if (memory === true) { + self.disable(); + } + else { + list = []; + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + var length = list.length; + add( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away, unless previous + // firing was halted (stopOnFalse) + } else if ( memory && memory !== true ) { + firingStart = length; + fire( memory[ 0 ], memory[ 1 ] ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + var args = arguments, + argIndex = 0, + argLength = args.length; + for ( ; argIndex < argLength ; argIndex++ ) { + for ( var i = 0; i < list.length; i++ ) { + if ( args[ argIndex ] === list[ i ] ) { + // Handle firingIndex and firingLength + if ( firing ) { + if ( i <= firingLength ) { + firingLength--; + if ( i <= firingIndex ) { + firingIndex--; + } + } + } + // Remove the element + list.splice( i--, 1 ); + // If we have some unicity property then + // we only need to do this once + if ( flags.unique ) { + break; + } + } + } + } + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + if ( list ) { + var i = 0, + length = list.length; + for ( ; i < length; i++ ) { + if ( fn === list[ i ] ) { + return true; + } + } + } + return false; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory || memory === true ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( stack ) { + if ( firing ) { + if ( !flags.once ) { + stack.push( [ context, args ] ); + } + } else if ( !( flags.once && memory ) ) { + fire( context, args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!memory; + } + }; + + return self; }; var // Static reference to slice - sliceDeferred = [].slice; + sliceDeferred = [].slice; jQuery.extend({ - Deferred: function( func ) { - var doneList = jQuery.Callbacks( "once memory" ), - failList = jQuery.Callbacks( "once memory" ), - progressList = jQuery.Callbacks( "memory" ), - state = "pending", - lists = { - resolve: doneList, - reject: failList, - notify: progressList - }, - promise = { - done: doneList.add, - fail: failList.add, - progress: progressList.add, - - state: function() { - return state; - }, - - // Deprecated - isResolved: doneList.fired, - isRejected: failList.fired, - - then: function( doneCallbacks, failCallbacks, progressCallbacks ) { - deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); - return this; - }, - always: function() { - deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); - return this; - }, - - toES6Promise: function(){ - var self = this; - - return new Promise(function (resolve, reject){ - - self.done(function(d){ - resolve(d); - }); - - self.fail(function(d){ - reject(d); - }); - }); - }, - pipe: function( fnDone, fnFail, fnProgress ) { - return jQuery.Deferred(function( newDefer ) { - jQuery.each( { - done: [ fnDone, "resolve" ], - fail: [ fnFail, "reject" ], - progress: [ fnProgress, "notify" ] - }, function( handler, data ) { - var fn = data[ 0 ], - action = data[ 1 ], - returned; - if ( jQuery.isFunction( fn ) ) { - deferred[ handler ](function() { - returned = fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); - } else { - newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); - } - }); - } else { - deferred[ handler ]( newDefer[ action ] ); - } - }); - }).promise(); - }, - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - if ( obj == null ) { - obj = promise; - } else { - for ( var key in promise ) { - obj[ key ] = promise[ key ]; - } - } - return obj; - } - }, - deferred = promise.promise({}), - key; - - for ( key in lists ) { - deferred[ key ] = lists[ key ].fire; - deferred[ key + "With" ] = lists[ key ].fireWith; - } - - // Handle state - deferred.done( function() { - state = "resolved"; - }, failList.disable, progressList.lock ).fail( function() { - state = "rejected"; - }, doneList.disable, progressList.lock ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( firstParam ) { - var args = sliceDeferred.call( arguments, 0 ), - i = 0, - length = args.length, - pValues = new Array( length ), - count = length, - pCount = length, - deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? - firstParam : - jQuery.Deferred(), - promise = deferred.promise(); - function resolveFunc( i ) { - return function( value ) { - args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; - if ( !( --count ) ) { - deferred.resolveWith( deferred, args ); - } - }; - } - function progressFunc( i ) { - return function( value ) { - pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; - deferred.notifyWith( promise, pValues ); - }; - } - if ( length > 1 ) { - for ( ; i < length; i++ ) { - if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { - args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); - } else { - --count; - } - } - if ( !count ) { - deferred.resolveWith( deferred, args ); - } - } else if ( deferred !== firstParam ) { - deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); - } - return promise; - } + Deferred: function( func ) { + var doneList = jQuery.Callbacks( 'once memory' ), + failList = jQuery.Callbacks( 'once memory' ), + progressList = jQuery.Callbacks( 'memory' ), + state = 'pending', + lists = { + resolve: doneList, + reject: failList, + notify: progressList + }, + promise = { + done: doneList.add, + fail: failList.add, + progress: progressList.add, + + state: function() { + return state; + }, + + // Deprecated + isResolved: doneList.fired, + isRejected: failList.fired, + + then: function( doneCallbacks, failCallbacks, progressCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); + return this; + }, + always: function() { + deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); + return this; + }, + + toES6Promise: function(){ + var self = this; + + return new Promise(function (resolve, reject){ + + self.done(function(d){ + resolve(d); + }); + + self.fail(function(d){ + reject(d); + }); + }); + }, + pipe: function( fnDone, fnFail, fnProgress ) { + return jQuery.Deferred(function( newDefer ) { + jQuery.each( { + done: [ fnDone, 'resolve' ], + fail: [ fnFail, 'reject' ], + progress: [ fnProgress, 'notify' ] + }, function( handler, data ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( jQuery.isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); + } else { + newDefer[ action + 'With' ]( this === deferred ? newDefer : this, [ returned ] ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + obj = promise; + } else { + for ( var key in promise ) { + obj[ key ] = promise[ key ]; + } + } + return obj; + } + }, + deferred = promise.promise({}), + key; + + for ( key in lists ) { + deferred[ key ] = lists[ key ].fire; + deferred[ key + 'With' ] = lists[ key ].fireWith; + } + + // Handle state + deferred.done( function() { + state = 'resolved'; + }, failList.disable, progressList.lock ).fail( function() { + state = 'rejected'; + }, doneList.disable, progressList.lock ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( firstParam ) { + var args = sliceDeferred.call( arguments, 0 ), + i = 0, + length = args.length, + pValues = new Array( length ), + count = length, + deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? + firstParam : + jQuery.Deferred(), + promise = deferred.promise(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( deferred, args ); + } + }; + } + function progressFunc( i ) { + return function( value ) { + pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + deferred.notifyWith( promise, pValues ); + }; + } + if ( length > 1 ) { + for ( ; i < length; i++ ) { + if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return promise; + } }); module.exports = { - create: function(){ - return jQuery.Deferred(); - }, - when: jQuery.when, - extend: jQuery.extend -} + create: function(){ + return jQuery.Deferred(); + }, + when: jQuery.when, + extend: jQuery.extend +}; diff --git a/bin/tsw/util/Queue/index.js b/bin/tsw/util/Queue/index.js index c5d81c26..3305745c 100644 --- a/bin/tsw/util/Queue/index.js +++ b/bin/tsw/util/Queue/index.js @@ -5,70 +5,70 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; function Queue(){ - this._queue = []; + this._queue = []; } this.create = function(){ - return new Queue(); -} + return new Queue(); +}; Queue.prototype.queue = function(fn){ - if(typeof fn !== 'function'){ + if(typeof fn !== 'function'){ - return this; - } + return this; + } - fn._domain = process.domain; + fn._domain = process.domain; - this._queue.push(fn); + this._queue.push(fn); - if(this._queue.length === 1){ - this.dequeue(); - } + if(this._queue.length === 1){ + this.dequeue(); + } - return this; -} + return this; +}; Queue.prototype.dequeue = function(){ - var domain,that,fn; + var domain,that,fn; - if(this._queue.length <= 0){ - return this; - } + if(this._queue.length <= 0){ + return this; + } - if(this._queue[0] === 'ing'){ + if(this._queue[0] === 'ing'){ - this._queue.shift(); - this.dequeue(); + this._queue.shift(); + this.dequeue(); - return this; - } + return this; + } - fn = this._queue[0]; - this._queue[0] = 'ing'; + fn = this._queue[0]; + this._queue[0] = 'ing'; - domain = fn._domain; - that = this; - fn._domain = undefined; + domain = fn._domain; + that = this; + fn._domain = undefined; - if(domain && domain !== process.domain){ - domain.run(function(){ - fn.call(that); - }); - }else{ - fn.call(this); - } + if(domain && domain !== process.domain){ + domain.run(function(){ + fn.call(that); + }); + }else{ + fn.call(this); + } - return this; -} + return this; +}; diff --git a/bin/tsw/util/alpha.js b/bin/tsw/util/alpha.js index 50ca2aa4..bb41e645 100644 --- a/bin/tsw/util/alpha.js +++ b/bin/tsw/util/alpha.js @@ -5,6 +5,6 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; module.exports = require('./auto-report/alpha.js'); diff --git a/bin/tsw/util/auto-report/.eslintrc.json b/bin/tsw/util/auto-report/.eslintrc.json new file mode 100644 index 00000000..0e4b665b --- /dev/null +++ b/bin/tsw/util/auto-report/.eslintrc.json @@ -0,0 +1,11 @@ +{ + "rules": { + "no-unused-vars": [ + "error", + { + "varsIgnorePattern": "out", + "args": "none" + } + ] + } +} \ No newline at end of file diff --git a/bin/tsw/util/auto-report/TEReport.js b/bin/tsw/util/auto-report/TEReport.js index 783263fe..bc59a943 100644 --- a/bin/tsw/util/auto-report/TEReport.js +++ b/bin/tsw/util/auto-report/TEReport.js @@ -5,177 +5,172 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; /** * 测试环境自动发现 */ -const fs = require('fs'); -const logger = require('logger'); const serverInfo = require('serverInfo'); const config = require('config'); const logReport = require('./logReport.js'); const post = require('util/auto-report/post.js'); const postOpenapi = require('util/auto-report/post.openapi.js'); const Deferred = require('util/Deferred'); -const gzipHttp = require('util/gzipHttp.js'); const isWindows = require('util/isWindows.js'); -const ajax = require('ajax'); this.report = function(){ - if(isWindows.isWindows){ - return; - } - - if(!config.isTest){ - return; - } - - var logText = `${serverInfo.intranetIp}:${config.httpPort}`; - var logJson = { - ip : serverInfo.intranetIp, - port : config.httpPort - }; - var logKey = ''; - - require('api/cmdb').GetDeviceThisServer().done(function(d){ - - var business; - - if(d && d.business){ - business = d.business[0]; - } - - if(!business){ - business = { - moduleId: 0, - L1Business: '未知', - L2Business: '未知', - L3Business: '未知', - module: '未知' - }; - } - - logJson.moduleId = business.moduleId; - logJson.moduleName = [business.L1Business,business.L2Business,business.L3Business,business.module].join('->'); - - logJson = Deferred.extend(true,{ - time : new Date().toGMTString(), - name : '', - group : 'unknown', - desc : '', - order : 0, - owner : '' - },config.testInfo,logJson); - - var logKey = 'h5test' + logJson.group; - - //上报自己 - post.report(logKey,logText,logJson); - - //开放平台上报,不用再分组了 - if(config.appid && config.appkey){ - logReport.reportCloud({ - type : 'alpha', - logText : logText, - logJson : logJson, - key : 'h5test', - group : 'tsw', - mod_act : 'h5test', - ua : '', - userip : '', - host : '', - pathname : '', - statusCode : '' - }); - } - - //上报分组 - require('util/CD.js').check('h5test' + logJson.group,1,60).done(function(){ - post.report('group.h5test',logText,logJson); - }); - - }); + if(isWindows.isWindows){ + return; + } + + if(!config.isTest){ + return; + } + + var logText = `${serverInfo.intranetIp}:${config.httpPort}`; + var logJson = { + ip : serverInfo.intranetIp, + port : config.httpPort + }; + + require('api/cmdb').GetDeviceThisServer().done(function(d){ + + var business; + + if(d && d.business){ + business = d.business[0]; + } + + if(!business){ + business = { + moduleId: 0, + L1Business: '未知', + L2Business: '未知', + L3Business: '未知', + module: '未知' + }; + } + + logJson.moduleId = business.moduleId; + logJson.moduleName = [business.L1Business,business.L2Business,business.L3Business,business.module].join('->'); + + logJson = Deferred.extend(true,{ + time : new Date().toGMTString(), + name : '', + group : 'unknown', + desc : '', + order : 0, + owner : '' + },config.testInfo,logJson); + + var logKey = 'h5test' + logJson.group; + + //上报自己 + post.report(logKey,logText,logJson); + + //开放平台上报,不用再分组了 + if(config.appid && config.appkey){ + logReport.reportCloud({ + type : 'alpha', + logText : logText, + logJson : logJson, + key : 'h5test', + group : 'tsw', + mod_act : 'h5test', + ua : '', + userip : '', + host : '', + pathname : '', + statusCode : '' + }); + } + + //上报分组 + require('util/CD.js').check('h5test' + logJson.group,1,60).done(function(){ + post.report('group.h5test',logText,logJson); + }); + + }); -} +}; this.list = function(group){ - var defer = Deferred.create(); - var getLogJsonDefer; + var defer = Deferred.create(); + var getLogJsonDefer; - group = group || ''; + group = group || ''; - //开平对应的存储 - if(context.appid && context.appkey){ - getLogJsonDefer = postOpenapi.getLogJson(`${context.appid}/tsw/h5test`); - }else{ - getLogJsonDefer = post.getLogJson(`h5test${group}`); - } + //开平对应的存储 + if(context.appid && context.appkey){ + getLogJsonDefer = postOpenapi.getLogJson(`${context.appid}/tsw/h5test`); + }else{ + getLogJsonDefer = post.getLogJson(`h5test${group}`); + } - getLogJsonDefer.done(function(arr){ + getLogJsonDefer.done(function(arr){ - var res = []; - var map = {}; + var res = []; + var map = {}; - arr.forEach(function(v){ - if(!map[v.ip]){ - map[v.ip] = true; - res.push(v); - } - }); - - //增加一个临时染色 - res.push({ - time: new Date(), - name: "临时染色", - group: "TSW", - desc: "人在家中坐,包从天上来", - order: -65536, - //owner: "TSW", - groupName: group, - ip: "alpha", - moduleId: 0, - moduleName: "null" - }); - - res.sort(function(a,b){ - return a.order - b.order; - }); - - defer.resolve(res); - }); + arr.forEach(function(v){ + if(!map[v.ip]){ + map[v.ip] = true; + res.push(v); + } + }); + + //增加一个临时染色 + res.push({ + time: new Date(), + name: '临时染色', + group: 'TSW', + desc: '人在家中坐,包从天上来', + order: -65536, + //owner: "TSW", + groupName: group, + ip: 'alpha', + moduleId: 0, + moduleName: 'null' + }); + + res.sort(function(a,b){ + return a.order - b.order; + }); + + defer.resolve(res); + }); - return defer; -} + return defer; +}; this.getAllGroup = function(){ - var defer = Deferred.create(); + var defer = Deferred.create(); - post.getLogJson('group.h5test').done(function(arr){ + post.getLogJson('group.h5test').done(function(arr){ - var res = []; - var map = {}; + var res = []; + var map = {}; - arr.forEach(function(v){ - if(!map[v.group]){ - map[v.group] = true; - res.push(v); - } - }); + arr.forEach(function(v){ + if(!map[v.group]){ + map[v.group] = true; + res.push(v); + } + }); - res.sort(function(a,b){ - return a.order - b.order; - }); + res.sort(function(a,b){ + return a.order - b.order; + }); - defer.resolve(res); - }); + defer.resolve(res); + }); - return defer; -} + return defer; +}; diff --git a/bin/tsw/util/auto-report/alpha.js b/bin/tsw/util/auto-report/alpha.js index fc334676..34dcce74 100644 --- a/bin/tsw/util/auto-report/alpha.js +++ b/bin/tsw/util/auto-report/alpha.js @@ -5,9 +5,8 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; -const fs = require('fs'); const config = require('config'); const logger = require('logger'); const {isWindows} = require('util/isWindows'); @@ -23,7 +22,7 @@ this.update = function(map){ this.add = function(uin){ // -} +}; this.isAlpha = function(req){ @@ -60,7 +59,7 @@ this.isAlpha = function(req){ var uinMap = global[__filename] || {}; return uinMap[uin] || TSW.getAlphaUinMapSync()[uin]; -} +}; this.getUin = function(req){ @@ -79,4 +78,4 @@ this.getUin = function(req){ } return uin; -} +}; diff --git a/bin/tsw/util/auto-report/download.js b/bin/tsw/util/auto-report/download.js index dad1962f..6023365f 100644 --- a/bin/tsw/util/auto-report/download.js +++ b/bin/tsw/util/auto-report/download.js @@ -1,634 +1,619 @@ -/*! - * Tencent is pleased to support the open source community by making Tencent Server Web available. - * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. - * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - * http://opensource.org/licenses/MIT - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ -"use strict"; - -const logger = require('logger'); -const dcapi = require('api/libdcapi/dcapi.js'); -const serverInfo = require('serverInfo'); -const gzipHttp = require('util/gzipHttp.js'); -const httpUtil = require('util/http'); -const Archiver = require('archiver'); -const OALogin = require('util/oa-login/index.js'); -const tmpl = require('./tmpl'); -const post = require('./post'); -const postOpenapi = require('./post.openapi.js'); -const canIuse = /^[0-9a-zA-Z_\-]{0,64}$/; -const Deferred = require('util/Deferred'); -const zlib = require('zlib'); -const MAX_ALPHA_LOG = post.MAX_ALPHA_LOG; - - -module.exports = function(request, response){ - OALogin.checkLoginForTSW(request,response,function(){ - module.exports.go(request,response); - }); -} - -module.exports.go = function(request, response){ - - var arr = request.REQUEST.pathname.split('/'); - var appid = context.appid || ''; - var group = arr[3]; - var key = arr[4]; - var groupKey = 'v2.group.alpha'; - var limit = ~~context.limit || 64; - var currPost = post; - - - var flagOfDownloadFileFormat = request.query.fileFormat; - - if(appid){ - currPost = postOpenapi; - groupKey = `${appid}/v2.group.alpha`; - } - - if(!key){ - key = group; - group = ''; - } - - if(!canIuse.test(appid)){ - return returnError('appid格式非法'); - } - - if(!canIuse.test(group)){ - return returnError('group格式非法'); - } - - if(!canIuse.test(key)){ - return returnError('key格式非法'); - } - - var createLogKey = function(appid,group,key){ - var logKey = key; - - if(group){ - logKey = `${group}/${logKey}`; - } - - return logKey; - }; - - var logKey = createLogKey(appid,group,key); - - if(appid){ - logKey = `${appid}/${logKey}`; - } - - //上下文设置 - context.group = group; - context.limit = limit; - context.key = key; - context.groupKey = groupKey; - context.logKey = logKey; - context.createLogKey = createLogKey; - - var logCount = 0; - var logKeyCount = 0; - var logNumMax = context.MAX_ALPHA_LOG || MAX_ALPHA_LOG; - - logger.debug('logKey :${logKey}',{ - logKey: logKey - }); - - //下标。 - var index = parseInt(request.GET.index,10); - - key = logKey + '.' + index; - - if(index >= 0){ - if(flagOfDownloadFileFormat === 'har'){ - currPost.getLogJsonByKey(logKey,key).done(function(data){ - downloadHaz(request, response, { - id: logKey + data['SNKeys'][0], - data: data - }); - }); - }else { - currPost.getLogJsonByKey(logKey,key).done(function(data){ - download(request, response, { - id: logKey + data['SNKeys'][0], - data: data - }); - }); - } - - }else{ - //点击下载全部 - if(flagOfDownloadFileFormat === 'har'){ - currPost.getLogJson(logKey).done(function(data){ - downloadHaz(request, response, { - id: logKey, - data: data - }); - }); - }else { - currPost.getLogJson(logKey).done(function(data){ - download(request, response, { - id: logKey, - data: data - }); - }); - } - - } -}; - - -function returnError(message){ - var window = context.window; - var gzipResponse = gzipHttp.getGzipResponse({ - request: window.request, - response: window.response, - code: 200, - contentType: 'text/html; charset=UTF-8' - }); - - gzipResponse.end(message); -} - - -//curr -var initRequestHar = function (request) { - var unpackRaw = function (requestRaw) { - var requestArr = []; - // 补全没有的数据 - var request = { - cookie:'', - headers:[], - postData:{}, - queryString:[], - cache:{}, - timings:{} - }; - if(requestRaw){ - requestArr = requestRaw.split(/\r\n/g); - if(requestArr.length > 0 ){ - - requestArr.forEach(function (item,index) { - - item = item.trim(); - if(item!=='' && item.length !== 0){ - // 第一行,请求头:GET url;回包:HTTP/1.1 200 OK - if(index === 0){ - var firstItem = item.split(' '); - // 请求头:GET url; - if(firstItem.length === 3){ - request.protocol = firstItem[2]; - }else{ - request.protocol = firstItem[1]; - } - request.method = firstItem[0]; - - }else{ - item = item.split(':') || []; - if(item.length === 2 ){ - request[item[0]] = item[1].trim(); - request.headers.push({ - name:item[0], - value:item[1] - }); - } - } - } - }); - if(request.method && request.method === 'POST'){ - var postDataArr = requestArr[requestArr.length - 1]; - request.postData.mimeType = "multipart/form-data"; - request.postData.text = postDataArr; - } - - - } - } - // 补齐cookie - if(request.cookie){ - var cookieArray = request.cookie.split(';'); - if(cookieArray.length > 0){ - request.cookieArray = []; - cookieArray.forEach(function (item) { - item = item.split('=') || []; - request.cookieArray.push({ - name:item[0], - value:item[1] - }); - }) - } - } - // 补齐query - if(request.path && request.path.indexOf('?') !== -1){ - var query = request.path.slice(request.path.indexOf('?') + 1); - if(query){ - query = query.split('&');// re=va - query.forEach(function (item) { - item = item.split('='); - request.queryString.push({ - name:item[0], - value:item[1], - }); - }); - } - } - - return request; - }; - var getUrl = function (curr) { - var url; - var host; - if(curr){ - host = String(curr.host); - url = String(curr.url); - // 不包括host,特殊处理下 - if(url && host && url.indexOf(host) === -1){ - url = 'https://'+ host + url; - } - } - return url - } - var - requestHaz = {}, - requestHeader, - responseHeader, - response; - - requestHeader = unpackRaw((Buffer.from(request.requestRaw ||'')).toString('utf8')); - responseHeader = unpackRaw((Buffer.from(request.responseHeader || '')).toString('utf8')); - - - - requestHaz.startedDateTime = request.timestamps.ClientConnected; - requestHaz.time = 3000; - - requestHaz.request = { - "method":requestHeader.method, - "url":getUrl(request), - "httpVersion": requestHeader.protocol, - "cookies": requestHeader.cookieArray, - "headers": requestHeader.headers, - "queryString" : requestHeader.queryString, - "postData" : requestHeader.postData, - "headersSize" : request.requestRaw.replace(/\n/g,'').length, - "bodySize" : requestHeader['Content-Length'] || 0, - }; - - // console.error(request.responseBody,'request.responseBody'); - // 处理responseBody 的格式,由base64 转到 utf-8 ; - // var requestResponseBodyBase64 = request.responseBody || 0; - // if(response.headers['content-encoding'] === 'gzip'){ - // - // } - // zlib.unzip(requestResponseBodyBase64, function(err, buffer) { - // console.log(buffer.toString()) - // }); - - var mimeTypeTemp = responseHeader['Content-Type'] ; - var mimeType= (typeof mimeTypeTemp === 'undefined')? responseHeader['content-type']: mimeTypeTemp ; - mimeType = (typeof mimeType=== 'undefined') ? mimeType : mimeType.trim(); - - requestHaz.response = { - 'Content-Type':'text/html; charset=UTF-8', - "status": parseInt(request.resultCode)||0, - "statusText": "OK", - "httpVersion": responseHeader.protocol, - "cookies": responseHeader.cookieArray, - "headers": responseHeader.headers, - "redirectURL": '', - "headersSize" : requestHeader['Content-Length'] || 0, - "bodySize" : request.contentLength || 0, - "comment" : "", - "content":{ - "mimeType":mimeType, - // "compression":request.responseBody.length - (request.contentLength || 0), - // "text":request.responseBody, - // "text": (Buffer.from(request.responseBody || '', 'base64')).toString('utf8'), - // "encoding":'base64', - } - }; - - requestHaz.serverIPAddress = request.serverIp; - requestHaz.pageref = request.sid; - requestHaz.timings = { - "blocked": 0, - "dns": request.timestamps.dns, - "connect": request.timestamps.TCPConnectTime, - "send": 20, - "wait": 38, - "receive": 12, - "ssl": -1, - "comment": "" - }; - - if(typeof request.responseBody !== 'undefined' && request.responseBody.length !== 0 ){ - requestHaz.response.content.size = request.responseBody.length; - var requestResponseBodyBaseBuffer = (Buffer.from(request.responseBody || '', 'base64')); - - // chunked decode - if(typeof responseHeader['Transfer-Encoding'] !== 'undefined' && responseHeader['Transfer-Encoding'] === 'chunked'){ - requestResponseBodyBaseBuffer = decodeChunkedUint8Array(requestResponseBodyBaseBuffer); - } - - // console.error(requestResponseBodyBaseBuffer.length,'requestResponseBodyBaseBuffer'); - - if(typeof responseHeader['Content-Encoding'] !== 'undefined' && responseHeader['Content-Encoding'] === 'gzip'){ - try { - var ungziprawText = zlib.gunzipSync(requestResponseBodyBaseBuffer); - requestHaz.response.content.text = ungziprawText.toString('utf8');// 暂时文件 - } catch (e) { - requestHaz.response.content.text = requestResponseBodyBaseBuffer;// 暂时文件 - } finally { - - } - - return requestHaz; - }else{ - requestHaz.response.content.text = requestResponseBodyBaseBuffer.toString('utf8'); - - return requestHaz; - } - - }else{ - requestHaz.response.content.size =0; - requestHaz.response.content.text = ''; - return requestHaz; - } - -}; - -var downloadHaz = function (request, response, opt) { - opt = opt || {}; - - var data = opt.data || [], - viewData = [], - filename = opt.id || 'log', - index = parseInt(request.GET.index,10), - SNKey = request.GET.SNKey, - tmp - ; - var hazJson = { - "log":{ - "version": "1.2", - "creator": { - "name": "TSW", - "version": "1.0" - }, - "entries":[] - } - }; - - if(data.length <= 0){ - failRet(request, response, 'not find log'); - - return; - } - - if(SNKey && data.SNKeys && data.SNKeys[0] != SNKey){ - failRet(request, response, '该log已经过期,请联系用户慢点刷log~'); - - return; - } - - if(typeof data == 'string'){ - failRet(request, response, 'key类型不对'); - - return; - } - - response.setHeader('Content-disposition', 'attachment; filename=' + filename + '.har'); - var gzipResponse = gzipHttp.getGzipResponse({ - request: request, - response: response, - plug: plug, - code: 200, - contentType: 'application/octet-stream' - }); - - if(SNKey){ - //override index - index = 0; - } - - if(index >= 0){ - data = [data[index]]; - }else{ - data = data.reverse(); - } - data.forEach(function (tmp,i) { - if(tmp.curr){ - viewData.push(tmp.curr); - } - - tmp.ajax && - tmp.ajax.forEach(function(ajax,i){ - if(!ajax.SN){ - return; - } - viewData.push(ajax); - }); - }); - - viewData.forEach(function(tmp,i){ - - hazJson.log.entries.push(initRequestHar(tmp)); - - - }); - var buf = Buffer.from(JSON.stringify(hazJson),'UTF-8'); - gzipResponse.write(buf); - gzipResponse.end(); -}; - -var download = function(request, response, opt){ - opt = opt || {}; - - var data = opt.data || [], - viewData = [], - filename = opt.id || 'log', - index = parseInt(request.GET.index,10), - SNKey = request.GET.SNKey, - tmp - ; - - if(data.length <= 0){ - failRet(request, response, 'not find log'); - - return; - } - - if(SNKey && data.SNKeys && data.SNKeys[0] != SNKey){ - failRet(request, response, '该log已经过期,请联系用户慢点刷log~'); - - return; - } - - //data = data[0]; - - if(typeof data == 'string'){ - failRet(request, response, 'key类型不对'); - - return; - } - - filename = filename.replace(/[^a-zA-Z0-9_\.\-]/g,'_'); - - response.setHeader('Content-disposition', 'attachment; filename=' + filename + '.saz'); - - var gzipResponse = gzipHttp.getGzipResponse({ - request: request, - response: response, - plug: plug, - code: 200, - contentType: 'application/octet-stream' - }); - - if(SNKey){ - //override index - index = 0; - } - - if(index >= 0){ - data = [data[index]]; - }else{ - data = data.reverse(); - } - - var archiver = new Archiver('zip'); - - archiver.append(tmpl.download_index(data), {name: '_index.htm'}); - archiver.append(tmpl.download_content_types(), {name: '[Content_Types].xml'}); - - data.forEach(function(tmp,i){ - var sid = ('0000' + (i + 1)).slice(-3); - tmp.curr = tmp.curr || {}; - tmp.curr.sid = sid + '.0000'; - - - tmp.curr.logText = tmp.curr.logText || ''; - tmp.curr.logText = tmp.curr.logText.replace(/\r\n|\r|\n/gm,'\r\n'); - var logSNKey = post.getLogSN(tmp.curr.logText); - - var log = { - curr: { - sid : sid, - - protocol : 'HTTP', - host : '', - url : '', - cache : '', - process : tmp.curr.process, - resultCode : '200', - contentLength : Buffer.byteLength(tmp.curr.responseBody || '','UTF-8'), - contentType : 'text/plain', - clientIp : '', - clientPort : '', - serverIp : '', - serverPort : '', - requestRaw : 'GET log/'+logSNKey+' HTTP/1.1\r\n\r\n', - responseHeader : 'HTTP/1.1 200 OK\r\nContent-Type: text/plain; charset=UTF-8\r\nConnection: close\r\n\r\n', - responseBody : Buffer.from(tmp.curr.logText || '','UTF-8').toString('base64'), - timestamps : tmp.curr.timestamps - } - }; - - viewData.push(tmp); - viewData.push(log); - - tmp.ajax && - tmp.ajax.forEach(function(curr,i){ - - var ajax = {}; - - if(!curr.SN){ - return; - } - - ajax.curr = curr; - - curr.sid = sid + '.' + (`0000${curr.SN}`.slice(-3)); - - viewData.push(ajax); - }); - }); - - viewData.forEach(function(tmp,i){ - archiver.append( - tmp.curr.requestRaw || '', - { - name: 'raw/' + (tmp.curr.sid) + '_c.txt' - } - ); - archiver.append( - tmpl.download_timestamp(tmp.curr), - { - name: 'raw/' + (tmp.curr.sid) + '_m.xml' - } - ); - archiver.append( - Buffer.concat([ - Buffer.from(tmp.curr.responseHeader || '','utf-8'), - Buffer.from(tmp.curr.responseBody || '', 'base64') - ]), - { - name: 'raw/' + (tmp.curr.sid) + '_s.txt' - } - ); - }); - - // archiver.pipe(gzipResponse); - - archiver.on('error', function(e){ - logger.error('archive log error \n' + e.message); - }); - - archiver.on('data', function(buffer){ - gzipResponse.write(buffer); - }); - - archiver.once('end', function(){ - gzipResponse.end(); - }); - - archiver.finalize(); -}; - -var failRet = function(request, response, msg){ - var gzipResponse = gzipHttp.getGzipResponse({ - request: request, - response: response, - plug: plug, - code: 200, - contentType: 'text/html; charset=UTF-8' - }); - - gzipResponse.end(msg || ''); -}; - - - -// chunked decode buffer , 格式 :size +\r\n + rawText +\r\n + 0|r\n , \r\n ====》 13,10, 中间的即为rawText - -var decodeChunkedUint8Array = function (Uint8ArrayBuffer) { - var rawText = []; - var startOfTheRawText = Uint8ArrayBuffer.indexOf(13); - while( startOfTheRawText !== -1 && startOfTheRawText !== 0 ){ - var rawTextSizeUint8ArrayBuffer = Uint8ArrayBuffer.slice(0 ,startOfTheRawText); - var rawTextSizeUint8ArrayInt = parseInt(Buffer.from(rawTextSizeUint8ArrayBuffer),16); - if(rawTextSizeUint8ArrayInt === 0 ){ - break; - } - var chunkedText = Uint8ArrayBuffer.slice(startOfTheRawText+2, startOfTheRawText+2 +rawTextSizeUint8ArrayInt ); - rawText.push(Buffer.from(chunkedText)); - Uint8ArrayBuffer = Uint8ArrayBuffer.slice(startOfTheRawText+2 +rawTextSizeUint8ArrayInt+2); - startOfTheRawText = Uint8ArrayBuffer.indexOf(13); - console.log(startOfTheRawText,'startOfTheRawText'); - } - var bufferText = new Uint8Array( 0 ); - for(var ji=0; ji= 0){ + if(flagOfDownloadFileFormat === 'har'){ + currPost.getLogJsonByKey(logKey,key).done(function(data){ + downloadHaz(request, response, { + id: logKey + data['SNKeys'][0], + data: data + }); + }); + }else { + currPost.getLogJsonByKey(logKey,key).done(function(data){ + download(request, response, { + id: logKey + data['SNKeys'][0], + data: data + }); + }); + } + + }else{ + //点击下载全部 + if(flagOfDownloadFileFormat === 'har'){ + currPost.getLogJson(logKey).done(function(data){ + downloadHaz(request, response, { + id: logKey, + data: data + }); + }); + }else { + currPost.getLogJson(logKey).done(function(data){ + download(request, response, { + id: logKey, + data: data + }); + }); + } + + } +}; + + +function returnError(message){ + var window = context.window; + var gzipResponse = gzipHttp.getGzipResponse({ + request: window.request, + response: window.response, + code: 200, + contentType: 'text/html; charset=UTF-8' + }); + + gzipResponse.end(message); +} + + +//curr +var initRequestHar = function (request) { + var unpackRaw = function (requestRaw) { + var requestArr = []; + // 补全没有的数据 + var request = { + cookie:'', + headers:[], + postData:{}, + queryString:[], + cache:{}, + timings:{} + }; + if(requestRaw){ + requestArr = requestRaw.split(/\r\n/g); + if(requestArr.length > 0 ){ + + requestArr.forEach(function (item,index) { + + item = item.trim(); + if(item!=='' && item.length !== 0){ + // 第一行,请求头:GET url;回包:HTTP/1.1 200 OK + if(index === 0){ + var firstItem = item.split(' '); + // 请求头:GET url; + if(firstItem.length === 3){ + request.protocol = firstItem[2]; + }else{ + request.protocol = firstItem[1]; + } + request.method = firstItem[0]; + + }else{ + item = item.split(':') || []; + if(item.length === 2 ){ + request[item[0]] = item[1].trim(); + request.headers.push({ + name:item[0], + value:item[1] + }); + } + } + } + }); + if(request.method && request.method === 'POST'){ + var postDataArr = requestArr[requestArr.length - 1]; + request.postData.mimeType = 'multipart/form-data'; + request.postData.text = postDataArr; + } + + + } + } + // 补齐cookie + if(request.cookie){ + var cookieArray = request.cookie.split(';'); + if(cookieArray.length > 0){ + request.cookieArray = []; + cookieArray.forEach(function (item) { + item = item.split('=') || []; + request.cookieArray.push({ + name:item[0], + value:item[1] + }); + }); + } + } + // 补齐query + if(request.path && request.path.indexOf('?') !== -1){ + var query = request.path.slice(request.path.indexOf('?') + 1); + if(query){ + query = query.split('&');// re=va + query.forEach(function (item) { + item = item.split('='); + request.queryString.push({ + name:item[0], + value:item[1], + }); + }); + } + } + + return request; + }; + var getUrl = function (curr) { + var url; + var host; + if(curr){ + host = String(curr.host); + url = String(curr.url); + // 不包括host,特殊处理下 + if(url && host && url.indexOf(host) === -1){ + url = 'https://'+ host + url; + } + } + return url; + }; + + var + requestHaz = {}, + requestHeader, + responseHeader; + + requestHeader = unpackRaw((Buffer.from(request.requestRaw ||'')).toString('utf8')); + responseHeader = unpackRaw((Buffer.from(request.responseHeader || '')).toString('utf8')); + + + + requestHaz.startedDateTime = request.timestamps.ClientConnected; + requestHaz.time = 3000; + + requestHaz.request = { + 'method':requestHeader.method, + 'url':getUrl(request), + 'httpVersion': requestHeader.protocol, + 'cookies': requestHeader.cookieArray, + 'headers': requestHeader.headers, + 'queryString' : requestHeader.queryString, + 'postData' : requestHeader.postData, + 'headersSize' : request.requestRaw.replace(/\n/g,'').length, + 'bodySize' : requestHeader['Content-Length'] || 0, + }; + + // console.error(request.responseBody,'request.responseBody'); + // 处理responseBody 的格式,由base64 转到 utf-8 ; + // var requestResponseBodyBase64 = request.responseBody || 0; + // if(response.headers['content-encoding'] === 'gzip'){ + // + // } + // zlib.unzip(requestResponseBodyBase64, function(err, buffer) { + // console.log(buffer.toString()) + // }); + + var mimeTypeTemp = responseHeader['Content-Type'] ; + var mimeType= (typeof mimeTypeTemp === 'undefined')? responseHeader['content-type']: mimeTypeTemp ; + mimeType = (typeof mimeType=== 'undefined') ? mimeType : mimeType.trim(); + + requestHaz.response = { + 'Content-Type':'text/html; charset=UTF-8', + 'status': parseInt(request.resultCode)||0, + 'statusText': 'OK', + 'httpVersion': responseHeader.protocol, + 'cookies': responseHeader.cookieArray, + 'headers': responseHeader.headers, + 'redirectURL': '', + 'headersSize' : requestHeader['Content-Length'] || 0, + 'bodySize' : request.contentLength || 0, + 'comment' : '', + 'content':{ + 'mimeType':mimeType, + // "compression":request.responseBody.length - (request.contentLength || 0), + // "text":request.responseBody, + // "text": (Buffer.from(request.responseBody || '', 'base64')).toString('utf8'), + // "encoding":'base64', + } + }; + + requestHaz.serverIPAddress = request.serverIp; + requestHaz.pageref = request.sid; + requestHaz.timings = { + 'blocked': 0, + 'dns': request.timestamps.dns, + 'connect': request.timestamps.TCPConnectTime, + 'send': 20, + 'wait': 38, + 'receive': 12, + 'ssl': -1, + 'comment': '' + }; + + if(typeof request.responseBody !== 'undefined' && request.responseBody.length !== 0 ){ + requestHaz.response.content.size = request.responseBody.length; + var requestResponseBodyBaseBuffer = (Buffer.from(request.responseBody || '', 'base64')); + + // chunked decode + if(typeof responseHeader['Transfer-Encoding'] !== 'undefined' && responseHeader['Transfer-Encoding'] === 'chunked'){ + requestResponseBodyBaseBuffer = decodeChunkedUint8Array(requestResponseBodyBaseBuffer); + } + + // console.error(requestResponseBodyBaseBuffer.length,'requestResponseBodyBaseBuffer'); + + if(typeof responseHeader['Content-Encoding'] !== 'undefined' && responseHeader['Content-Encoding'] === 'gzip'){ + try { + var ungziprawText = zlib.gunzipSync(requestResponseBodyBaseBuffer); + requestHaz.response.content.text = ungziprawText.toString('utf8');// 暂时文件 + } catch (e) { + requestHaz.response.content.text = requestResponseBodyBaseBuffer;// 暂时文件 + } + + return requestHaz; + }else{ + requestHaz.response.content.text = requestResponseBodyBaseBuffer.toString('utf8'); + + return requestHaz; + } + + }else{ + requestHaz.response.content.size =0; + requestHaz.response.content.text = ''; + return requestHaz; + } + +}; + +var downloadHaz = function (request, response, opt) { + opt = opt || {}; + + var data = opt.data || [], + viewData = [], + filename = opt.id || 'log', + index = parseInt(request.GET.index,10), + SNKey = request.GET.SNKey; + + var hazJson = { + 'log':{ + 'version': '1.2', + 'creator': { + 'name': 'TSW', + 'version': '1.0' + }, + 'entries':[] + } + }; + + if(data.length <= 0){ + failRet(request, response, 'not find log'); + + return; + } + + if(SNKey && data.SNKeys && data.SNKeys[0] != SNKey){ + failRet(request, response, '该log已经过期,请联系用户慢点刷log~'); + + return; + } + + if(typeof data == 'string'){ + failRet(request, response, 'key类型不对'); + + return; + } + + response.setHeader('Content-disposition', 'attachment; filename=' + filename + '.har'); + var gzipResponse = gzipHttp.getGzipResponse({ + request: request, + response: response, + plug: plug, + code: 200, + contentType: 'application/octet-stream' + }); + + if(SNKey){ + //override index + index = 0; + } + + if(index >= 0){ + data = [data[index]]; + }else{ + data = data.reverse(); + } + data.forEach(function (tmp,i) { + if(tmp.curr){ + viewData.push(tmp.curr); + } + + tmp.ajax && + tmp.ajax.forEach(function(ajax,i){ + if(!ajax.SN){ + return; + } + viewData.push(ajax); + }); + }); + + viewData.forEach(function(tmp,i){ + + hazJson.log.entries.push(initRequestHar(tmp)); + + + }); + var buf = Buffer.from(JSON.stringify(hazJson),'UTF-8'); + gzipResponse.write(buf); + gzipResponse.end(); +}; + +var download = function(request, response, opt){ + opt = opt || {}; + + var data = opt.data || [], + viewData = [], + filename = opt.id || 'log', + index = parseInt(request.GET.index,10), + SNKey = request.GET.SNKey; + + if(data.length <= 0){ + failRet(request, response, 'not find log'); + + return; + } + + if(SNKey && data.SNKeys && data.SNKeys[0] != SNKey){ + failRet(request, response, '该log已经过期,请联系用户慢点刷log~'); + + return; + } + + //data = data[0]; + + if(typeof data == 'string'){ + failRet(request, response, 'key类型不对'); + + return; + } + + filename = filename.replace(/[^a-zA-Z0-9_.-]/g,'_'); + + response.setHeader('Content-disposition', 'attachment; filename=' + filename + '.saz'); + + var gzipResponse = gzipHttp.getGzipResponse({ + request: request, + response: response, + plug: plug, + code: 200, + contentType: 'application/octet-stream' + }); + + if(SNKey){ + //override index + index = 0; + } + + if(index >= 0){ + data = [data[index]]; + }else{ + data = data.reverse(); + } + + var archiver = new Archiver('zip'); + + archiver.append(tmpl.download_index(data), {name: '_index.htm'}); + archiver.append(tmpl.download_content_types(), {name: '[Content_Types].xml'}); + + data.forEach(function(tmp,i){ + var sid = ('0000' + (i + 1)).slice(-3); + tmp.curr = tmp.curr || {}; + tmp.curr.sid = sid + '.0000'; + + + tmp.curr.logText = tmp.curr.logText || ''; + tmp.curr.logText = tmp.curr.logText.replace(/\r\n|\r|\n/gm,'\r\n'); + var logSNKey = post.getLogSN(tmp.curr.logText); + + var log = { + curr: { + sid : sid, + + protocol : 'HTTP', + host : '', + url : '', + cache : '', + process : tmp.curr.process, + resultCode : '200', + contentLength : Buffer.byteLength(tmp.curr.responseBody || '','UTF-8'), + contentType : 'text/plain', + clientIp : '', + clientPort : '', + serverIp : '', + serverPort : '', + requestRaw : 'GET log/'+logSNKey+' HTTP/1.1\r\n\r\n', + responseHeader : 'HTTP/1.1 200 OK\r\nContent-Type: text/plain; charset=UTF-8\r\nConnection: close\r\n\r\n', + responseBody : Buffer.from(tmp.curr.logText || '','UTF-8').toString('base64'), + timestamps : tmp.curr.timestamps + } + }; + + viewData.push(tmp); + viewData.push(log); + + tmp.ajax && + tmp.ajax.forEach(function(curr,i){ + + var ajax = {}; + + if(!curr.SN){ + return; + } + + ajax.curr = curr; + + curr.sid = sid + '.' + (`0000${curr.SN}`.slice(-3)); + + viewData.push(ajax); + }); + }); + + viewData.forEach(function(tmp,i){ + archiver.append( + tmp.curr.requestRaw || '', + { + name: 'raw/' + (tmp.curr.sid) + '_c.txt' + } + ); + archiver.append( + tmpl.download_timestamp(tmp.curr), + { + name: 'raw/' + (tmp.curr.sid) + '_m.xml' + } + ); + archiver.append( + Buffer.concat([ + Buffer.from(tmp.curr.responseHeader || '','utf-8'), + Buffer.from(tmp.curr.responseBody || '', 'base64') + ]), + { + name: 'raw/' + (tmp.curr.sid) + '_s.txt' + } + ); + }); + + // archiver.pipe(gzipResponse); + + archiver.on('error', function(e){ + logger.error('archive log error \n' + e.message); + }); + + archiver.on('data', function(buffer){ + gzipResponse.write(buffer); + }); + + archiver.once('end', function(){ + gzipResponse.end(); + }); + + archiver.finalize(); +}; + +var failRet = function(request, response, msg){ + var gzipResponse = gzipHttp.getGzipResponse({ + request: request, + response: response, + plug: plug, + code: 200, + contentType: 'text/html; charset=UTF-8' + }); + + gzipResponse.end(msg || ''); +}; + + + +// chunked decode buffer , 格式 :size +\r\n + rawText +\r\n + 0|r\n , \r\n ====》 13,10, 中间的即为rawText + +var decodeChunkedUint8Array = function (Uint8ArrayBuffer) { + var rawText = []; + var startOfTheRawText = Uint8ArrayBuffer.indexOf(13); + while( startOfTheRawText !== -1 && startOfTheRawText !== 0 ){ + var rawTextSizeUint8ArrayBuffer = Uint8ArrayBuffer.slice(0 ,startOfTheRawText); + var rawTextSizeUint8ArrayInt = parseInt(Buffer.from(rawTextSizeUint8ArrayBuffer),16); + if(rawTextSizeUint8ArrayInt === 0 ){ + break; + } + var chunkedText = Uint8ArrayBuffer.slice(startOfTheRawText+2, startOfTheRawText+2 +rawTextSizeUint8ArrayInt ); + rawText.push(Buffer.from(chunkedText)); + Uint8ArrayBuffer = Uint8ArrayBuffer.slice(startOfTheRawText+2 +rawTextSizeUint8ArrayInt+2); + startOfTheRawText = Uint8ArrayBuffer.indexOf(13); + } + var bufferText = new Uint8Array( 0 ); + for(var ji=0; ji 0 === false){ - return; - } - - //频率限制 - if(limit.count[type] > 0){ - limit.count[type]++; - }else{ - limit.count[type] = 1; - } + if(alpha.isAlpha(key) && !isTST.isTST(req)){ + type = 'alpha'; + typeKey = 'EVENT_TSW_LOG_ALPHA'; + arrtKey = 'SUM_TSW_LOG_ALPHA'; + code = 0; + }else if(log.ERRO || log.WARN){ + key && logger.error('report key: ${key}',{key: key}); + type = 'error'; + typeKey = 'EVENT_TSW_LOG_ERROR'; + arrtKey = 'SUM_TSW_LOG_ERROR'; + code = 1; + }else if(log.force){ + type = 'force'; + typeKey = 'EVENT_TSW_LOG_FORCE'; + arrtKey = 'SUM_TSW_LOG_FORCE'; + code = 3; + }else if(context.dcapiIsFail && key){ + type = 'fail'; + typeKey = 'EVENT_TSW_LOG_FAIL'; + arrtKey = 'SUM_TSW_LOG_FAIL'; + code = 2; + }else{ + logger.debug('report nothing: ' + key); + //不用上报 + return; + } + + if(isTST.isTST(req)){ + logger.debug('log type origin: ' + type); + type = 'TST'; + typeKey = 'EVENT_TSW_LOG_TST'; + arrtKey = 'SUM_TSW_LOG_TST'; + code = -1; + } + + if(limit.max[type] > 0 === false){ + return; + } + + //频率限制 + if(limit.count[type] > 0){ + limit.count[type]++; + }else{ + limit.count[type] = 1; + } - if(Date.now() - limit.time < 5000){ + if(Date.now() - limit.time < 5000){ - if(limit.count[type] > limit.max[type]){ + if(limit.count[type] > limit.max[type]){ - dcapi.report({ - key : typeKey, - toIp : '127.0.0.1', - code : -1, - isFail : 1, - delay : 100 - }); + dcapi.report({ + key : typeKey, + toIp : '127.0.0.1', + code : -1, + isFail : 1, + delay : 100 + }); - return; - } + return; + } - }else{ - limit.count = {}; - limit.time = Date.now(); - } - - logger.debug('logType: ' + type); - - dcapi.report({ - key : typeKey, - toIp : '127.0.0.1', - code : code, - isFail : 0, - delay : 100 - }); - - tnm2.Attr_API(arrtKey, 1); - - if(Buffer.isBuffer(req.REQUEST.body)){ - req.REQUEST.body = format.formatBuffer(req.REQUEST.body); - } - - logger.debug('\n${headers}${body}\r\nresponse ${statusCode} ${resHeaders}',{ - headers : httpUtil.getRequestHeaderStr(req), - body : req.REQUEST.body || '', - statusCode : res.statusCode, - resHeaders : JSON.stringify(res._headers,null,2) - }); - - logText = logText || logger.getText(); + }else{ + limit.count = {}; + limit.time = Date.now(); + } + + logger.debug('logType: ' + type); + + dcapi.report({ + key : typeKey, + toIp : '127.0.0.1', + code : code, + isFail : 0, + delay : 100 + }); + + tnm2.Attr_API(arrtKey, 1); + + if(Buffer.isBuffer(req.REQUEST.body)){ + req.REQUEST.body = format.formatBuffer(req.REQUEST.body); + } + + logger.debug('\n${headers}${body}\r\nresponse ${statusCode} ${resHeaders}',{ + headers : httpUtil.getRequestHeaderStr(req), + body : req.REQUEST.body || '', + statusCode : res.statusCode, + resHeaders : JSON.stringify(res._headers,null,2) + }); + + logText = logText || logger.getText(); - if(type === 'alpha'){ - try{ - - //webapp的二进制回包转成可视化的结构 - if(res._body && res._headers['content-type'] === 'webapp'){ - res._body = Buffer.from(format.formatBuffer(res._body)); - } - - logJson = logJson || logger.getJson(); - logJson.curr = { - protocol : 'HTTP', - host : req.headers.host, - url : req.REQUEST.path, - cache : '', - process : 'TSW:' + process.pid, - resultCode : res.statusCode, - contentLength : isWebSocket ? (res._body ? res._body.length : 0) : (res._headers['content-length'] || res._bodySize), - contentType : isWebSocket ? 'websocket' : res._headers['content-type'], - clientIp : httpUtil.getUserIp(req), - clientPort : req.socket && req.socket.remotePort, - serverIp : serverInfo.intranetIp, - serverPort : config.httpPort, - requestRaw : httpUtil.getRequestHeaderStr(req) + (req.REQUEST.body || ''), - responseHeader : httpUtil.getResponseHeaderStr(res), - responseBody : res._body ? res._body.toString('base64') : '', - logText : logText, - timestamps : req.timestamps - }; - }catch(e){ - logger.error(e.stack); - } - - } - - var reportData = { - type : type || '', - logText : logText || '', - logJson : logJson, - key : String(key), - group : String(group || ''), - mod_act : String(mod_act || ''), - ua : req.headers['user-agent'] || '', - userip : req.userIp || '', - host : req.headers.host || '', - pathname : req.REQUEST.pathname || '', - ext_info : '', - statusCode : res.statusCode - }; - - if(type === 'alpha'){ - //根据content-type设置group便于分类查询抓包 - if(!reportData.group){ - var pathName = req.REQUEST.pathname; - var fileName = pathName.substr( pathName.lastIndexOf('/') + 1); - reportData.group = module.exports.fingureCroup({ - resHeaders : res._headers, - reqHeaders : req.headers, - suffix : ~fileName.indexOf('.') ? fileName.substr( fileName.lastIndexOf('.') + 1) : '', - method : req.method, - mod_act : mod_act, - returnCode : res.statusCode - }); - } - - if(config.appid && config.appkey){ - module.exports.reportCloud(reportData); - }else{ - module.exports.reportAlpha(reportData); - } - - } - - module.exports.report(reportData); - }); + if(type === 'alpha'){ + try{ + + //webapp的二进制回包转成可视化的结构 + if(res._body && res._headers['content-type'] === 'webapp'){ + res._body = Buffer.from(format.formatBuffer(res._body)); + } + + logJson = logJson || logger.getJson(); + logJson.curr = { + protocol : 'HTTP', + host : req.headers.host, + url : req.REQUEST.path, + cache : '', + process : 'TSW:' + process.pid, + resultCode : res.statusCode, + contentLength : isWebSocket ? (res._body ? res._body.length : 0) : (res._headers['content-length'] || res._bodySize), + contentType : isWebSocket ? 'websocket' : res._headers['content-type'], + clientIp : httpUtil.getUserIp(req), + clientPort : req.socket && req.socket.remotePort, + serverIp : serverInfo.intranetIp, + serverPort : config.httpPort, + requestRaw : httpUtil.getRequestHeaderStr(req) + (req.REQUEST.body || ''), + responseHeader : httpUtil.getResponseHeaderStr(res), + responseBody : res._body ? res._body.toString('base64') : '', + logText : logText, + timestamps : req.timestamps + }; + }catch(e){ + logger.error(e.stack); + } + + } + + var reportData = { + type : type || '', + logText : logText || '', + logJson : logJson, + key : String(key), + group : String(group || ''), + mod_act : String(mod_act || ''), + ua : req.headers['user-agent'] || '', + userip : req.userIp || '', + host : req.headers.host || '', + pathname : req.REQUEST.pathname || '', + ext_info : '', + statusCode : res.statusCode + }; + + if(type === 'alpha'){ + //根据content-type设置group便于分类查询抓包 + if(!reportData.group){ + var pathName = req.REQUEST.pathname; + var fileName = pathName.substr( pathName.lastIndexOf('/') + 1); + reportData.group = module.exports.fingureCroup({ + resHeaders : res._headers, + reqHeaders : req.headers, + suffix : ~fileName.indexOf('.') ? fileName.substr( fileName.lastIndexOf('.') + 1) : '', + method : req.method, + mod_act : mod_act, + returnCode : res.statusCode + }); + } + + if(config.appid && config.appkey){ + module.exports.reportCloud(reportData); + }else{ + module.exports.reportAlpha(reportData); + } + + } + + module.exports.report(reportData); + }); -} +}; module.exports.fingureCroup = function(opts){ - var group = 'other', - contentType = opts.resHeaders['content-type'] || '', - mod_act = opts.mod_act, - suffix = opts.suffix.toLowerCase(), - //一些特殊后缀的映射 - groupMap = { - gif : 'image', - xml : 'xml', - map : 'js', - //有些js返回头不一样还是要根据后缀来 - js : 'js' - }; - - if(!contentType){ - //没声明算html - return 'html'; - } + var group = 'other', + contentType = opts.resHeaders['content-type'] || '', + suffix = opts.suffix.toLowerCase(), + //一些特殊后缀的映射 + groupMap = { + gif : 'image', + xml : 'xml', + map : 'js', + //有些js返回头不一样还是要根据后缀来 + js : 'js' + }; + + if(!contentType){ + //没声明算html + return 'html'; + } - switch(true){ - case /^text\/html/.test(contentType): - group = 'html'; - break; - case contentType === 'webapp': - group = 'webapp'; - break; - case contentType === 'websocket': - group = 'websocket'; - break; - case opts.reqHeaders['x-requested-with'] === 'XMLHttpRequest': - group = 'XHR'; - break; - case /^text\/javascript/.test(contentType): - group = 'js'; - break; - case /^image\/.*/.test(contentType): - group = 'image'; - break; - case !!~['json','cgi', 'fcg', 'php'].indexOf(suffix): - group = 'XHR'; - break; - case !!~['eot', 'svg', 'ttf', 'woff'].indexOf(suffix): - group = 'font'; - break; - //其余的通过后缀区分吧 - default : - if(!suffix){ - group = 'other'; - }else { - group = groupMap[suffix] || 'other'; - } - break; - } - - return group; -} + switch(true){ + case /^text\/html/.test(contentType): + group = 'html'; + break; + case contentType === 'webapp': + group = 'webapp'; + break; + case contentType === 'websocket': + group = 'websocket'; + break; + case opts.reqHeaders['x-requested-with'] === 'XMLHttpRequest': + group = 'XHR'; + break; + case /^text\/javascript/.test(contentType): + group = 'js'; + break; + case /^image\/.*/.test(contentType): + group = 'image'; + break; + case !!~['json','cgi', 'fcg', 'php'].indexOf(suffix): + group = 'XHR'; + break; + case !!~['eot', 'svg', 'ttf', 'woff'].indexOf(suffix): + group = 'font'; + break; + //其余的通过后缀区分吧 + default : + if(!suffix){ + group = 'other'; + }else { + group = groupMap[suffix] || 'other'; + } + break; + } + + return group; +}; module.exports.reportAlpha = function(data){ - var currDays = parseInt(Date.now() / 1000 / 60 / 60 / 24); - - if(!data.key){ - return; - } - - if(!canIuse.test(data.key)){ - return; - } - - var reportKey = [data.key].join('/'); - var logNumMax = context.MAX_ALPHA_LOG || MAX_ALPHA_LOG; - - post.report(reportKey,data.logText,data.logJson).done(function(isFirst){ - if(isFirst){ - //增加计数 - CD.checkByCmem(`SUM_TSW_ALPHA_LOG_KEY.${currDays}`, logNumMax, 24 * 60 * 60).done(function(curr){ - logger.debug('SUM_TSW_ALPHA_LOG_KEY curr count: ' + curr); - }); - }else{ - CD.checkByCmem(`SUM_TSW_ALPHA_LOG.${currDays}`, logNumMax * logNumMax * logNumMax, 24 * 60 * 60).done(function(curr){ - logger.debug('SUM_TSW_ALPHA_LOG curr count: ' + curr); - }); - } - }); - - if(!data.group){ - return; - } - - if(!canIuse.test(data.group)){ - return; - } - - var reportGroupKey = [data.group,data.key].join('/'); - - post.report(reportGroupKey,data.logText,data.logJson).done(function(isFirst){ - //这里不用计数了 - }).always(function(){ - //上报分组 - CD.checkByCmem('v2.group.send.${data.group}',1,60).done(function(){ - post.report('v2.group.alpha',data.group,{group: data.group}); - }); - }); -} + var currDays = parseInt(Date.now() / 1000 / 60 / 60 / 24); + + if(!data.key){ + return; + } + + if(!canIuse.test(data.key)){ + return; + } + + var reportKey = [data.key].join('/'); + var logNumMax = context.MAX_ALPHA_LOG || MAX_ALPHA_LOG; + + post.report(reportKey,data.logText,data.logJson).done(function(isFirst){ + if(isFirst){ + //增加计数 + CD.checkByCmem(`SUM_TSW_ALPHA_LOG_KEY.${currDays}`, logNumMax, 24 * 60 * 60).done(function(curr){ + logger.debug('SUM_TSW_ALPHA_LOG_KEY curr count: ' + curr); + }); + }else{ + CD.checkByCmem(`SUM_TSW_ALPHA_LOG.${currDays}`, logNumMax * logNumMax * logNumMax, 24 * 60 * 60).done(function(curr){ + logger.debug('SUM_TSW_ALPHA_LOG curr count: ' + curr); + }); + } + }); + + if(!data.group){ + return; + } + + if(!canIuse.test(data.group)){ + return; + } + + var reportGroupKey = [data.group,data.key].join('/'); + + post.report(reportGroupKey,data.logText,data.logJson).done(function(isFirst){ + //这里不用计数了 + }).always(function(){ + //上报分组 + CD.checkByCmem('v2.group.send.${data.group}',1,60).done(function(){ + post.report('v2.group.alpha',data.group,{group: data.group}); + }); + }); +}; module.exports.report = function(data){ - return require('default/logReport.js').report(data); -} + return require('default/logReport.js').report(data); +}; module.exports.reportCloud = function(data){ - if(!config.appid){ - return; - } - - if(!config.appkey){ - return; - } - - if(!config.logReportUrl){ - return; - } - - if(!data.key){ - return; - } - - //only alpha - if(data.type !== 'alpha'){ - return; - } - - logger.debug('reportCloud'); - logger.debug('report log type: ${type}, key ${key}',data); - - var postData = Object.assign({},data); - - //加密 - postData.logText = post.encode(config.appid,config.appkey,data.logText); - postData.logJson = post.encode(config.appid,config.appkey,data.logJson); - postData.appid = config.appid; - postData.userip = ''; - postData.now = Date.now(); - - - var sig = openapi.signature({ - pathname: url.parse(config.logReportUrl).pathname, - method: 'POST', - data: postData, - appkey: config.appkey - }); - - postData.sig = sig; - - require('ajax').request({ - url : config.logReportUrl, - type : 'POST', - l5api : config.tswL5api['openapi.tswjs.org'], - dcapi : { - key: 'EVENT_TSW_OPENAPI_LOG_REPORT' - }, - data : postData, - keepAlive : true, - autoToken : false, - dataType : 'json' - }).done(function(){ - logger.debug('reportCloud success.'); - }).fail(function(){ - logger.error('reportCloud fail.'); - }); - -} - -module.exports.receiveCloud = function(req,res){ - - var returnJson = function(message){ - res.setHeader('Content-Type', 'application/json; charset=UTF-8'); - res.writeHead(200); - res.end(JSON.stringify({ - code: message?-1:0, - message: message || 'success' - }, null, 2)); - } - - var data = req.POST || {}; - - if(!data.appid){ - return returnJson('appid is required'); - } - - if(!canIuse.test(data.appid)){ - return returnJson('appid is invalid'); - } - - if(!data.key){ - return returnJson('key is required'); - } - - if(!canIuse.test(data.key)){ - return returnJson('key is invalid'); - } - - if(!data.group){ - //group is allow empty - } - - if(!canIuse.test(data.group)){ - return returnJson('group is invalid'); - } - - //only alpha - if(data.type !== 'alpha'){ - return returnJson('type=alpha is required'); - } + if(!config.appid){ + return; + } + + if(!config.appkey){ + return; + } + + if(!config.logReportUrl){ + return; + } + + if(!data.key){ + return; + } + + //only alpha + if(data.type !== 'alpha'){ + return; + } + + logger.debug('reportCloud'); + logger.debug('report log type: ${type}, key ${key}',data); + + var postData = Object.assign({},data); + + //加密 + postData.logText = post.encode(config.appid,config.appkey,data.logText); + postData.logJson = post.encode(config.appid,config.appkey,data.logJson); + postData.appid = config.appid; + postData.userip = ''; + postData.now = Date.now(); + + + var sig = openapi.signature({ + pathname: url.parse(config.logReportUrl).pathname, + method: 'POST', + data: postData, + appkey: config.appkey + }); + + postData.sig = sig; + + require('ajax').request({ + url : config.logReportUrl, + type : 'POST', + l5api : config.tswL5api['openapi.tswjs.org'], + dcapi : { + key: 'EVENT_TSW_OPENAPI_LOG_REPORT' + }, + data : postData, + keepAlive : true, + autoToken : false, + dataType : 'json' + }).done(function(){ + logger.debug('reportCloud success.'); + }).fail(function(){ + logger.error('reportCloud fail.'); + }); - if(context.appid !== data.appid){ - return returnJson('appid is not match'); - } - - if(!context.appkey){ - return returnJson('get appkey error'); - } - - var appid = context.appid; - var appkey = context.appkey; - var reportKey = [appid,data.key].join('/'); - var currDays = parseInt(Date.now() / 1000 / 60 / 60 / 24); - var logNumMax = context.MAX_ALPHA_LOG || MAX_ALPHA_LOG; - - logger.setKey(`report_${appid}_${data.key}`); //上报key - logger.debug('report log type: ${type}, key ${key}',data); - - CD.curr(`SUM_TSW_ALPHA_LOG_KEY.${currDays}`,logNumMax,24 * 60 * 60).fail(function(err){ - logger.debug(err && err.stack); - returnJson('服务器错误'); - }).done(function(count){ - count = ~~count; - - if(count > logNumMax){ - return returnJson('alpha log超限'); - } - - postOpenapi.report(reportKey,data.logText,data.logJson).done(function(isFirst){ - if(isFirst){ - //增加计数 - CD.checkByCmem(`SUM_TSW_ALPHA_LOG_KEY.${currDays}`, logNumMax, 24 * 60 * 60).done(function(curr){ - logger.debug('curr count: ' + curr); - }); - }else{ - CD.checkByCmem(`SUM_TSW_ALPHA_LOG.${currDays}`, logNumMax * logNumMax * logNumMax, 24 * 60 * 60).done(function(curr){ - logger.debug('curr count: ' + curr); - }); - } - }); - - if(!data.group){ - return returnJson(); - } - - if(!canIuse.test(data.group)){ - return returnJson(); - } - - var reportGroupKey = [appid,data.group,data.key].join('/'); +}; - postOpenapi.report(reportGroupKey,data.logText,data.logJson).done(function(isFirst){ - //这里不用计数了 - }).always(function(){ - //上报分组 - CD.checkByCmem(`v2.group.${appid}.${data.group}`,1,60).fail(function(){ - returnJson(); - }).done(function(){ +module.exports.receiveCloud = function(req,res){ - var logText = postOpenapi.encode(appid,appkey,data.group); - var logJson = postOpenapi.encode(appid,appkey,{group: data.group}); - - postOpenapi.report(`${appid}/v2.group.alpha`,logText,logJson).always(function(){ - returnJson(); - }); - }); - }); - }); + var returnJson = function(message){ + res.setHeader('Content-Type', 'application/json; charset=UTF-8'); + res.writeHead(200); + res.end(JSON.stringify({ + code: message?-1:0, + message: message || 'success' + }, null, 2)); + }; + + var data = req.POST || {}; + + if(!data.appid){ + return returnJson('appid is required'); + } + + if(!canIuse.test(data.appid)){ + return returnJson('appid is invalid'); + } + + if(!data.key){ + return returnJson('key is required'); + } + + if(!canIuse.test(data.key)){ + return returnJson('key is invalid'); + } + + if(!data.group){ + //group is allow empty + } + + if(!canIuse.test(data.group)){ + return returnJson('group is invalid'); + } + + //only alpha + if(data.type !== 'alpha'){ + return returnJson('type=alpha is required'); + } + + if(context.appid !== data.appid){ + return returnJson('appid is not match'); + } + + if(!context.appkey){ + return returnJson('get appkey error'); + } + + var appid = context.appid; + var appkey = context.appkey; + var reportKey = [appid,data.key].join('/'); + var currDays = parseInt(Date.now() / 1000 / 60 / 60 / 24); + var logNumMax = context.MAX_ALPHA_LOG || MAX_ALPHA_LOG; + + logger.setKey(`report_${appid}_${data.key}`); //上报key + logger.debug('report log type: ${type}, key ${key}',data); + + CD.curr(`SUM_TSW_ALPHA_LOG_KEY.${currDays}`,logNumMax,24 * 60 * 60).fail(function(err){ + logger.debug(err && err.stack); + returnJson('服务器错误'); + }).done(function(count){ + count = ~~count; + + if(count > logNumMax){ + return returnJson('alpha log超限'); + } + + postOpenapi.report(reportKey,data.logText,data.logJson).done(function(isFirst){ + if(isFirst){ + //增加计数 + CD.checkByCmem(`SUM_TSW_ALPHA_LOG_KEY.${currDays}`, logNumMax, 24 * 60 * 60).done(function(curr){ + logger.debug('curr count: ' + curr); + }); + }else{ + CD.checkByCmem(`SUM_TSW_ALPHA_LOG.${currDays}`, logNumMax * logNumMax * logNumMax, 24 * 60 * 60).done(function(curr){ + logger.debug('curr count: ' + curr); + }); + } + }); + + if(!data.group){ + return returnJson(); + } + + if(!canIuse.test(data.group)){ + return returnJson(); + } + + var reportGroupKey = [appid,data.group,data.key].join('/'); + + postOpenapi.report(reportGroupKey,data.logText,data.logJson).done(function(isFirst){ + //这里不用计数了 + }).always(function(){ + //上报分组 + CD.checkByCmem(`v2.group.${appid}.${data.group}`,1,60).fail(function(){ + returnJson(); + }).done(function(){ + + var logText = postOpenapi.encode(appid,appkey,data.group); + var logJson = postOpenapi.encode(appid,appkey,{group: data.group}); + + postOpenapi.report(`${appid}/v2.group.alpha`,logText,logJson).always(function(){ + returnJson(); + }); + }); + }); + }); -} +}; @@ -565,146 +563,146 @@ module.exports.receiveCloud = function(req,res){ module.exports.top100 = function(req, res){ - var item,str,filename,result; + var item,str,filename,result; - if(!global.top100){ - return; - } + if(!global.top100){ + return; + } - global.top100.push({ - pathname: req.REQUEST.pathname, - hostname: req.headers.host, - ip: httpUtil.getUserIp(req) || '', - socketIp: (req.socket && req.socket.remoteAddress), - header: httpUtil.getRequestHeaderStr(req), - body: req.REQUEST.body, - statusCode : res.statusCode, - resHeader: JSON.stringify(res._headers,null,2) - }); + global.top100.push({ + pathname: req.REQUEST.pathname, + hostname: req.headers.host, + ip: httpUtil.getUserIp(req) || '', + socketIp: (req.socket && req.socket.remoteAddress), + header: httpUtil.getRequestHeaderStr(req), + body: req.REQUEST.body, + statusCode : res.statusCode, + resHeader: JSON.stringify(res._headers,null,2) + }); - if(global.top100.length % 100 === 0){ - logger.info('top: ' + global.top100.length); - } + if(global.top100.length % 100 === 0){ + logger.info('top: ' + global.top100.length); + } - if(global.top100.length < 1000){ - return; - } + if(global.top100.length < 1000){ + return; + } - result = global.top100; - global.top100 = null; + result = global.top100; + global.top100 = null; - var map = {}; - var arr = []; - var key,item; - var buffer = []; + var map = {}; + var arr = []; + var key; + var buffer = []; - //分析pathname聚集 - map = {}; - arr = []; - result.forEach(function(v,i){ + //分析pathname聚集 + map = {}; + arr = []; + result.forEach(function(v,i){ - var key = v.hostname + v.pathname; + var key = v.hostname + v.pathname; - if(map[key]){ - map[key] ++; - }else{ - map[key] = 1; - } + if(map[key]){ + map[key] ++; + }else{ + map[key] = 1; + } - }); + }); - for(key in map){ + for(key in map){ - item = map[key]; + item = map[key]; - arr.push({ - count: item, - key: key - }); + arr.push({ + count: item, + key: key + }); - } + } - arr.sort(function(a,b){ - return b.count - a.count; - }); + arr.sort(function(a,b){ + return b.count - a.count; + }); - arr.forEach(function(v,i){ + arr.forEach(function(v,i){ - //top 100 - if(i < 100){ - buffer.push(v.count + '\t' + v.key); - buffer.push('\r\n'); - } + //top 100 + if(i < 100){ + buffer.push(v.count + '\t' + v.key); + buffer.push('\r\n'); + } - }); + }); - buffer.push('\r\n\r\n'); + buffer.push('\r\n\r\n'); - //分析ip聚集 - map = {}; - arr = []; - result.forEach(function(v,i){ + //分析ip聚集 + map = {}; + arr = []; + result.forEach(function(v,i){ - if(map[v.ip]){ - map[v.ip] ++; - }else{ - map[v.ip] = 1; - } + if(map[v.ip]){ + map[v.ip] ++; + }else{ + map[v.ip] = 1; + } - }); + }); - for(key in map){ + for(key in map){ - item = map[key]; + item = map[key]; - arr.push({ - count: item, - key: key - }); + arr.push({ + count: item, + key: key + }); - } + } - arr.sort(function(a,b){ - return b.count - a.count; - }); + arr.sort(function(a,b){ + return b.count - a.count; + }); - arr.forEach(function(v,i){ + arr.forEach(function(v,i){ - //top 100 - if(i < 100){ - buffer.push(v.count + '\t' + v.key); - buffer.push('\r\n'); - } + //top 100 + if(i < 100){ + buffer.push(v.count + '\t' + v.key); + buffer.push('\r\n'); + } - }); + }); - buffer.push('\r\n\r\n'); + buffer.push('\r\n\r\n'); - result.forEach(function(v,i){ + result.forEach(function(v,i){ - buffer.push(v.ip, ', socket ip: ' + v.socketIp); - buffer.push('\r\n'); - buffer.push(v.header); - buffer.push(v.body); - buffer.push('\r\n\r\n'); - buffer.push(v.statusCode + ':' + v.resHeader); - buffer.push('\r\n\r\n\r\n'); + buffer.push(v.ip, ', socket ip: ' + v.socketIp); + buffer.push('\r\n'); + buffer.push(v.header); + buffer.push(v.body); + buffer.push('\r\n\r\n'); + buffer.push(v.statusCode + ':' + v.resHeader); + buffer.push('\r\n\r\n\r\n'); - }); + }); - str = buffer.join(''); + str = buffer.join(''); - filename = __dirname + '/../../../proxy/cpu' + process.serverInfo.cpu + '.' + Date.now() + '.top100' + filename = __dirname + '/../../../proxy/cpu' + process.serverInfo.cpu + '.' + Date.now() + '.top100'; - fs.writeFile(filename,Buffer.from(str,'utf-8'),function(err){ - logger.info('top100: ' + filename); - }); + fs.writeFile(filename,Buffer.from(str,'utf-8'),function(err){ + logger.info('top100: ' + filename); + }); -} +}; diff --git a/bin/tsw/util/auto-report/post.js b/bin/tsw/util/auto-report/post.js index 78eb53da..4c2bcefa 100644 --- a/bin/tsw/util/auto-report/post.js +++ b/bin/tsw/util/auto-report/post.js @@ -5,16 +5,11 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; -const cmem = require('pool/cmem.l5.js'); const logger = require('logger'); -const gzipHttp = require('util/gzipHttp.js'); -const dcapi = require('api/libdcapi/dcapi.js'); -const serverInfo = require('serverInfo'); const Deferred = require('util/Deferred'); const cmemTSW = require('data/cmem.tsw.js'); -const config = require('config'); const crypto = require('crypto'); const zlib = require('zlib'); const MAX_NUM = 64; @@ -23,279 +18,279 @@ const MAX_ALPHA_LOG = 1000; module.exports.MAX_ALPHA_LOG = MAX_ALPHA_LOG; module.exports.cmem = function(){ - return cmemTSW.sz(); + return cmemTSW.sz(); }; module.exports.getLog = function(uin,limit){ - return this.getLogArr(uin,'text',null,limit); + return this.getLogArr(uin,'text',null,limit); }; module.exports.getLogJson = function(uin,limit){ - return this.getLogArr(uin,'json',null,limit); + return this.getLogArr(uin,'json',null,limit); }; module.exports.getLogJsonByKey = function (uin,key) { - var prefix = this.keyJson(''); - var keyJson; + var prefix = this.keyJson(''); + var keyJson; - if(String(key).startsWith(prefix)){ - keyJson = key; - }else{ - keyJson = this.keyJson(key); - } + if(String(key).startsWith(prefix)){ + keyJson = key; + }else{ + keyJson = this.keyJson(key); + } - return this.getLogArr(uin,'json',keyJson); + return this.getLogArr(uin,'json',keyJson); }; module.exports.getLogArr = function(uin,type,key,limit){ - var defer = Deferred.create(); - var memcached = this.cmem(); - var keyBitmap = this.keyBitmap(uin); - - if(!memcached){ - return defer.resolve([]); - } - - memcached.get(keyBitmap,function(err,data){ - var start = data || 0; - - var keyTextArr = type === 'text' ? module.exports.keyTextArr(uin,start) : module.exports.keyJsonArr(uin,start); - var keyJsonArr = module.exports.keyJsonArr(uin,start); - - //如果传递进来key,则只需要关注传进来的key - if(key){ - keyTextArr = [key]; - } - - if(limit && keyTextArr.length > limit){ - keyTextArr.length = limit; - keyJsonArr.length = limit; - } - - memcached.get(keyTextArr,function(err,data){ - - if(err){ - logger.error('bad key:'); - logger.error(keyTextArr); - logger.error((err && err.stack) || err); - defer.resolve([]); - return; - } - - var i,len,index; - var arr = [],keys = [],SNKeys = [],extInfos = []; //keys和SNKeys挂在arr下面,保持跟arr同序。 - var currKey,tmpInfo = {}; - - for(len = keyTextArr.length,i = 0; i < len ;i++){ - - index = i; - currKey = keyTextArr[index]; - tmpInfo = {}; - if(data[currKey]){ - if(context.appid && context.appkey){ - //解密 - data[currKey] = module.exports.decode(context.appid,context.appkey,data[currKey]); - } - arr.push(data[currKey]); - keys.push(keyJsonArr[index].split('.').slice(-1)); - - if(type == 'json'){ - tmpInfo = data[currKey].curr;//内含resultCode - SNKeys.push(module.exports.getLogSN(data[currKey].curr && data[currKey].curr.logText)); - }else{ - SNKeys.push(module.exports.getLogSN(data[currKey])); - tmpInfo.resultCode = module.exports.getLogResultCode(data[currKey]); - } - extInfos.push(tmpInfo); - - } - } - - arr.keys = keys; - arr.SNKeys = SNKeys; - arr.extInfos = extInfos; - arr.cmemIp = memcached.servers && memcached.servers[0]; - - logger.debug('log length: ' + arr.length); - defer.resolve(arr); - }); - }); + var defer = Deferred.create(); + var memcached = this.cmem(); + var keyBitmap = this.keyBitmap(uin); + + if(!memcached){ + return defer.resolve([]); + } + + memcached.get(keyBitmap,function(err,data){ + var start = data || 0; + + var keyTextArr = type === 'text' ? module.exports.keyTextArr(uin,start) : module.exports.keyJsonArr(uin,start); + var keyJsonArr = module.exports.keyJsonArr(uin,start); + + //如果传递进来key,则只需要关注传进来的key + if(key){ + keyTextArr = [key]; + } + + if(limit && keyTextArr.length > limit){ + keyTextArr.length = limit; + keyJsonArr.length = limit; + } + + memcached.get(keyTextArr,function(err,data){ + + if(err){ + logger.error('bad key:'); + logger.error(keyTextArr); + logger.error((err && err.stack) || err); + defer.resolve([]); + return; + } + + var i,len,index; + var arr = [],keys = [],SNKeys = [],extInfos = []; //keys和SNKeys挂在arr下面,保持跟arr同序。 + var currKey,tmpInfo = {}; + + for(len = keyTextArr.length,i = 0; i < len ;i++){ + + index = i; + currKey = keyTextArr[index]; + tmpInfo = {}; + if(data[currKey]){ + if(context.appid && context.appkey){ + //解密 + data[currKey] = module.exports.decode(context.appid,context.appkey,data[currKey]); + } + arr.push(data[currKey]); + keys.push(keyJsonArr[index].split('.').slice(-1)); + + if(type == 'json'){ + tmpInfo = data[currKey].curr;//内含resultCode + SNKeys.push(module.exports.getLogSN(data[currKey].curr && data[currKey].curr.logText)); + }else{ + SNKeys.push(module.exports.getLogSN(data[currKey])); + tmpInfo.resultCode = module.exports.getLogResultCode(data[currKey]); + } + extInfos.push(tmpInfo); + + } + } + + arr.keys = keys; + arr.SNKeys = SNKeys; + arr.extInfos = extInfos; + arr.cmemIp = memcached.servers && memcached.servers[0]; + + logger.debug('log length: ' + arr.length); + defer.resolve(arr); + }); + }); - return defer; + return defer; }; module.exports.getLogSN = function (logText) { - var SNReg = /\[(\d+\scpu\d+\s\d+)\]/; - if(logText){ - logText = logText.match && logText.match(SNReg) && logText.match(SNReg)[1] || 'unknown'; - return logText.replace(/\s/igm,''); + var SNReg = /\[(\d+\scpu\d+\s\d+)\]/; + if(logText){ + logText = logText.match && logText.match(SNReg) && logText.match(SNReg)[1] || 'unknown'; + return logText.replace(/\s/igm,''); - } - return 'unknown'; + } + return 'unknown'; }; module.exports.getLogFromReg = function (logText,reg) { - if(logText && reg){ - logText = logText.match && logText.match(reg) && logText.match(reg)[1] || 'unknown'; - return logText.replace(/\s/igm,''); + if(logText && reg){ + logText = logText.match && logText.match(reg) && logText.match(reg)[1] || 'unknown'; + return logText.replace(/\s/igm,''); - } - return ""; + } + return ''; }; module.exports.getLogResultCode = function (logText) { - var reg = /response\s(\d+)\s\{/; - return this.getLogFromReg(logText,reg); + var reg = /response\s(\d+)\s\{/; + return this.getLogFromReg(logText,reg); }; module.exports.report = function(key,logText,logJson){ - var defer = Deferred.create(); + var defer = Deferred.create(); - if(!key){ - return defer.reject(); - } + if(!key){ + return defer.reject(); + } - if(!logText){ - return defer.reject(); - } + if(!logText){ + return defer.reject(); + } - logJson = logJson || {}; + logJson = logJson || {}; - var memcached = this.cmem(); //要用this - var keyText = module.exports.keyText(key); - var keyJson = module.exports.keyJson(key); - var keyBitmap = module.exports.keyBitmap(key); + var memcached = this.cmem(); //要用this + var keyText = module.exports.keyText(key); + var keyJson = module.exports.keyJson(key); + var keyBitmap = module.exports.keyBitmap(key); - if(!memcached){ - return defer.resolve(); - } + if(!memcached){ + return defer.resolve(); + } - memcached.add(keyBitmap,0,24 * 60 * 60,function(err,ret){ + memcached.add(keyBitmap,0,24 * 60 * 60,function(err,ret){ - var isFirst = false; + var isFirst = false; - if(err){ - //add err是正常的 - //return; - } + if(err){ + //add err是正常的 + //return; + } - if(ret === true){ - isFirst = true; - } + if(ret === true){ + isFirst = true; + } - memcached.incr(keyBitmap, 1, function(err, result){ - if(err){ - logger.error(err.stack); - defer.reject(); - return; - } + memcached.incr(keyBitmap, 1, function(err, result){ + if(err){ + logger.error(err.stack); + defer.reject(); + return; + } - var index = 0; + var index = 0; - if(typeof result === 'number'){ - index = result % MAX_NUM; - } + if(typeof result === 'number'){ + index = result % MAX_NUM; + } - memcached.set([keyText,index].join('.'),logText,24 * 60 * 60,function(err,ret){ - memcached.set([keyJson,index].join('.'),logJson,24 * 60 * 60,function(err,ret){ - defer.resolve(isFirst); - }); - }); + memcached.set([keyText,index].join('.'),logText,24 * 60 * 60,function(err,ret){ + memcached.set([keyJson,index].join('.'),logJson,24 * 60 * 60,function(err,ret){ + defer.resolve(isFirst); + }); + }); - }); - }); + }); + }); - return defer; -} + return defer; +}; module.exports.keyBitmap = function(key){ - var currDays = parseInt(Date.now() / 1000 / 60 / 60 / 24); - return ['bitmap.v4.log',currDays,key].join('.'); -} + var currDays = parseInt(Date.now() / 1000 / 60 / 60 / 24); + return ['bitmap.v4.log',currDays,key].join('.'); +}; module.exports.keyJson = function(key){ - var currDays = parseInt(Date.now() / 1000 / 60 / 60 / 24); - return ['json.v4.log',currDays,key].join('.'); -} + var currDays = parseInt(Date.now() / 1000 / 60 / 60 / 24); + return ['json.v4.log',currDays,key].join('.'); +}; module.exports.keyText = function(key){ - var currDays = parseInt(Date.now() / 1000 / 60 / 60 / 24); - return ['text.v4.log',currDays,key].join('.'); -} + var currDays = parseInt(Date.now() / 1000 / 60 / 60 / 24); + return ['text.v4.log',currDays,key].join('.'); +}; module.exports.keyJsonArr = function(key,index){ - var i = 0; - var arr = []; - var keyJson = this.keyJson(key); - - index = index || 0; - for(i = MAX_NUM; i > 0; i--){ - arr.push([keyJson,(i + index)%MAX_NUM].join('.')); - } + var i = 0; + var arr = []; + var keyJson = this.keyJson(key); + + index = index || 0; + for(i = MAX_NUM; i > 0; i--){ + arr.push([keyJson,(i + index)%MAX_NUM].join('.')); + } - return arr; -} + return arr; +}; module.exports.keyTextArr = function(key,index){ - var i = 0; - var arr = []; - var keyText = this.keyText(key); - - index = index || 0; - for(i = MAX_NUM; i > 0; i--){ - arr.push([keyText,(i + index)%MAX_NUM].join('.')); - } + var i = 0; + var arr = []; + var keyText = this.keyText(key); + + index = index || 0; + for(i = MAX_NUM; i > 0; i--){ + arr.push([keyText,(i + index)%MAX_NUM].join('.')); + } - return arr; -} + return arr; +}; //加密 module.exports.encode = function(appid,appkey,data){ - var input = Buffer.from(JSON.stringify(data),'UTF-8'); - var buff = zlib.deflateSync(input); - var des = crypto.createCipher('des',(appid + appkey)); - var buf1 = des.update(buff, null , 'hex'); - var buf2 = des.final('hex'); - var body = Buffer.from(buf1 + buf2,'hex').toString('base64'); - return body; -} + var input = Buffer.from(JSON.stringify(data),'UTF-8'); + var buff = zlib.deflateSync(input); + var des = crypto.createCipher('des',(appid + appkey)); + var buf1 = des.update(buff, null , 'hex'); + var buf2 = des.final('hex'); + var body = Buffer.from(buf1 + buf2,'hex').toString('base64'); + return body; +}; //解密 module.exports.decode = function(appid,appkey,body){ - var des = crypto.createDecipher('des',(appid + appkey)); - var buf1 = ''; - var buf2 = ''; - - try{ - buf1 = des.update(body,'base64', 'hex') - buf2 = des.final('hex') - }catch(e){ - logger.error(e.stack); - return null; - } - - var buff = Buffer.from(buf1 + buf2 ,'hex'); - var input = zlib.inflateSync(buff); - - var data = null; - - try{ - data = JSON.parse(input.toString('UTF-8')); - }catch(e){ - logger.error(e.stack); - return null; - } - - return data; -} + var des = crypto.createDecipher('des',(appid + appkey)); + var buf1 = ''; + var buf2 = ''; + + try{ + buf1 = des.update(body,'base64', 'hex'); + buf2 = des.final('hex'); + }catch(e){ + logger.error(e.stack); + return null; + } + + var buff = Buffer.from(buf1 + buf2 ,'hex'); + var input = zlib.inflateSync(buff); + + var data = null; + + try{ + data = JSON.parse(input.toString('UTF-8')); + }catch(e){ + logger.error(e.stack); + return null; + } + + return data; +}; diff --git a/bin/tsw/util/auto-report/post.openapi.js b/bin/tsw/util/auto-report/post.openapi.js index 3701e548..d8e4b6a9 100644 --- a/bin/tsw/util/auto-report/post.openapi.js +++ b/bin/tsw/util/auto-report/post.openapi.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const cmemTSW = require('data/cmem.tsw.js'); const post = require('./post.js'); @@ -14,7 +14,7 @@ const post = require('./post.js'); module.exports = Object.assign({},post); module.exports.cmem = function(){ - return cmemTSW.openapi(); + return cmemTSW.openapi(); }; diff --git a/bin/tsw/util/auto-report/src/_config.js b/bin/tsw/util/auto-report/src/_config.js index ed4d6036..09597f20 100644 --- a/bin/tsw/util/auto-report/src/_config.js +++ b/bin/tsw/util/auto-report/src/_config.js @@ -5,19 +5,19 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; define(function(require, exports, module){ - return { + return { - tmpl: { - create: true - }, - all: { - create: false - } + tmpl: { + create: true + }, + all: { + create: false + } - }; + }; }); \ No newline at end of file diff --git a/bin/tsw/util/auto-report/src/download.tmpl.html b/bin/tsw/util/auto-report/src/download.tmpl.html index 98429a87..449ca3ba 100644 --- a/bin/tsw/util/auto-report/src/download.tmpl.html +++ b/bin/tsw/util/auto-report/src/download.tmpl.html @@ -10,64 +10,64 @@ @@ -75,57 +75,57 @@ \ No newline at end of file diff --git a/bin/tsw/util/auto-report/src/mail.tmpl.html b/bin/tsw/util/auto-report/src/mail.tmpl.html index 1fe792cb..075088c1 100644 --- a/bin/tsw/util/auto-report/src/mail.tmpl.html +++ b/bin/tsw/util/auto-report/src/mail.tmpl.html @@ -95,7 +95,8 @@ - <%for(var i = 0,item; item = data.total_arr[i++];){%> + <%for(var i = 0,item; i < data.total_arr.length; i++){%> + item = data.total_arr[i++]; <%=item.config.title%> <%=item.mod_act%> diff --git a/bin/tsw/util/auto-report/tmpl.js b/bin/tsw/util/auto-report/tmpl.js index 57379f05..fa5bea80 100644 --- a/bin/tsw/util/auto-report/tmpl.js +++ b/bin/tsw/util/auto-report/tmpl.js @@ -1,366 +1,362 @@ - -//tmpl file list: -//auto-report/src/download.tmpl.html -//auto-report/src/mail.tmpl.html -//auto-report/src/view.tmpl.html -//auto-report/src/zenburn.tmpl.html -define(function(require, exports, module){ -var tmpl = { -'encodeHtml': function(s){return (s+'').replace(/[\x26\x3c\x3e\x27\x22\x60]/g,function($0){return '&#'+$0.charCodeAt(0)+';';});}, - -'download_content_types': function(data){ - -var __p=[],_p=function(s){__p.push(s)},out=_p; -__p.push('\n\n\n\n\n'); - -return __p.join(""); -}, - -'download_index': function(data){ - -var __p=[],_p=function(s){__p.push(s)},out=_p; - - data = data || []; - - var i, len, entry; -__p.push('\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n '); - - for(i = 0, len = data.length; i < len; i++){ - entry = (data[i] || {}).curr || {}; - - __p.push(' \n \n \n \n \n \n \n \n \n \n \n \n \n \n '); - - } - __p.push(' \n
 #ResultProtocolHostURLBodyCachingContent-TypeProcessCommentsCustomServerIP
\n C S M\n '); -_p(('0000' + (i + 1)).slice(-3)); -__p.push(''); -_p(entry.resultCode); -__p.push(''); -_p(entry.protocol); -__p.push(''); -_p(entry.host); -__p.push(''); -_p(entry.url); -__p.push(''); -_p(entry.contentLength); -__p.push(''); -_p(entry.cache); -__p.push(''); -_p(entry.contentType); -__p.push(''); -_p(entry.process); -__p.push(''); -_p(entry.serverIp); -__p.push('
\n \n'); - -return __p.join(""); -}, - -'download_timestamp': function(data){ - -var __p=[],_p=function(s){__p.push(s)},out=_p; - - data = data || {}; - - var localISOString = function(d){ - if(!(d && d.getTimezoneOffset)){ - return d; - } - - var pad = function(n){return n < 10 ? '0' + n : n;}, - tz = d.getTimezoneOffset(), - tzs = (tz > 0 ? "-" : "+") + pad(parseInt(Math.abs(tz / 60))); - - if (tz === 0){ - tzs = 'Z'; - }else if (tz % 60 != 0){ - tzs += pad(Math.abs(tz % 60)); - }else{ - tzs += ':00'; - } - - return d.getFullYear()+'-' - + pad(d.getMonth()+1)+'-' - + pad(d.getDate())+'T' - + pad(d.getHours())+':' - + pad(d.getMinutes())+':' - + pad(d.getSeconds())+'.' - + pad(d.getMilliseconds()) + tzs; - }; - - var timeStamp = data.timestamps || {}, - defaultTime = new Date(); - -__p.push('\n\n \n \n \n \n \n \n \n \n \n \n \n'); - -return __p.join(""); -}, - -'errorSummary': function(data){ - -var __p=[],_p=function(s){__p.push(s)},out=_p; -__p.push('\n\n \n \n \n \n \n \n \n \n \n\n \n\n\n'); -if(data.total_arr.length){__p.push('\n \n \n \n \n \n \n \n \n '); -for(var i = 0,item; item = data.total_arr[i++];){__p.push(' \n \n \n \n \n '); -}__p.push(' \n
项目名称mod_act报错次数负责人
'); -_p(item.config.title); -__p.push(''); -_p(item.mod_act); -__p.push(''); -_p(item.errorNum); -__p.push(''); -_p(item.config.charge); -__p.push('
'); -}else{__p.push('

没有报错项目~

'); -}__p.push('\n'); - -return __p.join(""); -}, - -'error': function(data){ - -var __p=[],_p=function(s){__p.push(s)},out=_p; -__p.push('\n\n \n \n \n \n \n \n \n \n \n\n \n\n\n\n

'); -_p(data.mod_act); -__p.push(' '); -_p((data.config.title ? '('+data.config.title+')' : '')); -__p.push(':1分钟脚本报错超过频率限制('); -_p(data.minMaxNum); -__p.push(')

\n\n'); - -return __p.join(""); -}, - -'log_view': function(data){ - -var __p=[],_p=function(s){__p.push(s)},out=_p; - -var logArr = data.logArr || []; -var groupArr= data.groupArr || []; -var window = context.window || {}; -var hls = require('./highlight-tsw.js'); -var getResultCodeStyle = function (code) { - code = parseInt(code,10); - var style = ""; - if(code > 0){ - code = Math.floor(code / 100); - - - switch (code) { - case 2 : - style = "color:green;"; - case 6 : - style = "color:green;"; - break; - case 3 : - style = "color:#bf00ff;"; - break; - case 4 : - style = "color:orange;"; - break; - case 5 : - style = "color:red;"; - break; - } - } - return style+"font-weight:;font-size:18px"; -} - -var appid = context.appid; -var group = context.group; -var key = context.key; -var logKey = context.logKey; -var createLogKey = context.createLogKey; -var currPath = '/log/view/' + createLogKey(appid,group,key); - -//去重 -var tmp = [{name: '全部',href: '/log/view/' + createLogKey(appid,'',key)}]; -var groupMap= {}; -var nameMap = data.nameMap; - -for(var i in nameMap){ - tmp.push({ - name : nameMap[i], - href : '/log/view/' + createLogKey(appid,i,key) - }) -} - -groupArr.sort().forEach(function(v){ - if(!v){ - return; - } - if(groupMap[v]){ - return; - } - //默认展示的就去掉 - if(data.nameMap[v]) - return; - - groupMap[v] = 1; - var href = '/log/view/' + createLogKey(appid,v,key); - tmp.push({name: v, href: href}); -}); -groupArr = tmp; - -var XSS = plug('util/xss.js'); -__p.push('\n\n \n TSW云抓包™\n \n \n\n\n
\n 下载全部抓包\n Fiddler下载\n Whistle下载(mac推荐)\n \n '); -if(appid){__p.push(' 实时监控\n 测试环境'); -}else{__p.push(' 临时染色'); -}__p.push(' \n
'); -if(groupArr.length){__p.push('
'); -groupArr.forEach(function(v,i){__p.push(' '); -_p(XSS.htmlEncode(v.name)); -__p.push(''); -});__p.push('
'); -}if(logArr.length === 0){__p.push('
\n

还没有实时log,故障排除?

\n
'); -} - - logArr.forEach(function(logText,i){ - logText = logText || ''; - var logLineArr = logText.split("\n"); - var reqUrl = logLineArr && logLineArr[0]; - var reqType = '', - resultCode = logArr.extInfos[i].resultCode; - - var hasError = false; - for(var j = 0; j < logLineArr.length; j++){ - var logTextLine = logLineArr[j]; - if (!logTextLine) { - continue; - } - - //匹配ajax失败的fail log - var retCodeReg = new RegExp("isFail:(.*)"); - if (retCodeReg.exec(logTextLine)) { - var retCode = parseInt(RegExp.$1); - if (retCode) { - hasError = true; - break; - } - } - - //匹配ERRO log - if(!hasError && logTextLine.indexOf(' [ERRO] ') > 0){ - hasError = true; - break; - } - } - - if(i < 2){ - logText = hls.highlight('tswlog',(logText),true).value; - }else{ - logText = XSS.htmlEncode(logText) - } - - __p.push('
\n
\n  statusCode: '); -_p(resultCode); -__p.push('\n\n 点击下载 云抓包™.saz\n\n 点击下载 云抓包™.har\n\n  \n \n
\n
');
-_p((logText));
-__p.push('
\n
'); - - }); - __p.push(' \n \n \n\n $(\'pre code\').each(function(i, block) {\n if(i >= 2){\n setTimeout(function(){\n hljs.highlightBlock(block)\n },0)\n }\n });\n\n var showErrorLogItem = JSON.parse( window.localStorage.getItem(\'showErrorLogItem\') || false ),\n showRequestListItem = JSON.parse( window.localStorage.getItem(\'showRequestListItem\') || false );\n \n $("#showErrorLogItemChk").prop(\'checked\', showErrorLogItem);\n $("#showRequestListChk").prop(\'checked\', showRequestListItem);\n\n if(showErrorLogItem){\n $(".view-logText.error0:visible").hide();\n }\n\n if(showRequestListItem){\n $(".firstReq").show();\n $(".view-logText-log").hide();\n }\n $("#showErrorLogItemChk").click(function () {\n if ($("#showErrorLogItemChk").prop(\'checked\')) {\n showErrorLogItem = true;\n $(".view-logText.error0:visible").hide();\n window.localStorage.setItem(\'showErrorLogItem\', true);\n } else {\n showErrorLogItem = false;\n $(".view-logText.error0").show();\n window.localStorage.setItem(\'showErrorLogItem\', false);\n }\n });\n $("#showRequestListChk").click(function () {\n if ($("#showRequestListChk").prop(\'checked\')) {\n showRequestListItem = true;\n $(".firstReq").show();\n $(".view-logText-log").hide();\n window.localStorage.setItem(\'showRequestListItem\', true);\n } else {\n showRequestListItem = false;\n $(".firstReq").hide();\n $(".view-logText-log").show();\n window.localStorage.setItem(\'showRequestListItem\', false);\n }\n });\n $(".expand").click(function () {\n var expandChkDom = $(this).find(\'.expandChk\');\n var codeClass = $(this).data(\'j\') + \'_code\';\n if (expandChkDom.prop(\'checked\')) {\n $(\'.\' + codeClass).show();\n } else {\n $(\'.\' + codeClass).hide();\n }\n });\n var refreshTime = Date.now();\n function getPassTimeStr(preTime ,curTime) {\n var passTime = Math.round( (curTime - preTime) / 1000 );\n var sec = passTime % 60;\n passTime = (passTime - sec) / 60;\n var min = passTime % 60;\n passTime = (passTime - min) / 60;\n var hour = passTime;\n var passTimeStr = \'\';\n if(hour) passTimeStr = passTimeStr + hour + \'小时\';\n if(min) passTimeStr = passTimeStr + min + \'分钟\';\n if(sec) passTimeStr = passTimeStr + sec + \'秒\';\n return passTimeStr;\n }\n\n function updateTime() {\n var curTime = Date.now();\n $(\'.view-logText\').each(function (index) {\n var logItem = $(this);\n var timeStr = $(logItem.find(\'code.tswlog span.hljs-subst\')[0]).html();\n logItem.find(\'.log_pass_time\').html(getPassTimeStr( (new Date(timeStr)).getTime(), curTime )).parent().show();\n });\n }\n\n setInterval(updateTime, 1000);\n updateTime();\n \n\n'); - -return __p.join(""); -} -}; -return tmpl; -}); + +//tmpl file list: +//auto-report/src/download.tmpl.html +//auto-report/src/mail.tmpl.html +//auto-report/src/view.tmpl.html +//auto-report/src/zenburn.tmpl.html +define(function(require, exports, module){ + var tmpl = { + 'encodeHtml': function(s){return (s+'').replace(/[\x26\x3c\x3e\x27\x22\x60]/g,function($0){return '&#'+$0.charCodeAt(0)+';';});}, + + 'download_content_types': function(data){ + + var __p=[],_p=function(s){__p.push(s);},out=_p; + __p.push('\n\n\n\n\n'); + + return __p.join(''); + }, + + 'download_index': function(data){ + + var __p=[],_p=function(s){__p.push(s);},out=_p; + + data = data || []; + + var i, len, entry; + __p.push('\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n '); + + for(i = 0, len = data.length; i < len; i++){ + entry = (data[i] || {}).curr || {}; + + __p.push(' \n \n \n \n \n \n \n \n \n \n \n \n \n \n '); + + } + __p.push(' \n
 #ResultProtocolHostURLBodyCachingContent-TypeProcessCommentsCustomServerIP
\n C S M\n '); + _p(('0000' + (i + 1)).slice(-3)); + __p.push(''); + _p(entry.resultCode); + __p.push(''); + _p(entry.protocol); + __p.push(''); + _p(entry.host); + __p.push(''); + _p(entry.url); + __p.push(''); + _p(entry.contentLength); + __p.push(''); + _p(entry.cache); + __p.push(''); + _p(entry.contentType); + __p.push(''); + _p(entry.process); + __p.push(''); + _p(entry.serverIp); + __p.push('
\n \n'); + + return __p.join(''); + }, + + 'download_timestamp': function(data){ + + var __p=[],_p=function(s){__p.push(s);},out=_p; + + data = data || {}; + + var localISOString = function(d){ + if(!(d && d.getTimezoneOffset)){ + return d; + } + + var pad = function(n){return n < 10 ? '0' + n : n;}, + tz = d.getTimezoneOffset(), + tzs = (tz > 0 ? '-' : '+') + pad(parseInt(Math.abs(tz / 60))); + + if (tz === 0){ + tzs = 'Z'; + }else if (tz % 60 != 0){ + tzs += pad(Math.abs(tz % 60)); + }else{ + tzs += ':00'; + } + + return d.getFullYear()+'-' + + pad(d.getMonth()+1)+'-' + + pad(d.getDate())+'T' + + pad(d.getHours())+':' + + pad(d.getMinutes())+':' + + pad(d.getSeconds())+'.' + + pad(d.getMilliseconds()) + tzs; + }; + + var timeStamp = data.timestamps || {}, + defaultTime = new Date(); + + __p.push('\n\n \n \n \n \n \n \n \n \n \n \n \n'); + + return __p.join(''); + }, + + 'errorSummary': function(data){ + + var __p=[],_p=function(s){__p.push(s);},out=_p; + __p.push('\n\n \n \n \n \n \n \n \n \n \n\n \n\n\n'); + if(data.total_arr.length){__p.push('\n \n \n \n \n \n \n \n \n '); + for(var i = 0,item; i < data.total_arr.length; i++){__p.push(' item = data.total_arr[i++];\n \n \n \n \n \n '); + }__p.push(' \n
项目名称mod_act报错次数负责人
'); + _p(item.config.title); + __p.push(''); + _p(item.mod_act); + __p.push(''); + _p(item.errorNum); + __p.push(''); + _p(item.config.charge); + __p.push('
'); + }else{__p.push('

没有报错项目~

'); + }__p.push('\n'); + + return __p.join(''); + }, + + 'error': function(data){ + + var __p=[],_p=function(s){__p.push(s);},out=_p; + __p.push('\n\n \n \n \n \n \n \n \n \n \n\n \n\n\n\n

'); + _p(data.mod_act); + __p.push(' '); + _p((data.config.title ? '('+data.config.title+')' : '')); + __p.push(':1分钟脚本报错超过频率限制('); + _p(data.minMaxNum); + __p.push(')

\n\n'); + + return __p.join(''); + }, + + 'log_view': function(data){ + + var __p=[],_p=function(s){__p.push(s);},out=_p; + + var logArr = data.logArr || []; + var groupArr= data.groupArr || []; + var window = context.window || {}; + var hls = require('./highlight-tsw.js'); + var getResultCodeStyle = function (code) { + code = parseInt(code,10); + var style = ''; + if(code > 0){ + code = Math.floor(code / 100); + switch (code) { + case 2 : + case 6 : + style = 'color:green;'; + break; + case 3 : + style = 'color:#bf00ff;'; + break; + case 4 : + style = 'color:orange;'; + break; + case 5 : + style = 'color:red;'; + break; + } + } + return style+'font-weight:;font-size:18px'; + }; + + var appid = context.appid; + var group = context.group; + var key = context.key; + var createLogKey = context.createLogKey; + var currPath = '/log/view/' + createLogKey(appid,group,key); + + //去重 + var tmp = [{name: '全部',href: '/log/view/' + createLogKey(appid,'',key)}]; + var groupMap= {}; + var nameMap = data.nameMap; + + for(var i in nameMap){ + tmp.push({ + name : nameMap[i], + href : '/log/view/' + createLogKey(appid,i,key) + }); + } + + groupArr.sort().forEach(function(v){ + if(!v){ + return; + } + if(groupMap[v]){ + return; + } + //默认展示的就去掉 + if(data.nameMap[v]) + return; + + groupMap[v] = 1; + var href = '/log/view/' + createLogKey(appid,v,key); + tmp.push({name: v, href: href}); + }); + groupArr = tmp; + + var XSS = plug('util/xss.js'); + __p.push('\n\n \n TSW云抓包™\n \n \n\n\n
\n 下载全部抓包\n Fiddler下载\n Whistle下载(mac推荐)\n \n '); + if(appid){__p.push(' 实时监控\n 测试环境'); + }else{__p.push(' 临时染色'); + }__p.push(' \n
'); + if(groupArr.length){__p.push('
'); + groupArr.forEach(function(v,i){__p.push(' '); + _p(XSS.htmlEncode(v.name)); + __p.push(''); + });__p.push('
'); + }if(logArr.length === 0){__p.push('
\n

还没有实时log

\n
'); + } + + logArr.forEach(function(logText,i){ + logText = logText || ''; + var logLineArr = logText.split('\n'); + var reqUrl = logLineArr && logLineArr[0]; + var reqType = '', + resultCode = logArr.extInfos[i].resultCode; + + var hasError = false; + for(var j = 0; j < logLineArr.length; j++){ + var logTextLine = logLineArr[j]; + if (!logTextLine) { + continue; + } + + //匹配ajax失败的fail log + var retCodeReg = new RegExp('isFail:(.*)'); + if (retCodeReg.exec(logTextLine)) { + var retCode = parseInt(RegExp.$1); + if (retCode) { + hasError = true; + break; + } + } + + //匹配ERRO log + if(!hasError && logTextLine.indexOf(' [ERRO] ') > 0){ + hasError = true; + break; + } + } + + if(i < 2){ + logText = hls.highlight('tswlog',(logText),true).value; + }else{ + logText = XSS.htmlEncode(logText); + } + + __p.push('
\n
\n  statusCode: '); + _p(resultCode); + __p.push('\n\n 点击下载 云抓包™.saz\n\n 点击下载 云抓包™.har\n\n  \n \n
\n
');
+                _p((logText));
+                __p.push('
\n
'); + + }); + __p.push(' \n \n \n\n $(\'pre code\').each(function(i, block) {\n if(i >= 2){\n setTimeout(function(){\n hljs.highlightBlock(block)\n },0)\n }\n });\n\n var showErrorLogItem = JSON.parse( window.localStorage.getItem(\'showErrorLogItem\') || false ),\n showRequestListItem = JSON.parse( window.localStorage.getItem(\'showRequestListItem\') || false );\n \n $("#showErrorLogItemChk").prop(\'checked\', showErrorLogItem);\n $("#showRequestListChk").prop(\'checked\', showRequestListItem);\n\n if(showErrorLogItem){\n $(".view-logText.error0:visible").hide();\n }\n\n if(showRequestListItem){\n $(".firstReq").show();\n $(".view-logText-log").hide();\n }\n $("#showErrorLogItemChk").click(function () {\n if ($("#showErrorLogItemChk").prop(\'checked\')) {\n showErrorLogItem = true;\n $(".view-logText.error0:visible").hide();\n window.localStorage.setItem(\'showErrorLogItem\', true);\n } else {\n showErrorLogItem = false;\n $(".view-logText.error0").show();\n window.localStorage.setItem(\'showErrorLogItem\', false);\n }\n });\n $("#showRequestListChk").click(function () {\n if ($("#showRequestListChk").prop(\'checked\')) {\n showRequestListItem = true;\n $(".firstReq").show();\n $(".view-logText-log").hide();\n window.localStorage.setItem(\'showRequestListItem\', true);\n } else {\n showRequestListItem = false;\n $(".firstReq").hide();\n $(".view-logText-log").show();\n window.localStorage.setItem(\'showRequestListItem\', false);\n }\n });\n $(".expand").click(function () {\n var expandChkDom = $(this).find(\'.expandChk\');\n var codeClass = $(this).data(\'j\') + \'_code\';\n if (expandChkDom.prop(\'checked\')) {\n $(\'.\' + codeClass).show();\n } else {\n $(\'.\' + codeClass).hide();\n }\n });\n var refreshTime = Date.now();\n function getPassTimeStr(preTime ,curTime) {\n var passTime = Math.round( (curTime - preTime) / 1000 );\n var sec = passTime % 60;\n passTime = (passTime - sec) / 60;\n var min = passTime % 60;\n passTime = (passTime - min) / 60;\n var hour = passTime;\n var passTimeStr = \'\';\n if(hour) passTimeStr = passTimeStr + hour + \'小时\';\n if(min) passTimeStr = passTimeStr + min + \'分钟\';\n if(sec) passTimeStr = passTimeStr + sec + \'秒\';\n return passTimeStr;\n }\n\n function updateTime() {\n var curTime = Date.now();\n $(\'.view-logText\').each(function (index) {\n var logItem = $(this);\n var timeStr = $(logItem.find(\'code.tswlog span.hljs-subst\')[0]).html();\n logItem.find(\'.log_pass_time\').html(getPassTimeStr( (new Date(timeStr)).getTime(), curTime )).parent().show();\n });\n }\n\n setInterval(updateTime, 1000);\n updateTime();\n \n\n'); + + return __p.join(''); + } + }; + return tmpl; +}); diff --git a/bin/tsw/util/auto-report/view.js b/bin/tsw/util/auto-report/view.js index c30abc87..d4d4c5a7 100644 --- a/bin/tsw/util/auto-report/view.js +++ b/bin/tsw/util/auto-report/view.js @@ -5,166 +5,164 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const logger = require('logger'); const gzipHttp = require('util/gzipHttp.js'); -const config = require('config'); const post = require('./post'); const postOpenapi = require('./post.openapi.js'); const tmpl = require('./tmpl'); const OALogin = require('util/oa-login/index.js'); -const httpUtil = require('util/http'); const hls = require('./highlight-tsw.js'); -const canIuse = /^[0-9a-zA-Z_\-]{0,64}$/; +const canIuse = /^[0-9a-zA-Z_-]{0,64}$/; const CD = require('util/CD.js'); const MAX_ALPHA_LOG = post.MAX_ALPHA_LOG; tmpl.hls = hls; module.exports = function(request, response){ - OALogin.checkLoginForTSW(request,response,function(){ - module.exports.go(request,response); - }); -} + OALogin.checkLoginForTSW(request,response,function(){ + module.exports.go(request,response); + }); +}; module.exports.checkLogin = function(request, response, callback){ - OALogin.checkLoginForTSW(request,response,function(){ - callback(); - }); -} + OALogin.checkLoginForTSW(request,response,function(){ + callback(); + }); +}; module.exports.go = function(request, response){ - var arr = request.REQUEST.pathname.split('/'); - var appid = context.appid || ''; - var group = arr[3]; - var key = arr[4]; - var groupKey = 'v2.group.alpha'; - var limit = ~~context.limit || 64; - var currPost = post; - - if(appid){ - currPost = postOpenapi; - groupKey = `${appid}/v2.group.alpha`; - } - - if(!key){ - key = group; - group = ''; - } - - if(!canIuse.test(appid)){ - return returnError('appid格式非法'); - } - - if(!canIuse.test(group)){ - return returnError('group格式非法'); - } - - if(!canIuse.test(key)){ - return returnError('key格式非法'); - } - - var createLogKey = function(appid,group,key){ - var logKey = key; - - if(group){ - logKey = `${group}/${logKey}`; - } - - return logKey; - }; - - var logKey = createLogKey(appid,group,key); - - if(appid){ - logKey = `${appid}/${logKey}`; - } - - //上下文设置 - context.group = group; - context.limit = limit; - context.key = key; - context.groupKey = groupKey; - context.logKey = logKey; - context.createLogKey = createLogKey; - - var logCount = 0; - var logKeyCount = 0; - var logNumMax = context.MAX_ALPHA_LOG || MAX_ALPHA_LOG; - var currDays = parseInt(Date.now() / 1000 / 60 / 60 / 24); - - logger.debug('logKey :${logKey}',{ - logKey: logKey - }); - - if(request.GET.type === 'json'){ - currPost.getLogJson(logKey,limit).done(function(logArr){ - var gzipResponse = gzipHttp.getGzipResponse({ - request: request, - response: response, - code: 200, - contentType: 'text/html; charset=UTF-8' - }); - - gzipResponse.end(JSON.stringify(logArr,null,2)); - }); - }else{ - CD.curr(`SUM_TSW_ALPHA_LOG_KEY.${currDays}`,logNumMax,24 * 60 * 60).done(function(count){ - logKeyCount = ~~ count; - }).always(function(){ - CD.curr(`SUM_TSW_ALPHA_LOG.${currDays}`,logNumMax * logNumMax * logNumMax,24 * 60 * 60).done(function(count){ - logCount = ~~ count; - }).always(function(){ - currPost.getLog(logKey,limit).done(function(logArr){ - currPost.getLog(groupKey,limit).done(function(groupArr){ - - var html = tmpl.log_view({ - logKeyCount: logKeyCount, - logNumMax: logNumMax, - logCount: logCount, - logArr: logArr, - groupArr: groupArr, - //也代表顺序 - nameMap : { - html : 'html', - XHR : 'XHR', - js : 'js', - image : 'image', - css : 'css', - webapp : 'webapp', - websocket : 'websocket', - tsw : 'tsw', - font : '字体' - } - }); - - var gzipResponse = gzipHttp.getGzipResponse({ - request: request, - response: response, - code: 200, - contentType: 'text/html; charset=UTF-8' - }); - - gzipResponse.end(html); - }); - }); - }); - }); - } -} + var arr = request.REQUEST.pathname.split('/'); + var appid = context.appid || ''; + var group = arr[3]; + var key = arr[4]; + var groupKey = 'v2.group.alpha'; + var limit = ~~context.limit || 64; + var currPost = post; + + if(appid){ + currPost = postOpenapi; + groupKey = `${appid}/v2.group.alpha`; + } + + if(!key){ + key = group; + group = ''; + } + + if(!canIuse.test(appid)){ + return returnError('appid格式非法'); + } + + if(!canIuse.test(group)){ + return returnError('group格式非法'); + } + + if(!canIuse.test(key)){ + return returnError('key格式非法'); + } + + var createLogKey = function(appid,group,key){ + var logKey = key; + + if(group){ + logKey = `${group}/${logKey}`; + } + + return logKey; + }; + + var logKey = createLogKey(appid,group,key); + + if(appid){ + logKey = `${appid}/${logKey}`; + } + + //上下文设置 + context.group = group; + context.limit = limit; + context.key = key; + context.groupKey = groupKey; + context.logKey = logKey; + context.createLogKey = createLogKey; + + var logCount = 0; + var logKeyCount = 0; + var logNumMax = context.MAX_ALPHA_LOG || MAX_ALPHA_LOG; + var currDays = parseInt(Date.now() / 1000 / 60 / 60 / 24); + + logger.debug('logKey :${logKey}',{ + logKey: logKey + }); + + if(request.GET.type === 'json'){ + currPost.getLogJson(logKey,limit).done(function(logArr){ + var gzipResponse = gzipHttp.getGzipResponse({ + request: request, + response: response, + code: 200, + contentType: 'text/html; charset=UTF-8' + }); + + gzipResponse.end(JSON.stringify(logArr,null,2)); + }); + }else{ + CD.curr(`SUM_TSW_ALPHA_LOG_KEY.${currDays}`,logNumMax,24 * 60 * 60).done(function(count){ + logKeyCount = ~~ count; + }).always(function(){ + CD.curr(`SUM_TSW_ALPHA_LOG.${currDays}`,logNumMax * logNumMax * logNumMax,24 * 60 * 60).done(function(count){ + logCount = ~~ count; + }).always(function(){ + currPost.getLog(logKey,limit).done(function(logArr){ + currPost.getLog(groupKey,limit).done(function(groupArr){ + + var html = tmpl.log_view({ + logKeyCount: logKeyCount, + logNumMax: logNumMax, + logCount: logCount, + logArr: logArr, + groupArr: groupArr, + //也代表顺序 + nameMap : { + html : 'html', + XHR : 'XHR', + js : 'js', + image : 'image', + css : 'css', + webapp : 'webapp', + websocket : 'websocket', + tsw : 'tsw', + font : '字体' + } + }); + + var gzipResponse = gzipHttp.getGzipResponse({ + request: request, + response: response, + code: 200, + contentType: 'text/html; charset=UTF-8' + }); + + gzipResponse.end(html); + }); + }); + }); + }); + } +}; function returnError(message){ - var window = context.window; - var gzipResponse = gzipHttp.getGzipResponse({ - request: window.request, - response: window.response, - code: 200, - contentType: 'text/html; charset=UTF-8' - }); - - gzipResponse.end(message); + var window = context.window; + var gzipResponse = gzipHttp.getGzipResponse({ + request: window.request, + response: window.response, + code: 200, + contentType: 'text/html; charset=UTF-8' + }); + + gzipResponse.end(message); } diff --git a/bin/tsw/util/cache.cleaner.js b/bin/tsw/util/cache.cleaner.js index cfd89b31..75d75b1b 100644 --- a/bin/tsw/util/cache.cleaner.js +++ b/bin/tsw/util/cache.cleaner.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const path = require('path'); const logger = require('logger'); @@ -17,27 +17,27 @@ const logger = require('logger'); */ this.clear = function(dir,showLog){ - var dir = path.normalize(dir), - key; + dir = path.normalize(dir); + + let key; - logger.info('clear dir: ${dir}',{ - dir: dir - }); + logger.info('clear dir: ${dir}',{ + dir: dir + }); - for(key in require.cache){ - require.cache[key].children = []; - require.cache[key].resolveFilenameCache = {}; + for(key in require.cache){ + require.cache[key].children = []; + require.cache[key].resolveFilenameCache = {}; - if(key.indexOf(dir) >= 0 && !/\.node$/i.test(key)){ - delete require.cache[key].parent; - delete require.cache[key]; - if(showLog){ - logger.debug('clear: ${key}',{ - key: key.slice(dir.length) - }); - } - } - } - -} + if(key.indexOf(dir) >= 0 && !/\.node$/i.test(key)){ + delete require.cache[key].parent; + delete require.cache[key]; + if(showLog){ + logger.debug('clear: ${key}',{ + key: key.slice(dir.length) + }); + } + } + } +}; diff --git a/bin/tsw/util/cpu.js b/bin/tsw/util/cpu.js index 485347cd..43e36612 100644 --- a/bin/tsw/util/cpu.js +++ b/bin/tsw/util/cpu.js @@ -1,219 +1,153 @@ -/*! - * Tencent is pleased to support the open source community by making Tencent Server Web available. - * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. - * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - * http://opensource.org/licenses/MIT - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ -"use strict"; - -const os = require('os'); -const fs = require('fs'); -const cp = require('child_process'); -const {isWindows} = require('./isWindows.js'); -const logger = require('logger'); -var cache; - -if(!global[__filename]){ - cache = { - time: 0, - total: 0, - used: 0, - curr: 0 - }; - global[__filename] = cache; -}else{ - cache = { - time: 0, - total: 0, - used: 0, - curr: 0 - }; - global[__filename] = cache; -} - -this.getCpuUsed = function(cpu){ - - var now = Date.now(); - var cpu = cpu || ''; - - if(isWindows){ - return cache.curr; - } - - if(now - cache.time < 3000){ - return cache.curr; - } - - cache.time = now; - - if(typeof cpu !== 'number'){ - cpu = ''; - } - - fs.readFile('/proc/stat',function(err,buffer){ - - if(err){ - console.error(err.stack); - return; - } - - var lines = buffer.toString('UTF-8').split('\n'); - var str = ''; - var arr = []; - - for(var i = 0; i < lines.length; i++){ - if(lines[i].startsWith(`cpu${cpu} `)){ - str = lines[i]; - break; - } - } - - if(str){ - arr = str.split(/\W+/); - }else{ - return; - } - - var user = parseInt(arr[1],10) || 0; - var nice = parseInt(arr[2],10) || 0; - var system = parseInt(arr[3],10) || 0; - var idle = parseInt(arr[4],10) || 0; - var iowait = parseInt(arr[5],10) || 0; - var irq = parseInt(arr[6],10) || 0; - var softirq = parseInt(arr[7],10) || 0; - var steal = parseInt(arr[8],10) || 0; - var guest = parseInt(arr[9],10) || 0; - - var total = user + nice + system + idle + iowait + irq + softirq; - var used = user + nice + system + irq + softirq; - var curr = Math.round((used - cache.used) / (total - cache.total) * 100); - - cache.curr = curr; - cache.total = total; - cache.used = used; - }); - - return cache.curr; -} - - -this.cpus = function(){ - - var res = []; - - - os.cpus().forEach(function(v){ - - if(v.times && v.times.idle !== 0){ - res.push(v); - } - - }); - - - return res; -} - -this.taskset = function(oriCpu,pid){ - if(isWindows){ - return; - } - - //绑定CPU - logger.info('taskset -cp ${pid}',{ - pid: pid - }); - - //打印shell执行信息 - cp.exec(`taskset -cp ${pid}`,{ - timeout: 5000 - },function(err,data,errData){ - - var str = data.toString('UTF-8'); - var tmp = str.split(':'); - var cpus; - - if(tmp.length >= 2){ - cpus = exports.parseTaskset(tmp[1]); - } - - var cpu = oriCpu; - if(cpus.length > 1){ - //cpu编号修正 - cpu = parseInt(cpus[cpu % cpus.length],10); - }else{ - //超过cpu编号时,修正 - cpu = cpu % exports.cpus().length; - } - - if(err){ - logger.error(err.stack); - } - - if(data.length){ - logger.info('\n' + data.toString('UTF-8')); - } - - if(errData.length){ - logger.error('\n' + errData.toString('UTF-8')); - } - - logger.info('taskset -cp ${cpu} ${pid}',{ - cpu: cpu, - pid: pid - }); - - cp.exec(`taskset -cp ${cpu} ${pid}`,{ - timeout: 5000 - },function(err,data,errData){ - if(err){ - logger.error(err.stack); - } - - if(data.length){ - logger.info('\n' + data.toString('UTF-8')); - } - - if(errData.length){ - logger.error('\n' + errData.toString('UTF-8')); - } - }); - - }); - -} - - -this.parseTaskset = function(str){ - - var res = []; - var arr = str.split(','); - - arr.forEach(function(v){ - - v = v.trim(); - - var tmp = v.split('-'); - var start = ~~tmp[0]; - var end = ~~tmp[1]; - var i,len; - - if(end < start){ - end = start; - } - - for(i = start; i<=end ;i++){ - res.push(i); - } - }); - - return res; -} - - -if(process.mainModule === module){ - setInterval(function(){ - console.log('cpu: ' + module.exports.getCpuUsed()) - },1000) +/*! + * Tencent is pleased to support the open source community by making Tencent Server Web available. + * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ +'use strict'; + +const os = require('os'); +const fs = require('fs'); +const {isWindows} = require('./isWindows.js'); +var cache; + +if(!global[__filename]){ + cache = { + time: 0, + total: 0, + used: 0, + curr: 0 + }; + global[__filename] = cache; +}else{ + cache = { + time: 0, + total: 0, + used: 0, + curr: 0 + }; + global[__filename] = cache; +} + +this.getCpuUsed = function(cpu){ + + var now = Date.now(); + + cpu = cpu || ''; + + if(isWindows){ + return cache.curr; + } + + if(now - cache.time < 3000){ + return cache.curr; + } + + cache.time = now; + + if(typeof cpu !== 'number'){ + cpu = ''; + } + + fs.readFile('/proc/stat',function(err,buffer){ + + if(err){ + /* eslint-disable no-console */ + console.error(err.stack); + /* eslint-enable no-console */ + return; + } + + var lines = buffer.toString('UTF-8').split('\n'); + var str = ''; + var arr = []; + + for(var i = 0; i < lines.length; i++){ + if(lines[i].startsWith(`cpu${cpu} `)){ + str = lines[i]; + break; + } + } + + if(str){ + arr = str.split(/\W+/); + }else{ + return; + } + + var user = parseInt(arr[1],10) || 0; + var nice = parseInt(arr[2],10) || 0; + var system = parseInt(arr[3],10) || 0; + var idle = parseInt(arr[4],10) || 0; + var iowait = parseInt(arr[5],10) || 0; + var irq = parseInt(arr[6],10) || 0; + var softirq = parseInt(arr[7],10) || 0; + // var steal = parseInt(arr[8],10) || 0; + // var guest = parseInt(arr[9],10) || 0; + + var total = user + nice + system + idle + iowait + irq + softirq; + var used = user + nice + system + irq + softirq; + var curr = Math.round((used - cache.used) / (total - cache.total) * 100); + + cache.curr = curr; + cache.total = total; + cache.used = used; + }); + + return cache.curr; +}; + + +this.cpus = function(){ + + var res = []; + + + os.cpus().forEach(function(v){ + + if(v.times && v.times.idle !== 0){ + res.push(v); + } + + }); + + + return res; +}; + + +this.parseTaskset = function(str){ + + var res = []; + var arr = str.split(','); + + arr.forEach(function(v){ + + v = v.trim(); + + var tmp = v.split('-'); + var start = ~~tmp[0]; + var end = ~~tmp[1]; + var i; + + if(end < start){ + end = start; + } + + for(i = start; i<=end ;i++){ + res.push(i); + } + }); + + return res; +}; + + +if(process.mainModule === module){ + setInterval(function(){ + /* eslint-disable no-console */ + console.log('cpu: ' + module.exports.getCpuUsed()); + /* eslint-enable no-console */ + },1000); } \ No newline at end of file diff --git a/bin/tsw/util/h5-test/add.js b/bin/tsw/util/h5-test/add.js index 6332e900..0308fc78 100644 --- a/bin/tsw/util/h5-test/add.js +++ b/bin/tsw/util/h5-test/add.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const logger = require('logger'); const Deferred = require('util/Deferred'); @@ -13,111 +13,109 @@ const isTest = require('./is-test.js'); const post = require('util/auto-report/post.js'); const OALogin = require('util/oa-login/index.js'); const gzipHttp = require('util/gzipHttp.js'); -const canIuse = /^[0-9a-zA-Z_\-]{0,64}$/; +const canIuse = /^[0-9a-zA-Z_-]{0,64}$/; module.exports = function(request, response) { - OALogin.checkLoginForTSW(request, response, function() { - module.exports.go(request, response); - }); + OALogin.checkLoginForTSW(request, response, function() { + module.exports.go(request, response); + }); }; module.exports.go = async function(request, response){ - var uin = request.param('uin'); - var val = request.param('val'); + var uin = request.param('uin'); + var val = request.param('val'); - var data = await module.exports.addTestUser(uin,val).toES6Promise().catch(function(){ - return null; - }); + var data = await module.exports.addTestUser(uin,val).toES6Promise().catch(function(){ + return null; + }); - var result = {code: 0,data: data}; + var result = {code: 0,data: data}; - returnJson(result); -} + returnJson(result); +}; var returnJson = function(json){ - var gzip = gzipHttp.create({ - contentType: 'application/json; charset=UTF-8', - code: 200 - }); + var gzip = gzipHttp.create({ + contentType: 'application/json; charset=UTF-8', + code: 200 + }); - gzip.write(JSON.stringify(json,null,2)); - gzip.end(); -} + gzip.write(JSON.stringify(json,null,2)); + gzip.end(); +}; module.exports.addTestUser = function(uin, val){ - logger.debug("addTestUser:" + uin); - val = val || true; - var memcached = isTest.cmem(); - var keyText = isTest.keyBitmap(); - var defer = Deferred.create(); - var appid = ''; - var appkey = ''; - - if(context.appid && context.appkey){ - //开平过来的 - appid = context.appid; - appkey = context.appkey; - keyText = `${keyText}.${appid}`; - } - - if(!uin){ - return defer.reject(); - } - - if(!canIuse.test(uin)){ - return defer.reject(); - } - - if(!val){ - return defer.reject(); - } - - if(!memcached){ - return defer.reject('memcached not exists'); - } - - memcached.get(keyText,function(err,data){ - - if(appid && typeof data === 'string'){ - //解密 - data = post.decode(context.appid,context.appkey,data); - } - - var expire = 24*60*60; - - if(err){ - logger.error('memcache get error:' + err); - return defer.reject('memcache get error'); - } - - var text; - - if(typeof data === "object"){ - text = data || {}; - }else{ - text = {}; - }; - - text[uin] = val; - - logger.debug(`setKeyText: ${uin}; value: ${val}`); - - if(appid){ - //加密 - text = post.encode(context.appid,context.appkey,text); - } - - memcached.set(keyText, text, expire,function(err, ret){ - if(err){ - defer.reject('memcache set data error'); - }else { - logger.debug("setKeyText success"); - defer.resolve(); - } - }); - - }); - return defer; -} + logger.debug('addTestUser:' + uin); + val = val || true; + var memcached = isTest.cmem(); + var keyText = isTest.keyBitmap(); + var defer = Deferred.create(); + var appid = ''; + + if(context.appid && context.appkey){ + //开平过来的 + appid = context.appid; + keyText = `${keyText}.${appid}`; + } + + if(!uin){ + return defer.reject(); + } + + if(!canIuse.test(uin)){ + return defer.reject(); + } + + if(!val){ + return defer.reject(); + } + + if(!memcached){ + return defer.reject('memcached not exists'); + } + + memcached.get(keyText,function(err,data){ + + if(appid && typeof data === 'string'){ + //解密 + data = post.decode(context.appid,context.appkey,data); + } + + var expire = 24*60*60; + + if(err){ + logger.error('memcache get error:' + err); + return defer.reject('memcache get error'); + } + + var text; + + if(typeof data === 'object'){ + text = data || {}; + }else{ + text = {}; + } + + text[uin] = val; + + logger.debug(`setKeyText: ${uin}; value: ${val}`); + + if(appid){ + //加密 + text = post.encode(context.appid,context.appkey,text); + } + + memcached.set(keyText, text, expire,function(err, ret){ + if(err){ + defer.reject('memcache set data error'); + }else { + logger.debug('setKeyText success'); + defer.resolve(); + } + }); + + }); + return defer; +}; diff --git a/bin/tsw/util/h5-test/del.js b/bin/tsw/util/h5-test/del.js index 1b139de4..889b3557 100644 --- a/bin/tsw/util/h5-test/del.js +++ b/bin/tsw/util/h5-test/del.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const logger = require('logger'); const Deferred = require('util/Deferred'); @@ -13,110 +13,108 @@ const isTest = require('./is-test.js'); const post = require('util/auto-report/post.js'); const OALogin = require('util/oa-login/index.js'); const gzipHttp = require('util/gzipHttp.js'); -const canIuse = /^[0-9a-zA-Z_\-]{0,64}$/; +const canIuse = /^[0-9a-zA-Z_-]{0,64}$/; module.exports = function(request, response) { - OALogin.checkLoginForTSW(request, response, function() { - module.exports.go(request, response); - }); + OALogin.checkLoginForTSW(request, response, function() { + module.exports.go(request, response); + }); }; module.exports.go = async function(request, response){ - var uin = request.param('uin'); + var uin = request.param('uin'); - var data = await module.exports.deleteTestUser( - uin - ).toES6Promise().catch(function(){ - return null; - }); + var data = await module.exports.deleteTestUser( + uin + ).toES6Promise().catch(function(){ + return null; + }); - var result = {code: 0,data: data}; + var result = {code: 0,data: data}; - returnJson(result); -} + returnJson(result); +}; var returnJson = function(json){ - var gzip = gzipHttp.create({ - contentType: 'application/json; charset=UTF-8', - code: 200 - }); + var gzip = gzipHttp.create({ + contentType: 'application/json; charset=UTF-8', + code: 200 + }); - gzip.write(JSON.stringify(json,null,2)); - gzip.end(); -} + gzip.write(JSON.stringify(json,null,2)); + gzip.end(); +}; module.exports.deleteTestUser = function(uin){ - logger.debug("deleteTestUser:" + uin); - var memcached = isTest.cmem(); - var keyText = isTest.keyBitmap(); - var defer = Deferred.create(); - var appid = ''; - var appkey = ''; - - if(!uin){ - return defer.reject(); - } - - if(!canIuse.test(uin)){ - return defer.reject(); - } - - if(context.appid && context.appkey){ - //开平过来的 - appid = context.appid; - appkey = context.appkey; - keyText = `${keyText}.${appid}`; - } - - if(!memcached){ - return defer.reject('memcached not exists'); - } - - memcached.get(keyText,function(err,data){ - - if(appid && typeof data === 'string'){ - //解密 - data = post.decode(context.appid,context.appkey,data); - } - - var expire = 24*60*60; - - if(err){ - return defer.reject('memcache get error'); - } - - var text = data || {}; - - if(typeof data === "object"){ - text = data || {}; - }else{ - logger.debug('memcache return not a object'); - return defer.resolve(); - }; - - if(text[uin]) { - delete text[uin]; - } - - logger.debug("deleteKeyText:" + uin); - - if(appid){ - //加密 - text = post.encode(context.appid,context.appkey,text); - } - - memcached.set(keyText, text, expire,function(err,ret){ - if(err){ - defer.reject('memcache del data error'); - }else { - logger.debug("deleteKeyText success"); - defer.resolve(); - } - }); - - }); - return defer; -} \ No newline at end of file + logger.debug('deleteTestUser:' + uin); + var memcached = isTest.cmem(); + var keyText = isTest.keyBitmap(); + var defer = Deferred.create(); + var appid = ''; + + if(!uin){ + return defer.reject(); + } + + if(!canIuse.test(uin)){ + return defer.reject(); + } + + if(context.appid && context.appkey){ + //开平过来的 + appid = context.appid; + keyText = `${keyText}.${appid}`; + } + + if(!memcached){ + return defer.reject('memcached not exists'); + } + + memcached.get(keyText,function(err,data){ + + if(appid && typeof data === 'string'){ + //解密 + data = post.decode(context.appid,context.appkey,data); + } + + var expire = 24*60*60; + + if(err){ + return defer.reject('memcache get error'); + } + + var text = data || {}; + + if(typeof data === 'object'){ + text = data || {}; + }else{ + logger.debug('memcache return not a object'); + return defer.resolve(); + } + + if(text[uin]) { + delete text[uin]; + } + + logger.debug('deleteKeyText:' + uin); + + if(appid){ + //加密 + text = post.encode(context.appid,context.appkey,text); + } + + memcached.set(keyText, text, expire,function(err,ret){ + if(err){ + defer.reject('memcache del data error'); + }else { + logger.debug('deleteKeyText success'); + defer.resolve(); + } + }); + + }); + return defer; +}; \ No newline at end of file diff --git a/bin/tsw/util/h5-test/get.js b/bin/tsw/util/h5-test/get.js index 8be5a242..4d8a387c 100644 --- a/bin/tsw/util/h5-test/get.js +++ b/bin/tsw/util/h5-test/get.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/MIT * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -"use strict"; +'use strict'; const logger = require('logger'); const Deferred = require('util/Deferred'); @@ -15,109 +15,107 @@ const gzipHttp = require('util/gzipHttp.js'); const OALogin = require('util/oa-login/index.js'); module.exports = function(request, response) { - OALogin.checkLoginForTSW(request, response, function() { - module.exports.go(request, response); - }); + OALogin.checkLoginForTSW(request, response, function() { + module.exports.go(request, response); + }); }; module.exports.go = async function(request, response){ - var data = await module.exports.getTestUser().toES6Promise().catch(function(){ - return null; - }); + var data = await module.exports.getTestUser().toES6Promise().catch(function(){ + return null; + }); - var result = {code: 0,data: data}; + var result = {code: 0,data: data}; - returnJson(result); -} + returnJson(result); +}; module.exports.getTestUser = function(){ - logger.debug("getTestUser"); - - //从内存中读取testTargetMap - var memcached = isTest.cmem(); - var keyText = isTest.keyBitmap(); - var defer = Deferred.create(); - var appid = ''; - var appkey = ''; - - if(context.appid && context.appkey){ - //开平过来的 - appid = context.appid; - appkey = context.appkey; - keyText = `${keyText}.${appid}`; - } - - if(!memcached){ - return defer.resolve({}); - } - - memcached.get(keyText,function(err,data){ - - if(appid && typeof data === 'string'){ - //解密 - data = post.decode(context.appid,context.appkey,data); - } - - if(err){ - logger.error('memcache get error:' + err); - defer.reject('memcache get error'); - }else if(typeof data == "object"){ - logger.debug("getTestUser success!"); - defer.resolve(data); - }else{ - logger.debug('memcache return not a object'); - defer.resolve({}); - } - }); + logger.debug('getTestUser'); + + //从内存中读取testTargetMap + var memcached = isTest.cmem(); + var keyText = isTest.keyBitmap(); + var defer = Deferred.create(); + var appid = ''; + + if(context.appid && context.appkey){ + //开平过来的 + appid = context.appid; + keyText = `${keyText}.${appid}`; + } + + if(!memcached){ + return defer.resolve({}); + } + + memcached.get(keyText,function(err,data){ + + if(appid && typeof data === 'string'){ + //解密 + data = post.decode(context.appid,context.appkey,data); + } + + if(err){ + logger.error('memcache get error:' + err); + defer.reject('memcache get error'); + }else if(typeof data == 'object'){ + logger.debug('getTestUser success!'); + defer.resolve(data); + }else{ + logger.debug('memcache return not a object'); + defer.resolve({}); + } + }); - return defer; -} + return defer; +}; module.exports.openapi = async function(req,res){ - var appid = context.appid; - var appkey = context.appkey; + var appid = context.appid; + var appkey = context.appkey; - if(req.param('appid') !== appid){ - returnJson({ code: -2 , message: 'appid错误'}); - return; - } + if(req.param('appid') !== appid){ + returnJson({ code: -2 , message: 'appid错误'}); + return; + } - if(!appid){ - returnJson({ code: -2 , message: 'appid is required'}); - return; - } + if(!appid){ + returnJson({ code: -2 , message: 'appid is required'}); + return; + } - if(!appkey){ - returnJson({ code: -2 , message: 'appkey is required'}); - return; - } + if(!appkey){ + returnJson({ code: -2 , message: 'appkey is required'}); + return; + } - if(!/^[a-zA-Z0-9_\-]{0,50}$/.test(appid)){ - returnJson({ code: -2 , message: 'appid is required'}); - return; - } + if(!/^[a-zA-Z0-9_-]{0,50}$/.test(appid)){ + returnJson({ code: -2 , message: 'appid is required'}); + return; + } - logger.setKey(`h5testSync_${appid}`); //上报key + logger.setKey(`h5testSync_${appid}`); //上报key - var data = await module.exports.getTestUser().toES6Promise().catch(function(){ - return null; - }); + var data = await module.exports.getTestUser().toES6Promise().catch(function(){ + return null; + }); - var result = {code: 0,data: data}; + var result = {code: 0,data: data}; - returnJson(result); -} + returnJson(result); +}; var returnJson = function(json){ - var gzip = gzipHttp.create({ - contentType: 'application/json; charset=UTF-8', - code: 200 - }); - - gzip.write(JSON.stringify(json,null,2)); - gzip.end(); -} + var gzip = gzipHttp.create({ + contentType: 'application/json; charset=UTF-8', + code: 200 + }); + + gzip.write(JSON.stringify(json,null,2)); + gzip.end(); +}; diff --git a/bin/tsw/util/h5-test/group/.eslintrc.json b/bin/tsw/util/h5-test/group/.eslintrc.json new file mode 100644 index 00000000..0e4b665b --- /dev/null +++ b/bin/tsw/util/h5-test/group/.eslintrc.json @@ -0,0 +1,11 @@ +{ + "rules": { + "no-unused-vars": [ + "error", + { + "varsIgnorePattern": "out", + "args": "none" + } + ] + } +} \ No newline at end of file diff --git a/bin/tsw/util/h5-test/group/src/_config.js b/bin/tsw/util/h5-test/group/src/_config.js index b3770c31..5ded8ae7 100644 --- a/bin/tsw/util/h5-test/group/src/_config.js +++ b/bin/tsw/util/h5-test/group/src/_config.js @@ -3,15 +3,15 @@ */ define(function(require, exports, module){ - return { + return { - tmpl: { - create: true - }, - all: { - create: false - } + tmpl: { + create: true + }, + all: { + create: false + } - }; + }; }); \ No newline at end of file diff --git a/bin/tsw/util/h5-test/group/src/main.tmpl.html b/bin/tsw/util/h5-test/group/src/main.tmpl.html index 529ed9a9..0d80253d 100644 --- a/bin/tsw/util/h5-test/group/src/main.tmpl.html +++ b/bin/tsw/util/h5-test/group/src/main.tmpl.html @@ -25,11 +25,10 @@

分组